summaryrefslogtreecommitdiff
path: root/includes/filerepo
diff options
context:
space:
mode:
authorPierre Schmitz <pierre@archlinux.de>2008-12-15 18:02:47 +0100
committerPierre Schmitz <pierre@archlinux.de>2008-12-15 18:02:47 +0100
commit396b28f3d881f5debd888ba9bb9b47c2d478a76f (patch)
tree10d6e1a721ee4ef69def34a57f02d7eb3fc9e31e /includes/filerepo
parent0be4d3ccf6c4fe98a72704f9463ecdea2ee5e615 (diff)
update to Mediawiki 1.13.3; some cleanups
Diffstat (limited to 'includes/filerepo')
-rw-r--r--includes/filerepo/FSRepo.php21
-rw-r--r--includes/filerepo/ICRepo.php309
2 files changed, 16 insertions, 314 deletions
diff --git a/includes/filerepo/FSRepo.php b/includes/filerepo/FSRepo.php
index 08ec1514..eb8df0f5 100644
--- a/includes/filerepo/FSRepo.php
+++ b/includes/filerepo/FSRepo.php
@@ -149,10 +149,8 @@ class FSRepo extends FileRepo {
if ( !wfMkdirParents( $dstDir ) ) {
return $this->newFatal( 'directorycreateerror', $dstDir );
}
- // In the deleted zone, seed new directories with a blank
- // index.html, to prevent crawling
if ( $dstZone == 'deleted' ) {
- file_put_contents( "$dstDir/index.html", '' );
+ $this->initDeletedDir( $dstDir );
}
}
@@ -215,6 +213,20 @@ class FSRepo extends FileRepo {
}
/**
+ * Take all available measures to prevent web accessibility of new deleted
+ * directories, in case the user has not configured offline storage
+ */
+ protected function initDeletedDir( $dir ) {
+ // Add a .htaccess file to the root of the deleted zone
+ $root = $this->getZonePath( 'deleted' );
+ if ( !file_exists( "$root/.htaccess" ) ) {
+ file_put_contents( "$root/.htaccess", "Deny from all\n" );
+ }
+ // Seed new directories with a blank index.html, to prevent crawling
+ file_put_contents( "$dir/index.html", '' );
+ }
+
+ /**
* Pick a random name in the temp zone and store a file to it.
* @param string $originalName The base name of the file as specified
* by the user. The file extension will be maintained.
@@ -393,8 +405,7 @@ class FSRepo extends FileRepo {
$status->fatal( 'directorycreateerror', $archiveDir );
continue;
}
- // Seed new directories with a blank index.html, to prevent crawling
- file_put_contents( "$archiveDir/index.html", '' );
+ $this->initDeletedDir( $archiveDir );
}
// Check if the archive directory is writable
// This doesn't appear to work on NTFS
diff --git a/includes/filerepo/ICRepo.php b/includes/filerepo/ICRepo.php
deleted file mode 100644
index ab686f9b..00000000
--- a/includes/filerepo/ICRepo.php
+++ /dev/null
@@ -1,309 +0,0 @@
-<?php
-
-/**
- * A repository for files accessible via InstantCommons.
- */
-
-class ICRepo extends LocalRepo {
- var $directory, $url, $hashLevels, $cache;
- var $fileFactory = array( 'ICFile', 'newFromTitle' );
- var $oldFileFactory = false;
-
- function __construct( $info ) {
- parent::__construct( $info );
- // Required settings
- $this->directory = $info['directory'];
- $this->url = $info['url'];
- $this->hashLevels = $info['hashLevels'];
- if(isset($info['cache'])){
- $this->cache = getcwd().'/images/'.$info['cache'];
- }
- }
-}
-
-/**
- * A file loaded from InstantCommons
- */
-class ICFile extends LocalFile{
- static function newFromTitle($title,$repo){
- return new self($title, $repo);
- }
-
- /**
- * Returns true if the file comes from the local file repository.
- *
- * @return bool
- */
- function isLocal() {
- return true;
- }
-
- function load(){
- if (!$this->dataLoaded ) {
- if ( !$this->loadFromCache() ) {
- if(!$this->loadFromDB()){
- $this->loadFromIC();
- }
- $this->saveToCache();
- }
- $this->dataLoaded = true;
- }
- }
-
- /**
- * Load file metadata from the DB
- */
- function loadFromDB() {
- wfProfileIn( __METHOD__ );
-
- # Unconditionally set loaded=true, we don't want the accessors constantly rechecking
- $this->dataLoaded = true;
-
- $dbr = $this->repo->getSlaveDB();
-
- $row = $dbr->selectRow( 'ic_image', $this->getCacheFields( 'img_' ),
- array( 'img_name' => $this->getName() ), __METHOD__ );
- if ( $row ) {
- if (trim($row->img_media_type)==NULL) {
- $this->upgradeRow();
- $this->upgraded = true;
- }
- $this->loadFromRow( $row );
- //This means that these files are local so the repository locations are local
- $this->setUrlPathLocal();
- $this->fileExists = true;
- //var_dump($this); exit;
- } else {
- $this->fileExists = false;
- }
-
- wfProfileOut( __METHOD__ );
-
- return $this->fileExists;
- }
-
- /**
- * Fix assorted version-related problems with the image row by reloading it from the file
- */
- function upgradeRow() {
- wfProfileIn( __METHOD__ );
-
- $this->loadFromIC();
-
- $dbw = $this->repo->getMasterDB();
- list( $major, $minor ) = self::splitMime( $this->mime );
-
- wfDebug(__METHOD__.': upgrading '.$this->getName()." to the current schema\n");
-
- $dbw->update( 'ic_image',
- array(
- 'img_width' => $this->width,
- 'img_height' => $this->height,
- 'img_bits' => $this->bits,
- 'img_media_type' => $this->type,
- 'img_major_mime' => $major,
- 'img_minor_mime' => $minor,
- 'img_metadata' => $this->metadata,
- ), array( 'img_name' => $this->getName() ),
- __METHOD__
- );
- $this->saveToCache();
- wfProfileOut( __METHOD__ );
- }
-
- function exists(){
- $this->load();
- return $this->fileExists;
- }
-
- /**
- * Fetch the file from the repository. Check local ic_images table first. If not available, check remote server
- */
- function loadFromIC(){
- # Unconditionally set loaded=true, we don't want the accessors constantly rechecking
- $this->dataLoaded = true;
- $icUrl = $this->repo->directory.'&media='.$this->title->mDbkeyform;
- if($h = @fopen($icUrl, 'rb')){
- $contents = fread($h, 3000);
- $image = $this->api_xml_to_array($contents);
- if($image['fileExists']){
- foreach($image as $property=>$value){
- if($property=="url"){$value=$this->repo->url.$value; }
- $this->$property = $value;
- }
- if($this->curl_file_get_contents($this->repo->url.$image['url'], $this->repo->cache.'/'.$image['name'])){
- //Record the image
- $this->recordDownload("Downloaded with InstantCommons");
-
- //Then cache it
- }else{//set fileExists back to false
- $this->fileExists = false;
- }
- }
- }
- }
-
- function setUrlPathLocal(){
- global $wgScriptPath;
- $path = $wgScriptPath.'/'.substr($this->repo->cache, strlen($wgScriptPath));
- $this->repo->url = $path;//.'/'.rawurlencode($this->title->mDbkeyform);
- $this->repo->directory = $this->repo->cache;//.'/'.rawurlencode($this->title->mDbkeyform);
-
- }
-
- function getThumbPath( $suffix=false ){
- $path = $this->repo->cache;
- if ( $suffix !== false ) {
- $path .= '/thumb/' . rawurlencode( $suffix );
- }
- return $path;
- }
- function getThumbUrl( $suffix=false ){
- global $wgScriptPath;
- $path = $wgScriptPath.'/'.substr($this->repo->cache, strlen($wgScriptPath));
- if ( $suffix !== false ) {
- $path .= '/thumb/' . rawurlencode( $suffix );
- }
- return $path;
- }
-
- /**
- * Convert the InstantCommons Server API XML Response to an associative array
- */
- function api_xml_to_array($xml){
- preg_match("/<instantcommons><image(.*?)<\/instantcommons>/",$xml,$match);
- preg_match_all("/(.*?=\".*?\")/",$match[1], $matches);
- foreach($matches[1] as $match){
- list($key,$value) = split("=",$match);
- $image[trim($key,'<" ')]=trim($value,' "');
- }
- return $image;
- }
-
- /**
- * Use cURL to read the content of a URL into a string
- * ref: http://groups-beta.google.com/group/comp.lang.php/browse_thread/thread/8efbbaced3c45e3c/d63c7891cf8e380b?lnk=raot
- * @param string $url - the URL to fetch
- * @param resource $fp - filename to write file contents to
- * @param boolean $bg - call cURL in the background (don't hang page until complete)
- * @param int $timeout - cURL connect timeout
- */
- function curl_file_get_contents($url, $fp, $bg=TRUE, $timeout = 1) {
- # Call curl in the background to download the file
- $cmd = 'curl '.wfEscapeShellArg($url).' -o '.$fp.' &';
- wfDebug('Curl download initiated='.$cmd );
- $success = false;
- $file_contents = array();
- $file_contents['err'] = wfShellExec($cmd, $file_contents['return']);
- if($file_contents['err']==0){//Success
- $success = true;
- }
- return $success;
- }
-
- function getMasterDB() {
- if ( !isset( $this->dbConn ) ) {
- $class = 'Database' . ucfirst( $this->dbType );
- $this->dbConn = new $class( $this->dbServer, $this->dbUser,
- $this->dbPassword, $this->dbName, false, $this->dbFlags,
- $this->tablePrefix );
- }
- return $this->dbConn;
- }
-
- /**
- * Record a file upload in the upload log and the image table
- */
- private function recordDownload($comment='', $timestamp = false ){
- global $wgUser;
-
- $dbw = $this->repo->getMasterDB();
-
- if ( $timestamp === false ) {
- $timestamp = $dbw->timestamp();
- }
- list( $major, $minor ) = self::splitMime( $this->mime );
-
- # 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( 'ic_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->type,
- 'img_major_mime' => $major,
- 'img_minor_mime' => $minor,
- 'img_timestamp' => $timestamp,
- 'img_description' => $comment,
- '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 a file
- # Update the current image row
- $dbw->update( 'ic_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->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,
- ), array( /* WHERE */
- '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( 'icdownload' );
- $log->addEntry( 'InstantCommons download', $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();
- }
-
-
- # 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;
- }
-
-}
-