/**
  * Delete all previously generated thumbnails, refresh metadata in memcached and purge the squid
  */
 function purgeCache($archiveFiles = array(), $shared = false)
 {
     global $wgInternalServer, $wgUseSquid;
     // Refresh metadata cache
     clearstatcache();
     $this->loadFromFile();
     $this->saveToCache();
     // Delete thumbnails
     $files = $this->getThumbnails($shared);
     $dir = wfImageThumbDir($this->name, $shared);
     $urls = array();
     foreach ($files as $file) {
         if (preg_match('/^(\\d+)px/', $file, $m)) {
             $urls[] = $wgInternalServer . $this->thumbUrl($m[1], $this->fromSharedDirectory);
             @unlink("{$dir}/{$file}");
         }
     }
     // Purge the squid
     if ($wgUseSquid) {
         $urls[] = $wgInternalServer . $this->getViewURL();
         foreach ($archiveFiles as $file) {
             $urls[] = $wgInternalServer . wfImageArchiveUrl($file);
         }
         wfPurgeSquidServers($urls);
     }
 }
Beispiel #2
0
 /**
  * Delete an old version of the image.
  *
  * Moves the file into an archive directory (or deletes it)
  * and removes the database row.
  *
  * Cache purging is done; logging is caller's responsibility.
  *
  * @param $reason
  * @throws MWException or FSException on database or filestore failure
  * @return true on success, false on some kind of failure
  */
 function deleteOld($archiveName, $reason, $suppress = false)
 {
     $transaction = new FSTransaction();
     $urlArr = array();
     if (!FileStore::lock()) {
         wfDebug(__METHOD__ . ": failed to acquire file store lock, aborting\n");
         return false;
     }
     $transaction = new FSTransaction();
     try {
         $dbw = wfGetDB(DB_MASTER);
         $dbw->begin();
         $transaction->add($this->prepareDeleteOld($archiveName, $reason, $suppress));
         $dbw->immediateCommit();
     } catch (MWException $e) {
         wfDebug(__METHOD__ . ": db error, rolling back file transaction\n");
         $transaction->rollback();
         FileStore::unlock();
         throw $e;
     }
     wfDebug(__METHOD__ . ": deleted db items, applying file transaction\n");
     $transaction->commit();
     FileStore::unlock();
     $this->purgeDescription();
     // Squid purging
     global $wgUseSquid;
     if ($wgUseSquid) {
         $urlArr = array(wfImageArchiveUrl($archiveName));
         wfPurgeSquidServers($urlArr);
     }
     return true;
 }
                                break;
                            case 'history':
                                if ($_SERVER['REQUEST_URI'] == $wgTitle->getInternalURL('action=history')) {
                                    $wgOut->setSquidMaxage($wgSquidMaxage);
                                }
                                require_once 'includes/PageHistory.php';
                                $history = new PageHistory($wgArticle);
                                $history->history();
                                break;
                            case 'raw':
                                require_once 'includes/RawPage.php';
                                $raw = new RawPage($wgArticle);
                                $raw->view();
                                break;
                            case 'purge':
                                wfPurgeSquidServers(array($wgTitle->getInternalURL()));
                                $wgOut->setSquidMaxage($wgSquidMaxage);
                                $wgTitle->invalidateCache();
                                $wgArticle->view();
                                break;
                            default:
                                if (wfRunHooks('UnknownAction', array($action, $wgArticle))) {
                                    $wgOut->errorpage('nosuchaction', 'nosuchactiontext');
                                }
                        }
                    }
                }
            }
        }
    }
}
Beispiel #4
0
 /**
  * Record a file upload in the upload log and the image table
  */
 function recordUpload2($oldver, $comment, $pageText, $props = false, $timestamp = false)
 {
     global $wgUser;
     $dbw = $this->repo->getMasterDB();
     if (!$props) {
         $props = $this->repo->getFileProps($this->getVirtualUrl());
     }
     $props['description'] = $comment;
     $props['user'] = $wgUser->getID();
     $props['user_text'] = $wgUser->getName();
     $props['timestamp'] = wfTimestamp(TS_MW);
     $this->setProps($props);
     // Delete thumbnails and refresh the metadata cache
     $this->purgeThumbnails();
     $this->saveToCache();
     wfPurgeSquidServers(array($this->getURL()));
     // Fail now if the file isn't there
     if (!$this->fileExists) {
         wfDebug(__METHOD__ . ": File " . $this->getPath() . " went missing!\n");
         return false;
     }
     $reupload = false;
     if ($timestamp === false) {
         $timestamp = $dbw->timestamp();
     }
     # 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->getName(), 'img_size' => $this->size, 'img_width' => intval($this->width), 'img_height' => intval($this->height), 'img_bits' => $this->bits, 'img_media_type' => $this->media_type, 'img_major_mime' => $this->major_mime, 'img_minor_mime' => $this->minor_mime, 'img_timestamp' => $timestamp, 'img_description' => $comment, 'img_user' => $wgUser->getID(), 'img_user_text' => $wgUser->getName(), 'img_metadata' => $this->metadata, 'img_sha1' => $this->sha1), __METHOD__, 'IGNORE');
     if ($dbw->affectedRows() == 0) {
         $reupload = true;
         # Collision, this is an update of a file
         # 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', 'oi_metadata' => 'img_metadata', 'oi_media_type' => 'img_media_type', 'oi_major_mime' => 'img_major_mime', 'oi_minor_mime' => 'img_minor_mime', 'oi_sha1' => 'img_sha1'), array('img_name' => $this->getName()), __METHOD__);
         # Update the current image row
         $dbw->update('image', array('img_size' => $this->size, 'img_width' => intval($this->width), 'img_height' => intval($this->height), 'img_bits' => $this->bits, 'img_media_type' => $this->media_type, 'img_major_mime' => $this->major_mime, 'img_minor_mime' => $this->minor_mime, 'img_timestamp' => $timestamp, 'img_description' => $comment, 'img_user' => $wgUser->getID(), 'img_user_text' => $wgUser->getName(), 'img_metadata' => $this->metadata, 'img_sha1' => $this->sha1), array('img_name' => $this->getName()), __METHOD__);
     } else {
         # This is a new file
         # 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);
     # Add the log entry
     $log = new LogPage('upload');
     $action = $reupload ? 'overwrite' : 'upload';
     $log->addEntry($action, $descTitle, $comment);
     if ($descTitle->exists()) {
         # Create a null revision
         $nullRevision = Revision::newNullRevision($dbw, $descTitle->getArticleId(), $log->getRcComment(), false);
         $nullRevision->insertOn($dbw);
         $article->updateRevisionOn($dbw, $nullRevision);
         # Invalidate the cache for the description page
         $descTitle->invalidateCache();
         $descTitle->purgeSquid();
     } else {
         // New file; create the description page.
         // There's already a log entry, so don't make a second RC entry
         $article->doEdit($pageText, $comment, EDIT_NEW | EDIT_SUPPRESS_RC);
     }
     # Hooks, hooks, the magic of hooks...
     wfRunHooks('FileUpload', array($this));
     # Commit the transaction now, in case something goes wrong later
     # The most important thing is that files don't get lost, especially archives
     $dbw->immediateCommit();
     # Invalidate cache for all pages using this file
     $update = new HTMLCacheUpdate($this->getTitle(), 'imagelinks');
     $update->doUpdate();
     return true;
 }
 /**
  * Transform a media file
  *
  * @param array $params An associative array of handler-specific parameters. Typical 
  *                      keys are width, height and page.
  * @param integer $flags A bitfield, may contain self::RENDER_NOW to force rendering
  * @return MediaTransformOutput
  */
 function transform($params, $flags = 0)
 {
     global $wgUseSquid, $wgIgnoreImageErrors;
     wfProfileIn(__METHOD__);
     do {
         if (!$this->canRender()) {
             // not a bitmap or renderable image, don't try.
             $thumb = $this->iconThumb();
             break;
         }
         $script = $this->getTransformScript();
         if ($script && !($flags & self::RENDER_NOW)) {
             // Use a script to transform on client request, if possible
             $thumb = $this->handler->getScriptedTransform($this, $script, $params);
             if ($thumb) {
                 break;
             }
         }
         $normalisedParams = $params;
         $this->handler->normaliseParams($this, $normalisedParams);
         $thumbName = $this->thumbName($normalisedParams);
         $thumbPath = $this->getThumbPath($thumbName);
         $thumbUrl = $this->getThumbUrl($thumbName);
         if ($this->repo->canTransformVia404() && !($flags & self::RENDER_NOW)) {
             $thumb = $this->handler->getTransform($this, $thumbPath, $thumbUrl, $params);
             break;
         }
         wfDebug(__METHOD__ . ": Doing stat for {$thumbPath}\n");
         $this->migrateThumbFile($thumbName);
         if (file_exists($thumbPath)) {
             $thumb = $this->handler->getTransform($this, $thumbPath, $thumbUrl, $params);
             break;
         }
         $thumb = $this->handler->doTransform($this, $thumbPath, $thumbUrl, $params);
         // Ignore errors if requested
         if (!$thumb) {
             $thumb = null;
         } elseif ($thumb->isError()) {
             $this->lastError = $thumb->toText();
             if ($wgIgnoreImageErrors && !($flags & self::RENDER_NOW)) {
                 $thumb = $this->handler->getTransform($this, $thumbPath, $thumbUrl, $params);
             }
         }
         if ($wgUseSquid) {
             wfPurgeSquidServers(array($thumbUrl));
         }
     } while (false);
     wfProfileOut(__METHOD__);
     return $thumb;
 }
 function doDelete()
 {
     global $wgOut, $wgUser, $wgContLang, $wgRequest;
     global $wgUseSquid, $wgInternalServer, $wgPostCommitUpdateList;
     $fname = 'ImagePage::doDelete';
     $reason = $wgRequest->getVal('wpReason');
     $oldimage = $wgRequest->getVal('oldimage');
     $dbw =& wfGetDB(DB_MASTER);
     if (!is_null($oldimage)) {
         if (strlen($oldimage) < 16) {
             $wgOut->unexpectedValueError('oldimage', htmlspecialchars($oldimage));
             return;
         }
         if (strstr($oldimage, "/") || strstr($oldimage, "\\")) {
             $wgOut->unexpectedValueError('oldimage', htmlspecialchars($oldimage));
             return;
         }
         # Invalidate description page cache
         $this->mTitle->invalidateCache();
         # Squid purging
         if ($wgUseSquid) {
             $urlArr = array($wgInternalServer . wfImageArchiveUrl($oldimage), $wgInternalServer . $this->mTitle->getFullURL());
             wfPurgeSquidServers($urlArr);
         }
         $this->doDeleteOldImage($oldimage);
         $dbw->delete('oldimage', array('oi_archive_name' => $oldimage));
         $deleted = $oldimage;
     } else {
         $image = $this->mTitle->getDBkey();
         $dest = wfImageDir($image);
         $archive = wfImageDir($image);
         # Delete the image file if it exists; due to sync problems
         # or manual trimming sometimes the file will be missing.
         $targetFile = "{$dest}/{$image}";
         if (file_exists($targetFile) && !@unlink($targetFile)) {
             # If the deletion operation actually failed, bug out:
             $wgOut->fileDeleteError($targetFile);
             return;
         }
         $dbw->delete('image', array('img_name' => $image));
         $res = $dbw->select('oldimage', array('oi_archive_name'), array('oi_name' => $image));
         # Purge archive URLs from the squid
         $urlArr = array();
         while ($s = $dbw->fetchObject($res)) {
             $this->doDeleteOldImage($s->oi_archive_name);
             $urlArr[] = $wgInternalServer . wfImageArchiveUrl($s->oi_archive_name);
         }
         # And also the HTML of all pages using this image
         $linksTo = $this->img->getLinksTo();
         if ($wgUseSquid) {
             $u = SquidUpdate::newFromTitles($linksTo, $urlArr);
             array_push($wgPostCommitUpdateList, $u);
         }
         $dbw->delete('oldimage', array('oi_name' => $image));
         # Image itself is now gone, and database is cleaned.
         # Now we remove the image description page.
         $article = new Article($this->mTitle);
         $article->doDeleteArticle($reason);
         # ignore errors
         # Invalidate parser cache and client cache for pages using this image
         # This is left until relatively late to reduce lock time
         Title::touchArray($linksTo);
         /* Delete thumbnails and refresh image metadata cache */
         $this->img->purgeCache();
         $deleted = $image;
     }
     $wgOut->setPagetitle(wfMsg('actioncomplete'));
     $wgOut->setRobotpolicy('noindex,nofollow');
     $loglink = '[[Special:Log/delete|' . wfMsg('deletionlog') . ']]';
     $text = wfMsg('deletedtext', $deleted, $loglink);
     $wgOut->addWikiText($text);
     $wgOut->returnToMain(false, $this->mTitle->getPrefixedText());
 }