00001 <?php
00007 class LocalRepo extends FSRepo {
00008 var $fileFactory = array( 'LocalFile', 'newFromTitle' );
00009 var $oldFileFactory = array( 'OldLocalFile', 'newFromTitle' );
00010 var $fileFromRowFactory = array( 'LocalFile', 'newFromRow' );
00011 var $oldFileFromRowFactory = array( 'OldLocalFile', 'newFromRow' );
00012
00013 function newFileFromRow( $row ) {
00014 if ( isset( $row->img_name ) ) {
00015 return call_user_func( $this->fileFromRowFactory, $row, $this );
00016 } elseif ( isset( $row->oi_name ) ) {
00017 return call_user_func( $this->oldFileFromRowFactory, $row, $this );
00018 } else {
00019 throw new MWException( __METHOD__.': invalid row' );
00020 }
00021 }
00022
00023 function newFromArchiveName( $title, $archiveName ) {
00024 return OldLocalFile::newFromArchiveName( $title, $this, $archiveName );
00025 }
00026
00034 function cleanupDeletedBatch( $storageKeys ) {
00035 $root = $this->getZonePath( 'deleted' );
00036 $dbw = $this->getMasterDB();
00037 $status = $this->newGood();
00038 $storageKeys = array_unique($storageKeys);
00039 foreach ( $storageKeys as $key ) {
00040 $hashPath = $this->getDeletedHashPath( $key );
00041 $path = "$root/$hashPath$key";
00042 $dbw->begin();
00043 $inuse = $dbw->selectField( 'filearchive', '1',
00044 array( 'fa_storage_group' => 'deleted', 'fa_storage_key' => $key ),
00045 __METHOD__, array( 'FOR UPDATE' ) );
00046 if( !$inuse ) {
00047 $sha1 = substr( $key, 0, strcspn( $key, '.' ) );
00048 $ext = substr( $key, strcspn($key,'.') + 1 );
00049 $ext = File::normalizeExtension($ext);
00050 $inuse = $dbw->selectField( 'oldimage', '1',
00051 array( 'oi_sha1' => $sha1,
00052 "oi_archive_name LIKE '%.{$ext}'",
00053 'oi_deleted & '.File::DELETED_FILE => File::DELETED_FILE ),
00054 __METHOD__, array( 'FOR UPDATE' ) );
00055 }
00056 if ( !$inuse ) {
00057 wfDebug( __METHOD__ . ": deleting $key\n" );
00058 if ( !@unlink( $path ) ) {
00059 $status->error( 'undelete-cleanup-error', $path );
00060 $status->failCount++;
00061 }
00062 } else {
00063 wfDebug( __METHOD__ . ": $key still in use\n" );
00064 $status->successCount++;
00065 }
00066 $dbw->commit();
00067 }
00068 return $status;
00069 }
00070
00076 function checkRedirect( $title ) {
00077 global $wgMemc;
00078
00079 if( is_string( $title ) ) {
00080 $title = Title::newFromTitle( $title );
00081 }
00082 if( $title instanceof Title && $title->getNamespace() == NS_MEDIA ) {
00083 $title = Title::makeTitle( NS_FILE, $title->getText() );
00084 }
00085
00086 $memcKey = $this->getMemcKey( "image_redirect:" . md5( $title->getPrefixedDBkey() ) );
00087 $cachedValue = $wgMemc->get( $memcKey );
00088 if( $cachedValue ) {
00089 return Title::newFromDbKey( $cachedValue );
00090 } elseif( $cachedValue == ' ' ) { # FIXME: ugly hack, but BagOStuff caching seems to be weird and return false if !cachedValue, not only if it doesn't exist
00091 return false;
00092 }
00093
00094 $id = $this->getArticleID( $title );
00095 if( !$id ) {
00096 $wgMemc->set( $memcKey, " ", 9000 );
00097 return false;
00098 }
00099 $dbr = $this->getSlaveDB();
00100 $row = $dbr->selectRow(
00101 'redirect',
00102 array( 'rd_title', 'rd_namespace' ),
00103 array( 'rd_from' => $id ),
00104 __METHOD__
00105 );
00106
00107 if( $row ) $targetTitle = Title::makeTitle( $row->rd_namespace, $row->rd_title );
00108 $wgMemc->set( $memcKey, ($row ? $targetTitle->getPrefixedDBkey() : " "), 9000 );
00109 if( !$row ) {
00110 return false;
00111 }
00112 return $targetTitle;
00113 }
00114
00115
00120 protected function getArticleID( $title ) {
00121 if( !$title instanceof Title ) {
00122 return 0;
00123 }
00124 $dbr = $this->getSlaveDB();
00125 $id = $dbr->selectField(
00126 'page', // Table
00127 'page_id', //Field
00128 array( //Conditions
00129 'page_namespace' => $title->getNamespace(),
00130 'page_title' => $title->getDBKey(),
00131 ),
00132 __METHOD__ //Function name
00133 );
00134 return $id;
00135 }
00136
00137
00138
00139 function findBySha1( $hash ) {
00140 $dbr = $this->getSlaveDB();
00141 $res = $dbr->select(
00142 'image',
00143 LocalFile::selectFields(),
00144 array( 'img_sha1' => $hash )
00145 );
00146
00147 $result = array();
00148 while ( $row = $res->fetchObject() )
00149 $result[] = $this->newFileFromRow( $row );
00150 $res->free();
00151 return $result;
00152 }
00153
00154 /*
00155 * Find many files using one query
00156 */
00157 function findFiles( $titles ) {
00158 // FIXME: Only accepts a $titles array where the keys are the sanitized
00159 // file names.
00160
00161 if ( count( $titles ) == 0 ) return array();
00162
00163 $dbr = $this->getSlaveDB();
00164 $res = $dbr->select(
00165 'image',
00166 LocalFile::selectFields(),
00167 array( 'img_name' => array_keys( $titles ) )
00168 );
00169
00170 $result = array();
00171 while ( $row = $res->fetchObject() ) {
00172 $result[$row->img_name] = $this->newFileFromRow( $row );
00173 }
00174 $res->free();
00175 return $result;
00176 }
00177 }