[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/includes/api/ -> ApiQueryDuplicateFiles.php (source)

   1  <?php
   2  /**
   3   *
   4   *
   5   * Created on Sep 27, 2008
   6   *
   7   * Copyright © 2008 Roan Kattouw "<Firstname>.<Lastname>@gmail.com"
   8   *
   9   * This program is free software; you can redistribute it and/or modify
  10   * it under the terms of the GNU General Public License as published by
  11   * the Free Software Foundation; either version 2 of the License, or
  12   * (at your option) any later version.
  13   *
  14   * This program is distributed in the hope that it will be useful,
  15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17   * GNU General Public License for more details.
  18   *
  19   * You should have received a copy of the GNU General Public License along
  20   * with this program; if not, write to the Free Software Foundation, Inc.,
  21   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  22   * http://www.gnu.org/copyleft/gpl.html
  23   *
  24   * @file
  25   */
  26  
  27  /**
  28   * A query module to list duplicates of the given file(s)
  29   *
  30   * @ingroup API
  31   */
  32  class ApiQueryDuplicateFiles extends ApiQueryGeneratorBase {
  33  
  34  	public function __construct( ApiQuery $query, $moduleName ) {
  35          parent::__construct( $query, $moduleName, 'df' );
  36      }
  37  
  38  	public function execute() {
  39          $this->run();
  40      }
  41  
  42  	public function getCacheMode( $params ) {
  43          return 'public';
  44      }
  45  
  46  	public function executeGenerator( $resultPageSet ) {
  47          $this->run( $resultPageSet );
  48      }
  49  
  50      /**
  51       * @param ApiPageSet $resultPageSet
  52       */
  53  	private function run( $resultPageSet = null ) {
  54          $params = $this->extractRequestParams();
  55          $namespaces = $this->getPageSet()->getAllTitlesByNamespace();
  56          if ( empty( $namespaces[NS_FILE] ) ) {
  57              return;
  58          }
  59          $images = $namespaces[NS_FILE];
  60  
  61          if ( $params['dir'] == 'descending' ) {
  62              $images = array_reverse( $images );
  63          }
  64  
  65          $skipUntilThisDup = false;
  66          if ( isset( $params['continue'] ) ) {
  67              $cont = explode( '|', $params['continue'] );
  68              $this->dieContinueUsageIf( count( $cont ) != 2 );
  69              $fromImage = $cont[0];
  70              $skipUntilThisDup = $cont[1];
  71              // Filter out any images before $fromImage
  72              foreach ( $images as $image => $pageId ) {
  73                  if ( $image < $fromImage ) {
  74                      unset( $images[$image] );
  75                  } else {
  76                      break;
  77                  }
  78              }
  79          }
  80  
  81          $filesToFind = array_keys( $images );
  82          if ( $params['localonly'] ) {
  83              $files = RepoGroup::singleton()->getLocalRepo()->findFiles( $filesToFind );
  84          } else {
  85              $files = RepoGroup::singleton()->findFiles( $filesToFind );
  86          }
  87  
  88          $fit = true;
  89          $count = 0;
  90          $titles = array();
  91  
  92          $sha1s = array();
  93          foreach ( $files as $file ) {
  94              /** @var $file File */
  95              $sha1s[$file->getName()] = $file->getSha1();
  96          }
  97  
  98          // find all files with the hashes, result format is:
  99          // array( hash => array( dup1, dup2 ), hash1 => ... )
 100          $filesToFindBySha1s = array_unique( array_values( $sha1s ) );
 101          if ( $params['localonly'] ) {
 102              $filesBySha1s = RepoGroup::singleton()->getLocalRepo()->findBySha1s( $filesToFindBySha1s );
 103          } else {
 104              $filesBySha1s = RepoGroup::singleton()->findBySha1s( $filesToFindBySha1s );
 105          }
 106  
 107          // iterate over $images to handle continue param correct
 108          foreach ( $images as $image => $pageId ) {
 109              if ( !isset( $sha1s[$image] ) ) {
 110                  continue; //file does not exist
 111              }
 112              $sha1 = $sha1s[$image];
 113              $dupFiles = $filesBySha1s[$sha1];
 114              if ( $params['dir'] == 'descending' ) {
 115                  $dupFiles = array_reverse( $dupFiles );
 116              }
 117              /** @var $dupFile File */
 118              foreach ( $dupFiles as $dupFile ) {
 119                  $dupName = $dupFile->getName();
 120                  if ( $image == $dupName && $dupFile->isLocal() ) {
 121                      continue; //ignore the local file itself
 122                  }
 123                  if ( $skipUntilThisDup !== false && $dupName < $skipUntilThisDup ) {
 124                      continue; //skip to pos after the image from continue param
 125                  }
 126                  $skipUntilThisDup = false;
 127                  if ( ++$count > $params['limit'] ) {
 128                      $fit = false; //break outer loop
 129                      // We're one over limit which shows that
 130                      // there are additional images to be had. Stop here...
 131                      $this->setContinueEnumParameter( 'continue', $image . '|' . $dupName );
 132                      break;
 133                  }
 134                  if ( !is_null( $resultPageSet ) ) {
 135                      $titles[] = $dupFile->getTitle();
 136                  } else {
 137                      $r = array(
 138                          'name' => $dupName,
 139                          'user' => $dupFile->getUser( 'text' ),
 140                          'timestamp' => wfTimestamp( TS_ISO_8601, $dupFile->getTimestamp() )
 141                      );
 142                      if ( !$dupFile->isLocal() ) {
 143                          $r['shared'] = '';
 144                      }
 145                      $fit = $this->addPageSubItem( $pageId, $r );
 146                      if ( !$fit ) {
 147                          $this->setContinueEnumParameter( 'continue', $image . '|' . $dupName );
 148                          break;
 149                      }
 150                  }
 151              }
 152              if ( !$fit ) {
 153                  break;
 154              }
 155          }
 156          if ( !is_null( $resultPageSet ) ) {
 157              $resultPageSet->populateFromTitles( $titles );
 158          }
 159      }
 160  
 161  	public function getAllowedParams() {
 162          return array(
 163              'limit' => array(
 164                  ApiBase::PARAM_DFLT => 10,
 165                  ApiBase::PARAM_TYPE => 'limit',
 166                  ApiBase::PARAM_MIN => 1,
 167                  ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
 168                  ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
 169              ),
 170              'continue' => null,
 171              'dir' => array(
 172                  ApiBase::PARAM_DFLT => 'ascending',
 173                  ApiBase::PARAM_TYPE => array(
 174                      'ascending',
 175                      'descending'
 176                  )
 177              ),
 178              'localonly' => false,
 179          );
 180      }
 181  
 182  	public function getParamDescription() {
 183          return array(
 184              'limit' => 'How many duplicate files to return',
 185              'continue' => 'When more results are available, use this to continue',
 186              'dir' => 'The direction in which to list',
 187              'localonly' => 'Look only for files in the local repository',
 188          );
 189      }
 190  
 191  	public function getDescription() {
 192          return 'List all files that are duplicates of the given file(s) based on hash values.';
 193      }
 194  
 195  	public function getExamples() {
 196          return array(
 197              'api.php?action=query&titles=File:Albert_Einstein_Head.jpg&prop=duplicatefiles',
 198              'api.php?action=query&generator=allimages&prop=duplicatefiles',
 199          );
 200      }
 201  
 202  	public function getHelpUrls() {
 203          return 'https://www.mediawiki.org/wiki/API:Properties#duplicatefiles_.2F_df';
 204      }
 205  }


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1