image.php
字号:
if ( $wgUseSquid ) { $urls[] = $this->getViewURL(); foreach ( $archiveFiles as $file ) { $urls[] = wfImageArchiveUrl( $file ); } wfPurgeSquidServers( $urls ); } } /** * Purge the image description page, but don't go after * pages using the image. Use when modifying file history * but not the current data. */ function purgeDescription() { $page = Title::makeTitle( NS_IMAGE, $this->name ); $page->invalidateCache(); $page->purgeSquid(); } /** * Purge metadata and all affected pages when the image is created, * deleted, or majorly updated. A set of additional URLs may be * passed to purge, such as specific image files which have changed. * @param $urlArray array */ function purgeEverything( $urlArr=array() ) { // Delete thumbnails and refresh image metadata cache $this->purgeCache(); $this->purgeDescription(); // Purge cache of all pages using this image $update = new HTMLCacheUpdate( $this->getTitle(), 'imagelinks' ); $update->doUpdate(); } function checkDBSchema(&$db) { global $wgCheckDBSchema; if (!$wgCheckDBSchema) { return; } # img_name must be unique if ( !$db->indexUnique( 'image', 'img_name' ) && !$db->indexExists('image','PRIMARY') ) { throw new MWException( 'Database schema not up to date, please run maintenance/archives/patch-image_name_unique.sql' ); } # new fields must exist # # Not really, there's hundreds of checks like this that we could do and they're all pointless, because # if the fields are missing, the database will loudly report a query error, the first time you try to do # something. The only reason I put the above schema check in was because the absence of that particular # index would lead to an annoying subtle bug. No error message, just some very odd behaviour on duplicate # uploads. -- TS /* if ( !$db->fieldExists( 'image', 'img_media_type' ) || !$db->fieldExists( 'image', 'img_metadata' ) || !$db->fieldExists( 'image', 'img_width' ) ) { throw new MWException( 'Database schema not up to date, please run maintenance/update.php' ); } */ } /** * Return the image history of this image, line by line. * starts with current version, then old versions. * uses $this->historyLine to check which line to return: * 0 return line for current version * 1 query for old versions, return first one * 2, ... return next old version from above query * * @public */ function nextHistoryLine() { $dbr =& wfGetDB( DB_SLAVE ); $this->checkDBSchema($dbr); if ( $this->historyLine == 0 ) {// called for the first time, return line from cur $this->historyRes = $dbr->select( 'image', array( 'img_size', 'img_description', 'img_user','img_user_text', 'img_timestamp', 'img_width', 'img_height', "'' AS oi_archive_name" ), array( 'img_name' => $this->title->getDBkey() ), __METHOD__ ); if ( 0 == wfNumRows( $this->historyRes ) ) { return FALSE; } } else if ( $this->historyLine == 1 ) { $this->historyRes = $dbr->select( 'oldimage', array( 'oi_size AS img_size', 'oi_description AS img_description', 'oi_user AS img_user', 'oi_user_text AS img_user_text', 'oi_timestamp AS img_timestamp', 'oi_width as img_width', 'oi_height as img_height', 'oi_archive_name' ), array( 'oi_name' => $this->title->getDBkey() ), __METHOD__, array( 'ORDER BY' => 'oi_timestamp DESC' ) ); } $this->historyLine ++; return $dbr->fetchObject( $this->historyRes ); } /** * Reset the history pointer to the first element of the history * @public */ function resetHistory() { $this->historyLine = 0; } /** * Return the full filesystem path to the file. Note that this does * not mean that a file actually exists under that location. * * This path depends on whether directory hashing is active or not, * i.e. whether the images are all found in the same directory, * or in hashed paths like /images/3/3c. * * @public * @param boolean $fromSharedDirectory Return the path to the file * in a shared repository (see $wgUseSharedRepository and related * options in DefaultSettings.php) instead of a local one. * */ function getFullPath( $fromSharedRepository = false ) { global $wgUploadDirectory, $wgSharedUploadDirectory; $dir = $fromSharedRepository ? $wgSharedUploadDirectory : $wgUploadDirectory; // $wgSharedUploadDirectory may be false, if thumb.php is used if ( $dir ) { $fullpath = $dir . wfGetHashPath($this->name, $fromSharedRepository) . $this->name; } else { $fullpath = false; } return $fullpath; } /** * @return bool * @static */ function isHashed( $shared ) { global $wgHashedUploadDirectory, $wgHashedSharedUploadDirectory; return $shared ? $wgHashedSharedUploadDirectory : $wgHashedUploadDirectory; } /** * Record an image upload in the upload log and the image table */ function recordUpload( $oldver, $desc, $license = '', $copyStatus = '', $source = '', $watch = false ) { global $wgUser, $wgUseCopyrightUpload; $dbw =& wfGetDB( DB_MASTER ); $this->checkDBSchema($dbw); // Delete thumbnails and refresh the metadata cache $this->purgeCache(); // Fail now if the image isn't there if ( !$this->fileExists || $this->fromSharedDirectory ) { wfDebug( "Image::recordUpload: File ".$this->imagePath." went missing!\n" ); return false; } if ( $wgUseCopyrightUpload ) { if ( $license != '' ) { $licensetxt = '== ' . wfMsgForContent( 'license' ) . " ==\n" . '{{' . $license . '}}' . "\n"; } $textdesc = '== ' . wfMsg ( 'filedesc' ) . " ==\n" . $desc . "\n" . '== ' . wfMsgForContent ( 'filestatus' ) . " ==\n" . $copyStatus . "\n" . "$licensetxt" . '== ' . wfMsgForContent ( 'filesource' ) . " ==\n" . $source ; } else { if ( $license != '' ) { $filedesc = $desc == '' ? '' : '== ' . wfMsg ( 'filedesc' ) . " ==\n" . $desc . "\n"; $textdesc = $filedesc . '== ' . wfMsgForContent ( 'license' ) . " ==\n" . '{{' . $license . '}}' . "\n"; } else { $textdesc = $desc; } } $now = $dbw->timestamp(); #split mime type if (strpos($this->mime,'/')!==false) { list($major,$minor)= explode('/',$this->mime,2); } else { $major= $this->mime; $minor= "unknown"; } # Test to see if the row exists using INSERT IGNORE # This avoids race conditions by locking the row until the commit, and also # doesn't deadlock. SELECT FOR UPDATE causes a deadlock for every race condition. $dbw->insert( 'image', array( 'img_name' => $this->name, 'img_size'=> $this->size, 'img_width' => intval( $this->width ), 'img_height' => intval( $this->height ), 'img_bits' => $this->bits, 'img_media_type' => $this->type, 'img_major_mime' => $major, 'img_minor_mime' => $minor, 'img_timestamp' => $now, 'img_description' => $desc, 'img_user' => $wgUser->getID(), 'img_user_text' => $wgUser->getName(), 'img_metadata' => $this->metadata, ), __METHOD__, 'IGNORE' ); if( $dbw->affectedRows() == 0 ) { # Collision, this is an update of an image # Insert previous contents into oldimage $dbw->insertSelect( 'oldimage', 'image', array( 'oi_name' => 'img_name', 'oi_archive_name' => $dbw->addQuotes( $oldver ), 'oi_size' => 'img_size', 'oi_width' => 'img_width', 'oi_height' => 'img_height', 'oi_bits' => 'img_bits', 'oi_timestamp' => 'img_timestamp', 'oi_description' => 'img_description', 'oi_user' => 'img_user', 'oi_user_text' => 'img_user_text', ), array( 'img_name' => $this->name ), __METHOD__ ); # Update the current image row $dbw->update( 'image', array( /* SET */ 'img_size' => $this->size, 'img_width' => intval( $this->width ), 'img_height' => intval( $this->height ), 'img_bits' => $this->bits, 'img_media_type' => $this->type, 'img_major_mime' => $major, 'img_minor_mime' => $minor, 'img_timestamp' => $now, 'img_description' => $desc, 'img_user' => $wgUser->getID(), 'img_user_text' => $wgUser->getName(), 'img_metadata' => $this->metadata, ), array( /* WHERE */ 'img_name' => $this->name ), __METHOD__ ); } else { # This is a new image # Update the image count $site_stats = $dbw->tableName( 'site_stats' ); $dbw->query( "UPDATE $site_stats SET ss_images=ss_images+1", __METHOD__ ); } $descTitle = $this->getTitle(); $article = new Article( $descTitle ); $minor = false; $watch = $watch || $wgUser->isWatched( $descTitle ); $suppressRC = true; // There's already a log entry, so don't double the RC load if( $descTitle->exists() ) { // TODO: insert a null revision into the page history for this update. if( $watch ) { $wgUser->addWatch( $descTitle ); } # Invalidate the cache for the description page $descTitle->invalidateCache(); $descTitle->purgeSquid(); } else { // New image; create the description page. $article->insertNewArticle( $textdesc, $desc, $minor, $watch, $suppressRC ); } # Add the log entry $log = new LogPage( 'upload' ); $log->addEntry( 'upload', $descTitle, $desc ); # Commit the transaction now, in case something goes wrong later # The most important thing is that images don't get lost, especially archives $dbw->immediateCommit(); # Invalidate cache for all pages using this image $update = new HTMLCacheUpdate( $this->getTitle(), 'imagelinks' ); $update->doUpdate(); return true; } /** * Get an array of Title objects which are articles which use this image * Also adds their IDs to the link cache * * This is mostly copied from Title::getLinksTo() * * @deprecated Use HTMLCacheUpdate, this function uses too much memory */ function getLinksTo( $options = '' ) { wfProfileIn( __METHOD__ ); if ( $options ) { $db =& wfGetDB( DB_MASTER ); } else { $db =& wfGetDB( DB_SLAVE ); } $linkCache =& LinkCache::singleton(); extract( $db->tableNames( 'page', 'imagelinks' ) ); $encName = $db->addQuotes( $this->name ); $sql = "SELECT page_namespace,page_title,page_id FROM $page,$imagelinks WHERE page_id=il_from AND il_to=$encName $options"; $res = $db->query( $sql, __METHOD__ ); $retVal = array(); if ( $db->numRows( $res ) ) { while ( $row = $db->fetchObject( $res ) ) { if ( $titleObj = Title::makeTitle( $row->page_namespace, $row->page_title ) ) { $linkCache->addGoodLinkObj( $row->page_id, $titleObj ); $retVal[] = $titleObj; } } } $db->freeResult( $res ); wfProfileOut( __METHOD__ ); return $retVal; } /** * Retrive Exif data from the file and prune unrecognized tags * and/or tags with invalid contents * * @param $filename * @return array */ private function retrieveExifData( $filename ) { global $wgShowEXIF; /* if ( $this->getMimeType() !== "image/jpeg" ) return array(); */ if( $wgShowEXIF && file_exists( $filename ) ) { $exif = new Exif( $filename ); return $exif->getFilteredData(); } return array(); } function getExifData() { global $wgRequest; if ( $this->metadata === '0' ) return array(); $purge = $wgRequest->getVal( 'action' ) == 'purge'; $ret = unserialize( $this->metadata ); $oldver = isset( $ret['MEDIAWIKI_EXIF_VERSION'] ) ? $ret['MEDIAWIKI_EXIF_VERSION'] : 0; $newver = Exif::version(); if ( !count( $ret ) || $purge || $oldver != $newver ) { $this->purgeMetadataCache(); $this->updateExifData( $newver ); } if ( isset( $ret['MEDIAWIKI_EXIF_VERSION'] ) ) unset( $ret['MEDIAWIKI_EXIF_VERSION'] ); $format = new FormatExif( $ret ); return $format->getFormattedData(); } function updateExifData( $version ) { if ( $this->getImagePath() === false ) # Not a local image return; # Get EXIF data from image $exif = $this->retrieveExifData( $this->imagePath ); if ( count( $exif ) ) { $exif['MEDIAWIKI_EXIF_VERSION'] = $version; $this->metadata = serialize( $exif ); } else { $this->metadata = '0'; } # Update EXIF data in database $dbw =& wfGetDB( DB_MASTER ); $this->checkDBSchema($dbw); $dbw->update( 'image', array( 'img_metadata' => $this->metadata ), array( 'img_name' => $this->name ), __METHOD__ ); } /** * Returns true if the image does not come from the shared * image repository. * * @return bool */ function isLocal() { return !$this->fromSharedDirectory; } /** * Was this image ever deleted from the wiki? * * @return bool */ function wasDeleted() { $title = Title::makeTitle( NS_IMAGE, $this->name ); return ( $title->isDeleted() > 0 ); } /** * Delete all versions of the image. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -