/**
  * Lock a single resource key
  *
  * @param $path string
  * @param $type integer
  * @return Status 
  */
 protected function doSingleLock($path, $type)
 {
     $status = Status::newGood();
     if (isset($this->locksHeld[$path][$type])) {
         ++$this->locksHeld[$path][$type];
     } elseif (isset($this->locksHeld[$path][self::LOCK_EX])) {
         $this->locksHeld[$path][$type] = 1;
     } else {
         wfSuppressWarnings();
         $handle = fopen($this->getLockPath($path), 'a+');
         wfRestoreWarnings();
         if (!$handle) {
             // lock dir missing?
             wfMkdirParents($this->lockDir);
             $handle = fopen($this->getLockPath($path), 'a+');
             // try again
         }
         if ($handle) {
             // Either a shared or exclusive lock
             $lock = $type == self::LOCK_SH ? LOCK_SH : LOCK_EX;
             if (flock($handle, $lock | LOCK_NB)) {
                 // Record this lock as active
                 $this->locksHeld[$path][$type] = 1;
                 $this->handles[$path][$type] = $handle;
             } else {
                 fclose($handle);
                 $status->fatal('lockmanager-fail-acquirelock', $path);
             }
         } else {
             $status->fatal('lockmanager-fail-openlock', $path);
         }
     }
     return $status;
 }
Example #2
0
 function doTransform($image, $dstPath, $dstUrl, $params, $flags = 0)
 {
     global $wgSVGConverters, $wgSVGConverter, $wgSVGConverterPath;
     if (!$this->normaliseParams($image, $params)) {
         return new TransformParameterError($params);
     }
     $clientWidth = $params['width'];
     $clientHeight = $params['height'];
     $physicalWidth = $params['physicalWidth'];
     $physicalHeight = $params['physicalHeight'];
     $srcPath = $image->getPath();
     if ($flags & self::TRANSFORM_LATER) {
         return new ThumbnailImage($image, $dstUrl, $clientWidth, $clientHeight, $dstPath);
     }
     if (!wfMkdirParents(dirname($dstPath))) {
         return new MediaTransformError('thumbnail_error', $clientWidth, $clientHeight, wfMsg('thumbnail_dest_directory'));
     }
     $status = $this->rasterize($srcPath, $dstPath, $physicalWidth, $physicalHeight);
     if ($status === true) {
         return new ThumbnailImage($image, $dstUrl, $clientWidth, $clientHeight, $dstPath);
     } else {
         return $status;
         // MediaTransformError
     }
 }
 function doTransform($image, $dstPath, $dstUrl, $params, $flags = 0)
 {
     global $wgFLVConverters, $wgFLVConverter, $wgFLVConverterPath;
     if (!$this->normaliseParams($image, $params)) {
         return new TransformParameterError($params);
     }
     $clientWidth = $params['width'];
     $clientHeight = $params['height'];
     $physicalWidth = $params['physicalWidth'];
     $physicalHeight = $params['physicalHeight'];
     $srcPath = $image->getPath();
     if ($flags & self::TRANSFORM_LATER) {
         return new ThumbnailImage($image, $dstUrl, $clientWidth, $clientHeight, $dstPath);
     }
     if (!wfMkdirParents(dirname($dstPath), null, __METHOD__)) {
         return new MediaTransformError('thumbnail_error', $clientWidth, $clientHeight, wfMsg('thumbnail_dest_directory'));
     }
     $err = false;
     if (isset($wgFLVConverters[$wgFLVConverter])) {
         $cmd = str_replace(array('$path/', '$width', '$height', '$input', '$output'), array($wgFLVConverterPath ? wfEscapeShellArg("{$wgFLVConverterPath}/") : "", intval($physicalWidth), intval($physicalHeight), wfEscapeShellArg($srcPath), wfEscapeShellArg($dstPath)), $wgFLVConverters[$wgFLVConverter]) . " 2>&1";
         wfProfileIn('rsvg');
         wfDebug(__METHOD__ . ": {$cmd}\n");
         $err = wfShellExec($cmd, $retval);
         wfProfileOut('rsvg');
     }
     $removed = $this->removeBadFile($dstPath, $retval);
     if ($retval != 0 || $removed) {
         wfDebugLog('thumbnail', sprintf('thumbnail failed on %s: error %d "%s" from "%s"', wfHostname(), $retval, trim($err), $cmd));
         return new MediaTransformError('thumbnail_error', $clientWidth, $clientHeight, $err);
     } else {
         return new ThumbnailImage($image, $dstUrl, $clientWidth, $clientHeight, $dstPath);
     }
 }
Example #4
0
 private static function dataDirOKmaybeCreate($dir, $create = false)
 {
     if (!is_dir($dir)) {
         if (!is_writable(dirname($dir))) {
             $webserverGroup = Installer::maybeGetWebserverPrimaryGroup();
             if ($webserverGroup !== null) {
                 return Status::newFatal('config-sqlite-parent-unwritable-group', $dir, dirname($dir), basename($dir), $webserverGroup);
             } else {
                 return Status::newFatal('config-sqlite-parent-unwritable-nogroup', $dir, dirname($dir), basename($dir));
             }
         }
         # Called early on in the installer, later we just want to sanity check
         # if it's still writable
         if ($create) {
             wfSuppressWarnings();
             $ok = wfMkdirParents($dir, 0700);
             wfRestoreWarnings();
             if (!$ok) {
                 return Status::newFatal('config-sqlite-mkdir-error', $dir);
             }
             # Put a .htaccess file in in case the user didn't take our advice
             file_put_contents("{$dir}/.htaccess", "Deny from all\n");
         }
     }
     if (!is_writable($dir)) {
         return Status::newFatal('config-sqlite-dir-unwritable', $dir);
     }
     # We haven't blown up yet, fall through
     return Status::newGood();
 }
 function run()
 {
     global $wgExtensionMessagesFiles, $wgMessageCache, $IP;
     $nameHash = md5(implode("\n", array_keys($wgExtensionMessagesFiles)));
     $dir = "{$IP}/cache/ext-msgs";
     wfMkdirParents($dir);
     $db = dba_open("{$dir}/{$nameHash}.cdb", 'n', 'cdb');
     if (!$db) {
         echo "Cannot open DB file\n";
         exit(1);
     }
     # Load extension messages
     foreach ($wgExtensionMessagesFiles as $file) {
         $messages = $magicWords = array();
         require $file;
         foreach ($messages as $lang => $unused) {
             $wgMessageCache->processMessagesArray($messages, $lang);
         }
     }
     # Write them to the file
     foreach ($wgMessageCache->mExtensionMessages as $lang => $messages) {
         foreach ($messages as $key => $text) {
             dba_insert("{$lang}:{$key}", $text, $db);
         }
     }
     dba_close($db);
 }
Example #6
0
	function execute() {
		global $wgRequest;

		if ( !$wgRequest->wasPosted() ) {
			echo $this->dtd();
			echo <<<EOT
<html>
<head><title>store.php Test Interface</title></head>
<body>
<form method="post" action="store.php" enctype="multipart/form-data" >
<p>File: <input type="file" name="file"/></p>
<p><input type="submit" value="OK"/></p>
</form></body></html>
EOT;
			return true;
		}

		$srcFile = $wgRequest->getFileTempname( 'file' );
		if ( !$srcFile ) {
			$this->error( 400, 'webstore_no_file' );
			return false;
		}

		// Use an hourly timestamped directory for easy cleanup
		$now = time();
		$this->cleanupTemp( $now );

		$timestamp = gmdate( self::$tempDirFormat, $now );
		if ( !wfMkdirParents( "{$this->tmpDir}/$timestamp", null, __METHOD__ ) ) {
			$this->error( 500, 'webstore_dest_mkdir' );
			return false;
		}

		// Get the extension of the upload, needs to be preserved for type detection
		$name = $wgRequest->getFileName( 'file' );
		$n = strrpos( $name, '.' );
		if ( $n ) {
			$extension = '.' . File::normalizeExtension( substr( $name, $n + 1 ) );
		} else {
			$extension = '';
		}

		// Pick a random temporary path
		$destRel =  $timestamp . '/' . md5( mt_rand() . mt_rand() . mt_rand() ) . $extension;
		if ( !@move_uploaded_file( $srcFile, "{$this->tmpDir}/$destRel" ) ) {
			$this->error( 400, 'webstore_move_uploaded', $srcFile, "{$this->tmpDir}/$destRel" );
			return false;
		}

		// Succeeded, return temporary location
		header( 'Content-Type: text/xml' );
		echo <<<EOT
<?xml version="1.0" encoding="utf-8"?>
<response>
<location>$destRel</location>
</response>
EOT;
		return true;
	}
 public function execute()
 {
     global $wgCaptchaSecret, $wgCaptchaDirectoryLevels;
     $instance = ConfirmEditHooks::getInstance();
     if (!$instance instanceof FancyCaptcha) {
         $this->error("\$wgCaptchaClass is not FancyCaptcha.\n", 1);
     }
     $backend = $instance->getBackend();
     $countAct = $instance->estimateCaptchaCount();
     $this->output("Estimated number of captchas is {$countAct}.\n");
     $countGen = (int) $this->getOption('fill') - $countAct;
     if ($countGen <= 0) {
         $this->output("No need to generate anymore captchas.\n");
         return;
     }
     $tmpDir = wfTempDir() . '/mw-fancycaptcha-' . time() . '-' . wfRandomString(6);
     if (!wfMkdirParents($tmpDir)) {
         $this->error("Could not create temp directory.\n", 1);
     }
     $e = null;
     // exception
     try {
         $cmd = sprintf("python %s --key %s --output %s --count %s --dirs %s", wfEscapeShellArg(__DIR__ . '/../captcha.py'), wfEscapeShellArg($wgCaptchaSecret), wfEscapeShellArg($tmpDir), wfEscapeShellArg($countGen), wfEscapeShellArg($wgCaptchaDirectoryLevels));
         foreach (array('wordlist', 'font', 'font-size', 'blacklist', 'verbose') as $par) {
             if ($this->hasOption($par)) {
                 $cmd .= " --{$par} " . wfEscapeShellArg($this->getOption($par));
             }
         }
         $this->output("Generating {$countGen} new captchas...\n");
         $retVal = 1;
         wfShellExec($cmd, $retVal, array(), array('time' => 0));
         if ($retVal != 0) {
             wfRecursiveRemoveDir($tmpDir);
             $this->error("Could not run generation script.\n", 1);
         }
         $flags = FilesystemIterator::SKIP_DOTS;
         $iter = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($tmpDir, $flags), RecursiveIteratorIterator::CHILD_FIRST);
         $this->output("Copying the new captchas to storage...\n");
         foreach ($iter as $fileInfo) {
             if (!$fileInfo->isFile()) {
                 continue;
             }
             list($salt, $hash) = $instance->hashFromImageName($fileInfo->getBasename());
             $dest = $instance->imagePath($salt, $hash);
             $backend->prepare(array('dir' => dirname($dest)));
             $status = $backend->quickStore(array('src' => $fileInfo->getPathname(), 'dst' => $dest));
             if (!$status->isOK()) {
                 $this->error("Could not save file '{$fileInfo->getPathname()}'.\n");
             }
         }
     } catch (Exception $e) {
         wfRecursiveRemoveDir($tmpDir);
         throw $e;
     }
     $this->output("Removing temporary files...\n");
     wfRecursiveRemoveDir($tmpDir);
     $this->output("Done.\n");
 }
Example #8
0
 /**
  * Run PHP Storm's Code Inspect for a given directory
  *
  * Actually, PHP storm will be run for a given directory.
  * XML reports will then be parsed to get issues for given file.
  *
  * @param string $dirName file to run Code Inspect for
  * @return string output from Code Inspect
  * @throws Exception
  */
 protected function inspectDirectory($dirName)
 {
     global $wgPHPStormPath, $IP;
     $start = microtime(true);
     $dirName = realpath($dirName);
     $isCached = $this->cache['directory'] !== '' && strpos($dirName, $this->cache['directory']) === 0;
     if (!$isCached) {
         $lintProfile = dirname(__FILE__) . '/php/profiles/phplint.xml';
         $projectMetaData = dirname(__FILE__) . '/php/project';
         // copy project meta data to trunk root
         $copyCmd = "cp -rf {$projectMetaData}/.idea {$IP}";
         echo "Copying project meta data <{$copyCmd}>...";
         exec($copyCmd);
         echo " [done]\n";
         // create a temporary directory for Code Inspect results
         $resultsDir = wfTempDir() . '/phpstorm/' . uniqid('lint');
         echo "Creating temporary directory for results <{$resultsDir}>...";
         if (wfMkdirParents($resultsDir)) {
             echo " [done]\n";
         } else {
             echo " [err!]\n";
         }
         $cmd = sprintf('/bin/sh %s/inspect.sh %s %s %s -d %s -v2', $wgPHPStormPath, realpath($IP . '/includes/..'), $lintProfile, $resultsDir, $dirName);
         echo "Running PHP storm <{$cmd}>...";
         #echo "Running PhpStorm for <{$dirName}>...";
         $retVal = 0;
         $output = array();
         exec($cmd, $output, $retVal);
         if ($retVal !== 0) {
             throw new Exception("{$cmd} ended with code #{$retVal}");
         }
         // get the version of PhpStorm
         $tool = '';
         foreach ($output as $line) {
             if (strpos($line, 'Starting up JetBrains PhpStorm') !== false) {
                 preg_match('#JetBrains PhpStorm [\\d\\.]+#', $line, $matches);
                 $tool = $matches[0];
             }
         }
         echo implode("\n", $output);
         // debug
         echo " [done]\n";
         // format results
         $output = array('problems' => $this->parseResults($resultsDir), 'tool' => $tool);
         // update the cache
         $this->cache = array('directory' => $dirName, 'output' => $output);
     } else {
         //echo "Got results from cache for <{$this->cache['directory']}>\n";
         $output = $this->cache['output'];
     }
     $output['time'] = round(microtime(true) - $start, 4);
     return $output;
 }
	static function get( $options ){
		global $wgFFmpegLocation, $wgOggThumbLocation;

		// Set up lodal pointer to file
		$file = $options['file'];
		if( !is_dir( dirname( $options['dstPath'] ) ) ){
			wfMkdirParents( dirname( $options['dstPath'] ), null, __METHOD__ );
		}

		wfDebug( "Creating video thumbnail at" .  $options['dstPath']  . "\n" );
		// Else try ffmpeg and return result:
		return self::tryFfmpegThumb( $options );
	}
 private function generate()
 {
     if (preg_match('/^\\s*(\\w+)\\s*{/', $this->source, $matches)) {
         $diagram_type = $matches[1];
     } else {
         $diagram_type = 'blockdiag';
         // blockdiag for default
     }
     $diagprog_path = $this->path_array[$diagram_type];
     if (!is_file($diagprog_path)) {
         return $this->error("{$diagram_type} is not found at the specified place.");
     }
     // temporary directory check
     if (!file_exists($this->tmpDir)) {
         if (!wfMkdirParents($this->tmpDir)) {
             return $this->error('temporary directory is not found.');
         }
     } elseif (!is_dir($this->tmpDir)) {
         return $this->error('temporary directory is not directory');
     } elseif (!is_writable($this->tmpDir)) {
         return $this->error('temporary directory is not writable');
     }
     // create temporary file
     $dstTmpName = tempnam($this->tmpDir, 'blockdiag');
     $srcTmpName = tempnam($this->tmpDir, 'blockdiag');
     // write blockdiag source
     $fp = fopen($srcTmpName, 'w');
     fwrite($fp, $this->source);
     fclose($fp);
     // generate blockdiag image
     $cmd = $diagprog_path . ' -T ' . escapeshellarg($this->imgType) . ' -o ' . escapeshellarg($dstTmpName) . ' ' . escapeshellarg($srcTmpName);
     $res = `{$cmd}`;
     if (filesize($dstTmpName) == 0) {
         return $this->error('unknown error.');
     }
     // move to image directory
     $hashpath = $this->getHashPath();
     if (!file_exists($hashpath)) {
         if (!@wfMkdirParents($hashpath, 0755)) {
             return $this->error('can not make blockdiag image directory', $this->blockdiagDir);
         }
     } elseif (!is_dir($hashpath)) {
         return $this->error('blockdiag image directory is already exists. but not directory');
     } elseif (!is_writable($hashpath)) {
         return $this->error('blockdiag image directory is not writable');
     }
     if (!rename("{$dstTmpName}", "{$hashpath}/{$this->hash}.png")) {
         return $this->error('can not rename blockdiag image');
     }
     return $this->mkImageTag();
 }
Example #11
0
 /**
  * Constructor
  */
 function __construct($server = false, $user = false, $password = false, $dbName = false, $failFunction = false, $flags = 0)
 {
     global $wgOut, $wgSQLiteDataDir, $wgSQLiteDataDirMode;
     if ("{$wgSQLiteDataDir}" == '') {
         $wgSQLiteDataDir = dirname($_SERVER['DOCUMENT_ROOT']) . '/data';
     }
     if (!is_dir($wgSQLiteDataDir)) {
         wfMkdirParents($wgSQLiteDataDir, $wgSQLiteDataDirMode);
     }
     $this->mFailFunction = $failFunction;
     $this->mFlags = $flags;
     $this->mDatabaseFile = "{$wgSQLiteDataDir}/{$dbName}.sqlite";
     $this->open($server, $user, $password, $dbName);
 }
Example #12
0
 public function startWrite($code)
 {
     if (!file_exists($this->directory)) {
         if (!wfMkdirParents($this->directory, null, __METHOD__)) {
             throw new MWException("Unable to create the localisation store " . "directory \"{$this->directory}\"");
         }
     }
     // Close reader to stop permission errors on write
     if (!empty($this->readers[$code])) {
         $this->readers[$code]->close();
     }
     try {
         $this->writer = Writer::open($this->getFileName($code));
     } catch (Exception $e) {
         throw new MWException($e->getMessage());
     }
     $this->currentLang = $code;
 }
Example #13
0
 function doTransform($image, $dstPath, $dstUrl, $params, $flags = 0)
 {
     global $wgDjvuRenderer, $wgDjvuPostProcessor;
     // Fetch XML and check it, to give a more informative error message than the one which
     // normaliseParams will inevitably give.
     $xml = $image->getMetadata();
     if (!$xml) {
         return new MediaTransformError('thumbnail_error', @$params['width'], @$params['height'], wfMsg('djvu_no_xml'));
     }
     if (!$this->normaliseParams($image, $params)) {
         return new TransformParameterError($params);
     }
     $width = $params['width'];
     $height = $params['height'];
     $srcPath = $image->getPath();
     $page = $params['page'];
     if ($page > $this->pageCount($image)) {
         return new MediaTransformError('thumbnail_error', $width, $height, wfMsg('djvu_page_error'));
     }
     if ($flags & self::TRANSFORM_LATER) {
         return new ThumbnailImage($image, $dstUrl, $width, $height, $dstPath, $page);
     }
     if (!wfMkdirParents(dirname($dstPath))) {
         return new MediaTransformError('thumbnail_error', $width, $height, wfMsg('thumbnail_dest_directory'));
     }
     # Use a subshell (brackets) to aggregate stderr from both pipeline commands
     # before redirecting it to the overall stdout. This works in both Linux and Windows XP.
     $cmd = '(' . wfEscapeShellArg($wgDjvuRenderer) . " -format=ppm -page={$page} -size={$width}x{$height} " . wfEscapeShellArg($srcPath);
     if ($wgDjvuPostProcessor) {
         $cmd .= " | {$wgDjvuPostProcessor}";
     }
     $cmd .= ' > ' . wfEscapeShellArg($dstPath) . ') 2>&1';
     wfProfileIn('ddjvu');
     wfDebug(__METHOD__ . ": {$cmd}\n");
     $err = wfShellExec($cmd, $retval);
     wfProfileOut('ddjvu');
     $removed = $this->removeBadFile($dstPath, $retval);
     if ($retval != 0 || $removed) {
         wfDebugLog('thumbnail', sprintf('thumbnail failed on %s: error %d "%s" from "%s"', wfHostname(), $retval, trim($err), $cmd));
         return new MediaTransformError('thumbnail_error', $width, $height, $err);
     } else {
         return new ThumbnailImage($image, $dstUrl, $width, $height, $dstPath, $page);
     }
 }
function doJobLoop(){
	global $wgJobTypeConfig, $wahJobDelay, $wahRunOnce, $wahStatusOutput;

	//look for jobs (sleep for $wahJobDelay if none found)
	$job = WahJobManager :: getNewJob(false, 'Internal');
	if(!$job && $wahRunOnce == false){
		if($wahStatusOutput)
			print "no jobs found waiting $wahJobDelay \n";
		sleep($wahJobDelay);
		return doJobLoop();
	}elseif(!$job  && $wahRunOnce == true){
		if($wahStatusOutput)
			print "no job found \n";
		return ;
	}

	$jobSet = WahJobManager ::getJobSetById( $job->job_set_id );
	$jobDetails = FormatJson::decode( $job->job_json ) ;

	//get the title (so we can access the source file)
	$fTitle = Title::newFromText( $job->title, $job->ns );
	$file = wfLocalFile( $fTitle );
	$thumbPath = $file->getThumbPath( $jobSet->set_encodekey );
	//make sure the directory is ready:
	wfMkdirParents( $thumbPath, null, __METHOD__ );

	$destTarget = $thumbPath . '.ogg';
	//issue the encoding command
	if($wahStatusOutput) print "Running Encode Command...\n";
	wahDoEncode($file->getPath(), $destTarget, $jobDetails->encodeSettings );

	//once done with encode update the status:
	WahJobManager :: updateJobDone($job);
	//update set done (if only one item in the set)
	$wjm = WahJobManager::newFromSet( $jobSet );
	$percDone = $wjm->getDonePerc();
	if( $percDone == 1 ){
		WahJobManager :: updateSetDone( $jobSet );
	}else{
		if($wahStatusOutput)
			print "job not complete? (might be mixing chunkDuration types?) ";
	}
}
Example #15
0
 /**
  * checkImageDirectory
  *
  * check if target directory exists. if not create it. if not possible
  * signalize it. We have to have id of target wiki
  *
  * @access public
  * @author eloy@wikia
  *
  * @return boolean: status of operation
  */
 public function checkImageDirectory()
 {
     $mRetVal = false;
     if (empty($this->mTargetID)) {
         return $mRetVal;
     }
     wfProfileIn(__METHOD__);
     $UploadDirectory = WikiFactory::getVarValueByName("wgUploadDirectory", $this->mTargetID);
     if (file_exists($UploadDirectory)) {
         if (is_dir($UploadDirectory)) {
             $this->addLog("Target {$UploadDirectory} exists and is directory.");
             $mRetVal = true;
         } else {
             $this->addLog("Target {$UploadDirectory} exists but is not directory");
             $mRetVal = false;
         }
     } else {
         $mRetVal = wfMkdirParents($UploadDirectory);
     }
     wfProfileOut(__METHOD__);
     return $mRetVal;
 }
Example #16
0
 /**
  * main entry point, create wiki with given parameters
  *
  * @throw CreateWikiException an exception with status of operation set
  */
 public function create()
 {
     global $wgExternalSharedDB, $wgSharedDB, $wgUser;
     $then = microtime(true);
     // Set this flag to ensure that all select operations go against master
     // Slave lag can cause random errors during wiki creation process
     global $wgForceMasterDatabase;
     $wgForceMasterDatabase = true;
     wfProfileIn(__METHOD__);
     if (wfReadOnly()) {
         wfProfileOut(__METHOD__);
         throw new CreateWikiException('DB is read only', self::ERROR_READONLY);
     }
     // check founder
     if ($this->mFounder->isAnon()) {
         wfProfileOut(__METHOD__);
         throw new CreateWikiException('Founder is anon', self::ERROR_USER_IN_ANON);
     }
     // check executables
     $status = $this->checkExecutables();
     if ($status != 0) {
         wfProfileOut(__METHOD__);
         throw new CreateWikiException('checkExecutables() failed', $status);
     }
     // check domains
     $status = $this->checkDomain();
     if ($status != 0) {
         wfProfileOut(__METHOD__);
         throw new CreateWikiException('Check domain failed', $status);
     }
     // prepare all values needed for creating wiki
     $this->prepareValues();
     // prevent domain to be registered more than once
     if (!AutoCreateWiki::lockDomain($this->mDomain)) {
         wfProfileOut(__METHOD__);
         throw new CreateWikiException('Domain name taken', self::ERROR_DOMAIN_NAME_TAKEN);
     }
     // start counting time
     $this->mCurrTime = wfTime();
     // check and create database
     $this->mDBw = wfGetDB(DB_MASTER, array(), $wgExternalSharedDB);
     # central
     ///
     // local database handled is handler to cluster we create new wiki.
     // It doesn't have to be the same like wikifactory cluster or db cluster
     // where Special:CreateWiki exists.
     //
     // @todo do not use hardcoded name, code below is only for test
     //
     // set $activeCluster to false if you want to create wikis on first
     // cluster
     //
     $this->mClusterDB = self::ACTIVE_CLUSTER ? "wikicities_" . self::ACTIVE_CLUSTER : "wikicities";
     $this->mNewWiki->dbw = wfGetDB(DB_MASTER, array(), $this->mClusterDB);
     // database handler, old $dbwTarget
     // check if database is creatable
     // @todo move all database creation checkers to canCreateDatabase
     if (!$this->canCreateDatabase()) {
         wfProfileOut(__METHOD__);
         throw new CreateWikiException('DB exists - ' . $this->mNewWiki->dbname, self::ERROR_DATABASE_ALREADY_EXISTS);
     } else {
         $this->mNewWiki->dbw->query(sprintf("CREATE DATABASE `%s`", $this->mNewWiki->dbname));
         wfDebugLog("createwiki", "Database {$this->mNewWiki->dbname} created\n", true);
     }
     /**
      * create position in wiki.factory
      * (I like sprintf construction, so sue me)
      */
     if (!$this->addToCityList()) {
         wfDebugLog("createwiki", __METHOD__ . ": Cannot set data in city_list table\n", true);
         wfProfileOut(__METHOD__);
         throw new CreateWikiException('Cannot add wiki to city_list', self::ERROR_DATABASE_WRITE_TO_CITY_LIST_BROKEN);
     }
     // set new city_id
     $this->mNewWiki->city_id = $this->mDBw->insertId();
     if (empty($this->mNewWiki->city_id)) {
         wfProfileOut(__METHOD__);
         throw new CreateWikiException('Cannot set data in city_list table. city_id is empty after insert', self::ERROR_DATABASE_WIKI_FACTORY_TABLES_BROKEN);
     }
     wfDebugLog("createwiki", __METHOD__ . ": Row added added into city_list table, city_id = {$this->mNewWiki->city_id}\n", true);
     /**
      * add domain and www.domain to the city_domains table
      */
     if (!$this->addToCityDomains()) {
         wfProfileOut(__METHOD__);
         throw new CreateWikiException('Cannot set data in city_domains table', self::ERROR_DATABASE_WRITE_TO_CITY_DOMAINS_BROKEN);
     }
     wfDebugLog("createwiki", __METHOD__ . ": Row added into city_domains table, city_id = {$this->mNewWiki->city_id}\n", true);
     /**
      * create image folder
      */
     global $wgEnableSwiftFileBackend;
     if (empty($wgEnableSwiftFileBackend)) {
         wfMkdirParents("{$this->mNewWiki->images_dir}");
         wfDebugLog("createwiki", __METHOD__ . ": Folder {$this->mNewWiki->images_dir} created\n", true);
     }
     // Force initialize uploader user from correct shared db
     $uploader = User::newFromName('CreateWiki script');
     $uploader->getId();
     $oldUser = $wgUser;
     $wgUser = $uploader;
     /**
      * wikifactory variables
      */
     wfDebugLog("createwiki", __METHOD__ . ": Populating city_variables\n", true);
     $this->setWFVariables();
     $tmpSharedDB = $wgSharedDB;
     $wgSharedDB = $this->mNewWiki->dbname;
     $this->mDBw->commit(__METHOD__);
     // commit shared DB changes
     /**
      * we got empty database created, now we have to create tables and
      * populate it with some default values
      */
     wfDebugLog("createwiki", __METHOD__ . ": Creating tables in database\n", true);
     $this->mNewWiki->dbw = wfGetDB(DB_MASTER, array(), $this->mNewWiki->dbname);
     if (!$this->createTables()) {
         wfProfileOut(__METHOD__);
         throw new CreateWikiException('Creating tables not finished', self::ERROR_SQL_FILE_BROKEN);
     }
     /**
      * import language starter
      */
     if (!$this->importStarter()) {
         wfProfileOut(__METHOD__);
         throw new CreateWikiException('Starter import failed', self::ERROR_SQL_FILE_BROKEN);
     }
     /**
      * making the wiki founder a sysop/bureaucrat
      */
     wfDebugLog("createwiki", __METHOD__ . ": Create user sysop/bureaucrat for user: {$this->mNewWiki->founderId} \n", true);
     if (!$this->addUserToGroups()) {
         wfDebugLog("createwiki", __METHOD__ . ": Create user sysop/bureaucrat for user: {$this->mNewWiki->founderId} failed \n", true);
     }
     /**
      * init site_stats table (add empty row)
      */
     $this->mNewWiki->dbw->insert("site_stats", array("ss_row_id" => "1"), __METHOD__);
     /**
      * copy default logo
      */
     $res = ImagesService::uploadImageFromUrl(self::CREATEWIKI_LOGO, (object) ['name' => 'Wiki.png'], $uploader);
     if ($res['status'] === true) {
         wfDebugLog("createwiki", __METHOD__ . ": Default logo has been uploaded\n", true);
     } else {
         wfDebugLog("createwiki", __METHOD__ . ": Default logo has not been uploaded - " . print_r($res['errors'], true) . "\n", true);
     }
     /**
      * destroy connection to newly created database
      */
     $this->waitForSlaves(__METHOD__);
     $wgSharedDB = $tmpSharedDB;
     $oHub = WikiFactoryHub::getInstance();
     $oHub->setVertical($this->mNewWiki->city_id, $this->mNewWiki->vertical, "CW Setup");
     wfDebugLog("createwiki", __METHOD__ . ": Wiki added to the vertical: {$this->mNewWiki->vertical} \n", true);
     for ($i = 0; $i < count($this->mNewWiki->categories); $i++) {
         $oHub->addCategory($this->mNewWiki->city_id, $this->mNewWiki->categories[$i]);
         wfDebugLog("createwiki", __METHOD__ . ": Wiki added to the category: {$this->mNewWiki->categories[$i]} \n", true);
     }
     /**
      * define wiki type
      */
     $wiki_type = 'default';
     /**
      * modify variables
      */
     global $wgUniversalCreationVariables;
     if (!empty($wgUniversalCreationVariables) && !empty($wiki_type) && isset($wgUniversalCreationVariables[$wiki_type])) {
         $this->addCustomSettings(0, $wgUniversalCreationVariables[$wiki_type], "universal");
         wfDebugLog("createwiki", __METHOD__ . ": Custom settings added for wiki_type: {$wiki_type} \n", true);
     }
     /**
      * set variables per language
      */
     global $wgLangCreationVariables;
     $langCreationVar = isset($wgLangCreationVariables[$wiki_type]) ? $wgLangCreationVariables[$wiki_type] : $wgLangCreationVariables;
     $this->addCustomSettings($this->mNewWiki->language, $langCreationVar, "language");
     wfDebugLog("createwiki", __METHOD__ . ": Custom settings added for wiki_type: {$wiki_type} and language: {$this->mNewWiki->language} \n", true);
     /**
      * set tags per language and per hub
      * @FIXME the switch is !@#$ creazy, but I didn't find a core function
      */
     $tags = new WikiFactoryTags($this->mNewWiki->city_id);
     $langTag = $this->mNewWiki->language;
     if ($langTag !== 'en') {
         switch ($langTag) {
             case 'pt-br':
                 $langTag = 'pt';
                 break;
             case 'zh-tw':
             case 'zh-hk':
             case 'zh-clas':
             case 'zh-class':
             case 'zh-classical':
             case 'zh-cn':
             case 'zh-hans':
             case 'zh-hant':
             case 'zh-min-':
             case 'zh-min-n':
             case 'zh-mo':
             case 'zh-sg':
             case 'zh-yue':
                 $langTag = 'zh';
                 break;
         }
         $tags->addTagsByName($langTag);
     }
     /**
      * move main page -> this code exists in CreateWikiLocalJob - so it is not needed anymore
      */
     /**
      * Unset database from mNewWiki, because database objects cannot be serialized from MW1.19
      */
     unset($this->mNewWiki->dbw);
     // Restore wgUser
     $wgUser = $oldUser;
     unset($oldUser);
     /**
      * Schedule an async task
      */
     $creationTask = new \Wikia\Tasks\Tasks\CreateNewWikiTask();
     $job_params = new stdClass();
     foreach ($this->mNewWiki as $id => $value) {
         if (!is_object($value)) {
             $job_params->{$id} = $value;
         }
     }
     // BugId:15644 - I need to pass this to CreateWikiLocalJob::changeStarterContributions
     $job_params->sDbStarter = $this->sDbStarter;
     $task_id = (new \Wikia\Tasks\AsyncTaskList())->wikiId($this->mNewWiki->city_id)->prioritize()->add($creationTask->call('postCreationSetup', $job_params))->add($creationTask->call('maintenance', rtrim($this->mNewWiki->url, "/")))->queue();
     wfDebugLog("createwiki", __METHOD__ . ": Local maintenance task added as {$task_id}\n", true);
     $this->info(__METHOD__ . ': done', ['task_id' => $task_id, 'took' => microtime(true) - $then]);
     wfProfileOut(__METHOD__);
 }
Example #17
0
 protected function checkCacheDirs()
 {
     $filename = $this->fileCacheName();
     $mydir2 = substr($filename, 0, strrpos($filename, '/'));
     # subdirectory level 2
     $mydir1 = substr($mydir2, 0, strrpos($mydir2, '/'));
     # subdirectory level 1
     wfMkdirParents($mydir1);
     wfMkdirParents($mydir2);
 }
Example #18
0
/**
 * dump directory is created as
 *
 * <root>/<first letter>/<two first letters>/<database>
 */
function getDirectory($database, $hide = false)
{
    global $wgDevelEnvironment;
    $folder = empty($wgDevelEnvironment) ? "raid" : "tmp";
    $subfolder = $hide ? "dumps-hidden" : "dumps";
    $database = strtolower($database);
    $directory = sprintf("/%s/%s/%s/%s/%s", $folder, $subfolder, substr($database, 0, 1), substr($database, 0, 2), $database);
    if (!is_dir($directory)) {
        Wikia::log(__METHOD__, "dir", "create {$directory}", true, true);
        wfMkdirParents($directory);
    }
    return $directory;
}
 /** I BORROWED THIS FUNCTION FROM SpecialUpload.php!! CHECK FOR EACH VERSION OF MEDIAWIKI, IF
  *  THIS FUNCTION STILL MAKES SENSE!
  *
  * Move the uploaded file from its temporary location to the final
  * destination. If a previous version of the file exists, move
  * it into the archive subdirectory.
  *
  * @todo If the later save fails, we may have disappeared the original file.
  *
  * @param string $saveName
  * @param string $tempName full path to the temporary file
  * @param bool $useRename if true, doesn't check that the source file
  *                        is a PHP-managed upload temporary
  */
 function saveUploadedFile($saveName, $tempName, $useRename = false)
 {
     global $wgOut, $wgAllowCopyUploads;
     $fname = "SpecialUpload::saveUploadedFile";
     if (!$useRename && $wgAllowCopyUploads && $this->mSourceType == 'web') {
         $useRename = true;
     }
     $dest = wfImageDir($saveName);
     $archive = wfImageArchiveDir($saveName);
     if (!is_dir($dest)) {
         wfMkdirParents($dest);
     }
     if (!is_dir($archive)) {
         wfMkdirParents($archive);
     }
     $this->mSavedFile = "{$dest}/{$saveName}";
     if (is_file($this->mSavedFile)) {
         $this->mUploadOldVersion = gmdate('YmdHis') . "!{$saveName}";
         wfSuppressWarnings();
         $success = rename($this->mSavedFile, "{$archive}/{$this->mUploadOldVersion}");
         wfRestoreWarnings();
         if (!$success) {
             $wgOut->showFileRenameError($this->mSavedFile, "{$archive}/{$this->mUploadOldVersion}");
             return false;
         } else {
             wfDebug("{$fname}: moved file " . $this->mSavedFile . " to {$archive}/{$this->mUploadOldVersion}\n");
         }
     } else {
         $this->mUploadOldVersion = '';
     }
     wfSuppressWarnings();
     $success = $useRename ? rename($tempName, $this->mSavedFile) : move_uploaded_file($tempName, $this->mSavedFile);
     wfRestoreWarnings();
     if (!$success) {
         $wgOut->showFileCopyError($tempName, $this->mSavedFile);
         return false;
     } else {
         wfDebug("{$fname}: wrote tempfile {$tempName} to " . $this->mSavedFile . "\n");
     }
     chmod($this->mSavedFile, 0644);
     return true;
 }
 /**
  * Sets up requires directories
  * @param DatabaseUpdater $updater Provided by MediaWikis update.php
  * @return boolean Always true to keep the hook running
  */
 public static function getSchemaUpdates($updater)
 {
     //TODO: Create abstraction in Core/Adapter
     $sTmpDir = BSDATADIR . DS . 'UEModulePDF';
     if (!file_exists($sTmpDir)) {
         echo 'Directory "' . $sTmpDir . '" not found. Creating.' . "\n";
         wfMkdirParents($sTmpDir);
     } else {
         echo 'Directory "' . $sTmpDir . '" found.' . "\n";
     }
     $sDefaultTemplateDir = BSDATADIR . DS . 'PDFTemplates';
     if (!file_exists($sDefaultTemplateDir)) {
         echo 'Default template directory "' . $sDefaultTemplateDir . '" not found. Copying.' . "\n";
         BsFileSystemHelper::copyRecursive(__DIR__ . DS . 'data' . DS . 'PDFTemplates', $sDefaultTemplateDir);
     }
     return true;
 }
Example #21
0
 function revert()
 {
     global $wgOut, $wgRequest, $wgUser;
     $oldimage = $wgRequest->getText('oldimage');
     if (strlen($oldimage) < 16) {
         $wgOut->showUnexpectedValueError('oldimage', htmlspecialchars($oldimage));
         return;
     }
     if (strstr($oldimage, "/") || strstr($oldimage, "\\")) {
         $wgOut->showUnexpectedValueError('oldimage', htmlspecialchars($oldimage));
         return;
     }
     if (wfReadOnly()) {
         $wgOut->readOnlyPage();
         return;
     }
     if ($wgUser->isAnon()) {
         $wgOut->showErrorPage('uploadnologin', 'uploadnologintext');
         return;
     }
     if (!$this->mTitle->userCanEdit()) {
         $wgOut->sysopRequired();
         return;
     }
     if ($wgUser->isBlocked()) {
         return $this->blockedIPpage();
     }
     if (!$wgUser->matchEditToken($wgRequest->getVal('wpEditToken'), $oldimage)) {
         $wgOut->showErrorPage('internalerror', 'sessionfailure');
         return;
     }
     $name = substr($oldimage, 15);
     $dest = wfImageDir($name);
     $archive = wfImageArchiveDir($name);
     $curfile = "{$dest}/{$name}";
     if (!is_dir($dest)) {
         wfMkdirParents($dest);
     }
     if (!is_dir($archive)) {
         wfMkdirParents($archive);
     }
     if (!is_file($curfile)) {
         $wgOut->showFileNotFoundError(htmlspecialchars($curfile));
         return;
     }
     $oldver = wfTimestampNow() . "!{$name}";
     $dbr =& wfGetDB(DB_SLAVE);
     $size = $dbr->selectField('oldimage', 'oi_size', array('oi_archive_name' => $oldimage));
     if (!rename($curfile, "{$archive}/{$oldver}")) {
         $wgOut->showFileRenameError($curfile, "{$archive}/{$oldver}");
         return;
     }
     if (!copy("{$archive}/{$oldimage}", $curfile)) {
         $wgOut->showFileCopyError("{$archive}/{$oldimage}", $curfile);
         return;
     }
     # Record upload and update metadata cache
     $img = Image::newFromName($name);
     $img->recordUpload($oldver, wfMsg("reverted"));
     $wgOut->setPagetitle(wfMsg('actioncomplete'));
     $wgOut->setRobotpolicy('noindex,nofollow');
     $wgOut->addHTML(wfMsg('imagereverted'));
     $descTitle = $img->getTitle();
     $wgOut->returnToMain(false, $descTitle->getPrefixedText());
 }
Example #22
0
 /**
  * @covers ::wfMkdirParents
  */
 public function testWfMkdirParents()
 {
     // Should not return true if file exists instead of directory
     $fname = $this->getNewTempFile();
     MediaWiki\suppressWarnings();
     $ok = wfMkdirParents($fname);
     MediaWiki\restoreWarnings();
     $this->assertFalse($ok);
 }
Example #23
0
 /**
  * Moves an image from a safe private location
  * Caller is responsible for clearing caches
  * @param File $oimage
  * @returns mixed, string timestamp on success, false on failure
  */
 function makeOldImagePublic($oimage)
 {
     $transaction = new FSTransaction();
     if (!FileStore::lock()) {
         wfDebug(__METHOD__ . " could not acquire filestore lock\n");
         return false;
     }
     $store = FileStore::get('deleted');
     if (!$store) {
         wfDebug(__METHOD__ . ": skipping row with no file.\n");
         return false;
     }
     $key = $oimage->sha1 . '.' . $oimage->getExtension();
     $destDir = $oimage->getArchivePath();
     if (!is_dir($destDir)) {
         wfMkdirParents($destDir);
     }
     $destPath = $destDir . DIRECTORY_SEPARATOR . $oimage->archive_name;
     // Check if any other stored revisions use this file;
     // if so, we shouldn't remove the file from the hidden
     // archives so they will still work. Check hidden files first.
     $useCount = $this->dbw->selectField('oldimage', '1', array('oi_sha1' => $oimage->sha1, 'oi_deleted & ' . File::DELETED_FILE => File::DELETED_FILE), __METHOD__, array('FOR UPDATE'));
     // Check the rest of the deleted archives too.
     // (these are the ones that don't show in the image history)
     if (!$useCount) {
         $useCount = $this->dbw->selectField('filearchive', '1', array('fa_storage_group' => 'deleted', 'fa_storage_key' => $key), __METHOD__, array('FOR UPDATE'));
     }
     if ($useCount == 0) {
         wfDebug(__METHOD__ . ": nothing else using {$oimage->sha1}, will deleting after\n");
         $flags = FileStore::DELETE_ORIGINAL;
     } else {
         $flags = 0;
     }
     $transaction->add($store->export($key, $destPath, $flags));
     wfDebug(__METHOD__ . ": set db items, applying file transactions\n");
     $transaction->commit();
     FileStore::unlock();
     $m = explode('!', $oimage->archive_name, 2);
     $timestamp = $m[0];
     return $timestamp;
 }
Example #24
0
 /**
  * obtains a new temporary directory
  *
  * The obtained directory is enlisted to be removed (recursively with all its contained
  * files) upon tearDown.
  *
  * @since 1.20
  *
  * @return string Absolute name of the temporary directory
  */
 protected function getNewTempDirectory()
 {
     // Starting of with a temporary /file/.
     $fileName = $this->getNewTempFile();
     // Converting the temporary /file/ to a /directory/
     // The following is not atomic, but at least we now have a single place,
     // where temporary directory creation is bundled and can be improved
     unlink($fileName);
     $this->assertTrue(wfMkdirParents($fileName));
     return $fileName;
 }
Example #25
0
 /**
  * Stash a file in a temporary directory for later processing
  * after the user has confirmed it.
  *
  * If the user doesn't explicitly cancel or accept, these files
  * can accumulate in the temp directory.
  *
  * @param string $saveName - the destination filename
  * @param string $tempName - the source temporary file to save
  * @return string - full path the stashed file, or false on failure
  * @access private
  */
 function saveTempUploadedFile($saveName, $tempName)
 {
     global $wgOut;
     $archive = wfImageArchiveDir($saveName, 'temp');
     if (!is_dir($archive)) {
         wfMkdirParents($archive);
     }
     $stash = $archive . '/' . gmdate("YmdHis") . '!' . $saveName;
     $success = $this->mRemoveTempFile ? rename($tempName, $stash) : move_uploaded_file($tempName, $stash);
     if (!$success) {
         $wgOut->showFileCopyError($tempName, $stash);
         return false;
     }
     return $stash;
 }
     $dbc->setMode(DatabaseIbm_db2::INSTALL_MODE);
     $wgDatabase->setMode(DatabaseIbm_db2::INSTALL_MODE);
     if (!$wgDatabase->isOpen()) {
         print " error: " . htmlspecialchars($wgDatabase->lastError()) . "</li>\n";
     } else {
         $myver = $wgDatabase->getServerVersion();
     }
     if (is_callable(array($wgDatabase, 'initial_setup'))) {
         $wgDatabase->initial_setup('', $wgDBname);
     }
 } elseif ($conf->DBtype == 'sqlite') {
     $wgSQLiteDataDir = $conf->SQLiteDataDir;
     echo '<li>Attempting to connect to SQLite database at "' . htmlspecialchars($wgSQLiteDataDir) . '": ';
     if (!is_dir($wgSQLiteDataDir)) {
         if (is_writable(dirname($wgSQLiteDataDir))) {
             $ok = wfMkdirParents($wgSQLiteDataDir, $wgSQLiteDataDirMode);
         } else {
             $ok = false;
         }
         if (!$ok) {
             echo "cannot create data directory</li>";
             $errs['SQLiteDataDir'] = 'Enter a valid data directory';
             continue;
         }
     }
     if (!is_writable($wgSQLiteDataDir)) {
         echo "data directory not writable</li>";
         $errs['SQLiteDataDir'] = 'Enter a writable data directory';
         continue;
     }
     $dataFile = DatabaseSqlite::generateFileName($wgSQLiteDataDir, $wgDBname);
Example #27
0
 /**
  * Returns which scaler type should be used. Creates parent directories
  * for $dstPath and returns 'client' on error
  *
  * @return string client,im,custom,gd
  */
 protected static function getScalerType($dstPath, $checkDstPath = true)
 {
     global $wgUseImageResize, $wgUseImageMagick, $wgCustomConvertCommand;
     if (!$dstPath && $checkDstPath) {
         # No output path available, client side scaling only
         $scaler = 'client';
     } elseif (!$wgUseImageResize) {
         $scaler = 'client';
     } elseif ($wgUseImageMagick) {
         $scaler = 'im';
     } elseif ($wgCustomConvertCommand) {
         $scaler = 'custom';
     } elseif (function_exists('imagecreatetruecolor')) {
         $scaler = 'gd';
     } elseif (class_exists('Imagick')) {
         $scaler = 'imext';
     } else {
         $scaler = 'client';
     }
     if ($scaler != 'client' && $dstPath) {
         if (!wfMkdirParents(dirname($dstPath))) {
             # Unable to create a path for the thumbnail
             return 'client';
         }
     }
     return $scaler;
 }
Example #28
0
 function doTransform($image, $dstPath, $dstUrl, $params, $flags = 0)
 {
     global $wgUseImageMagick, $wgImageMagickConvertCommand, $wgImageMagickTempDir;
     global $wgCustomConvertCommand;
     global $wgSharpenParameter, $wgSharpenReductionThreshold;
     global $wgMaxAnimatedGifArea;
     if (!$this->normaliseParams($image, $params)) {
         return new TransformParameterError($params);
     }
     $physicalWidth = $params['physicalWidth'];
     $physicalHeight = $params['physicalHeight'];
     $clientWidth = $params['width'];
     $clientHeight = $params['height'];
     $srcWidth = $image->getWidth();
     $srcHeight = $image->getHeight();
     $mimeType = $image->getMimeType();
     $srcPath = $image->getPath();
     $retval = 0;
     wfDebug(__METHOD__ . ": creating {$physicalWidth}x{$physicalHeight} thumbnail at {$dstPath}\n");
     if (!$image->mustRender() && $physicalWidth == $srcWidth && $physicalHeight == $srcHeight) {
         # normaliseParams (or the user) wants us to return the unscaled image
         wfDebug(__METHOD__ . ": returning unscaled image\n");
         return new ThumbnailImage($image, $image->getURL(), $clientWidth, $clientHeight, $srcPath);
     }
     if (!$dstPath) {
         // No output path available, client side scaling only
         $scaler = 'client';
     } elseif ($wgUseImageMagick) {
         $scaler = 'im';
     } elseif ($wgCustomConvertCommand) {
         $scaler = 'custom';
     } elseif (function_exists('imagecreatetruecolor')) {
         $scaler = 'gd';
     } else {
         $scaler = 'client';
     }
     wfDebug(__METHOD__ . ": scaler {$scaler}\n");
     if ($scaler == 'client') {
         # Client-side image scaling, use the source URL
         # Using the destination URL in a TRANSFORM_LATER request would be incorrect
         return new ThumbnailImage($image, $image->getURL(), $clientWidth, $clientHeight, $srcPath);
     }
     if ($flags & self::TRANSFORM_LATER) {
         wfDebug(__METHOD__ . ": Transforming later per flags.\n");
         return new ThumbnailImage($image, $dstUrl, $clientWidth, $clientHeight, $dstPath);
     }
     if (!wfMkdirParents(dirname($dstPath))) {
         wfDebug(__METHOD__ . ": Unable to create thumbnail destination directory, falling back to client scaling\n");
         return new ThumbnailImage($image, $image->getURL(), $clientWidth, $clientHeight, $srcPath);
     }
     if ($scaler == 'im') {
         # use ImageMagick
         $quality = '';
         $sharpen = '';
         $frame = '';
         $animation = '';
         if ($mimeType == 'image/jpeg') {
             $quality = "-quality 80";
             // 80%
             # Sharpening, see bug 6193
             if (($physicalWidth + $physicalHeight) / ($srcWidth + $srcHeight) < $wgSharpenReductionThreshold) {
                 $sharpen = "-sharpen " . wfEscapeShellArg($wgSharpenParameter);
             }
         } elseif ($mimeType == 'image/png') {
             $quality = "-quality 95";
             // zlib 9, adaptive filtering
         } elseif ($mimeType == 'image/gif') {
             if ($srcWidth * $srcHeight > $wgMaxAnimatedGifArea) {
                 // Extract initial frame only; we're so big it'll
                 // be a total drag. :P
                 $frame = '[0]';
             } else {
                 // Coalesce is needed to scale animated GIFs properly (bug 1017).
                 $animation = ' -coalesce ';
             }
         }
         if (strval($wgImageMagickTempDir) !== '') {
             $tempEnv = 'MAGICK_TMPDIR=' . wfEscapeShellArg($wgImageMagickTempDir) . ' ';
         } else {
             $tempEnv = '';
         }
         # Specify white background color, will be used for transparent images
         # in Internet Explorer/Windows instead of default black.
         # Note, we specify "-size {$physicalWidth}" and NOT "-size {$physicalWidth}x{$physicalHeight}".
         # It seems that ImageMagick has a bug wherein it produces thumbnails of
         # the wrong size in the second case.
         $cmd = $tempEnv . wfEscapeShellArg($wgImageMagickConvertCommand) . " {$quality} -background white -size {$physicalWidth} " . wfEscapeShellArg($srcPath . $frame) . $animation . " -thumbnail " . wfEscapeShellArg("{$physicalWidth}x{$physicalHeight}!") . " -depth 8 {$sharpen} " . wfEscapeShellArg($dstPath) . " 2>&1";
         wfDebug(__METHOD__ . ": running ImageMagick: {$cmd}\n");
         wfProfileIn('convert');
         $err = wfShellExec($cmd, $retval);
         wfProfileOut('convert');
     } elseif ($scaler == 'custom') {
         # Use a custom convert command
         # Variables: %s %d %w %h
         $src = wfEscapeShellArg($srcPath);
         $dst = wfEscapeShellArg($dstPath);
         $cmd = $wgCustomConvertCommand;
         $cmd = str_replace('%s', $src, str_replace('%d', $dst, $cmd));
         # Filenames
         $cmd = str_replace('%h', $physicalHeight, str_replace('%w', $physicalWidth, $cmd));
         # Size
         wfDebug(__METHOD__ . ": Running custom convert command {$cmd}\n");
         wfProfileIn('convert');
         $err = wfShellExec($cmd, $retval);
         wfProfileOut('convert');
     } else {
         # Use PHP's builtin GD library functions.
         #
         # First find out what kind of file this is, and select the correct
         # input routine for this.
         $typemap = array('image/gif' => array('imagecreatefromgif', 'palette', 'imagegif'), 'image/jpeg' => array('imagecreatefromjpeg', 'truecolor', array(__CLASS__, 'imageJpegWrapper')), 'image/png' => array('imagecreatefrompng', 'bits', 'imagepng'), 'image/vnd.wap.wbmp' => array('imagecreatefromwbmp', 'palette', 'imagewbmp'), 'image/xbm' => array('imagecreatefromxbm', 'palette', 'imagexbm'));
         if (!isset($typemap[$mimeType])) {
             $err = 'Image type not supported';
             wfDebug("{$err}\n");
             return new MediaTransformError('thumbnail_error', $clientWidth, $clientHeight, $err);
         }
         list($loader, $colorStyle, $saveType) = $typemap[$mimeType];
         if (!function_exists($loader)) {
             $err = "Incomplete GD library configuration: missing function {$loader}";
             wfDebug("{$err}\n");
             return new MediaTransformError('thumbnail_error', $clientWidth, $clientHeight, $err);
         }
         $src_image = call_user_func($loader, $srcPath);
         $dst_image = imagecreatetruecolor($physicalWidth, $physicalHeight);
         // Initialise the destination image to transparent instead of
         // the default solid black, to support PNG and GIF transparency nicely
         $background = imagecolorallocate($dst_image, 0, 0, 0);
         imagecolortransparent($dst_image, $background);
         imagealphablending($dst_image, false);
         if ($colorStyle == 'palette') {
             // Don't resample for paletted GIF images.
             // It may just uglify them, and completely breaks transparency.
             imagecopyresized($dst_image, $src_image, 0, 0, 0, 0, $physicalWidth, $physicalHeight, imagesx($src_image), imagesy($src_image));
         } else {
             imagecopyresampled($dst_image, $src_image, 0, 0, 0, 0, $physicalWidth, $physicalHeight, imagesx($src_image), imagesy($src_image));
         }
         imagesavealpha($dst_image, true);
         call_user_func($saveType, $dst_image, $dstPath);
         imagedestroy($dst_image);
         imagedestroy($src_image);
         $retval = 0;
     }
     $removed = $this->removeBadFile($dstPath, $retval);
     if ($retval != 0 || $removed) {
         wfDebugLog('thumbnail', sprintf('thumbnail failed on %s: error %d "%s" from "%s"', wfHostname(), $retval, trim($err), $cmd));
         return new MediaTransformError('thumbnail_error', $clientWidth, $clientHeight, $err);
     } else {
         return new ThumbnailImage($image, $dstUrl, $clientWidth, $clientHeight, $dstPath);
     }
 }
Example #29
0
 /**
  * Return the imageurl from cache if possible
  *
  * If the url has been requested today, get it from cache
  * Otherwise retrieve remote thumb url, check for local file.
  *
  * @param $name String is a dbkey form of a title
  * @param $width
  * @param $height
  * @param String $param Other rendering parameters (page number, etc) from handler's makeParamString.
  */
 function getThumbUrlFromCache($name, $width, $height, $params = "")
 {
     global $wgMemc;
     if (!$this->canCacheThumbs()) {
         $result = null;
         // can't pass "null" by reference, but it's ok as default value
         return $this->getThumbUrl($name, $width, $height, $result, $params);
     }
     $key = $this->getLocalCacheKey('ForeignAPIRepo', 'ThumbUrl', $name);
     $sizekey = "{$width}:{$height}:{$params}";
     /* Get the array of urls that we already know */
     $knownThumbUrls = $wgMemc->get($key);
     if (!$knownThumbUrls) {
         /* No knownThumbUrls for this file */
         $knownThumbUrls = array();
     } else {
         if (isset($knownThumbUrls[$sizekey])) {
             wfDebug(__METHOD__ . ': Got thumburl from local cache: ' . "{$knownThumbUrls[$sizekey]} \n");
             return $knownThumbUrls[$sizekey];
         }
         /* This size is not yet known */
     }
     $metadata = null;
     $foreignUrl = $this->getThumbUrl($name, $width, $height, $metadata, $params);
     if (!$foreignUrl) {
         wfDebug(__METHOD__ . " Could not find thumburl\n");
         return false;
     }
     // We need the same filename as the remote one :)
     $fileName = rawurldecode(pathinfo($foreignUrl, PATHINFO_BASENAME));
     if (!$this->validateFilename($fileName)) {
         wfDebug(__METHOD__ . " The deduced filename {$fileName} is not safe\n");
         return false;
     }
     $localPath = $this->getZonePath('thumb') . "/" . $this->getHashPath($name) . $name;
     $localFilename = $localPath . "/" . $fileName;
     $localUrl = $this->getZoneUrl('thumb') . "/" . $this->getHashPath($name) . rawurlencode($name) . "/" . rawurlencode($fileName);
     if (file_exists($localFilename) && isset($metadata['timestamp'])) {
         wfDebug(__METHOD__ . " Thumbnail was already downloaded before\n");
         $modified = filemtime($localFilename);
         $remoteModified = strtotime($metadata['timestamp']);
         $current = time();
         $diff = abs($modified - $current);
         if ($remoteModified < $modified && $diff < $this->fileCacheExpiry) {
             /* Use our current and already downloaded thumbnail */
             $knownThumbUrls[$sizekey] = $localUrl;
             $wgMemc->set($key, $knownThumbUrls, $this->apiThumbCacheExpiry);
             return $localUrl;
         }
         /* There is a new Commons file, or existing thumbnail older than a month */
     }
     $thumb = self::httpGet($foreignUrl);
     if (!$thumb) {
         wfDebug(__METHOD__ . " Could not download thumb\n");
         return false;
     }
     if (!is_dir($localPath)) {
         if (!wfMkdirParents($localPath)) {
             wfDebug(__METHOD__ . " could not create directory {$localPath} for thumb\n");
             return $foreignUrl;
         }
     }
     # @todo FIXME: Delete old thumbs that aren't being used. Maintenance script?
     wfSuppressWarnings();
     if (!file_put_contents($localFilename, $thumb)) {
         wfRestoreWarnings();
         wfDebug(__METHOD__ . " could not write to thumb path\n");
         return $foreignUrl;
     }
     wfRestoreWarnings();
     $knownThumbUrls[$sizekey] = $localUrl;
     $wgMemc->set($key, $knownThumbUrls, $this->apiThumbCacheExpiry);
     wfDebug(__METHOD__ . " got local thumb {$localUrl}, saving to cache \n");
     return $localUrl;
 }
Example #30
0
 /**
  * Move a group of files to the deletion archive.
  * If no valid deletion archive is configured, this may either delete the
  * file or throw an exception, depending on the preference of the repository.
  *
  * @param array $sourceDestPairs Array of source/destination pairs. Each element
  *        is a two-element array containing the source file path relative to the
  *        public root in the first element, and the archive file path relative
  *        to the deleted zone root in the second element.
  * @return FileRepoStatus
  */
 function deleteBatch($sourceDestPairs)
 {
     $status = $this->newGood();
     if (!$this->deletedDir) {
         throw new MWException(__METHOD__ . ': no valid deletion archive directory');
     }
     /**
      * Validate filenames and create archive directories
      */
     foreach ($sourceDestPairs as $pair) {
         list($srcRel, $archiveRel) = $pair;
         if (!$this->validateFilename($srcRel)) {
             throw new MWException(__METHOD__ . ':Validation error in $srcRel');
         }
         if (!$this->validateFilename($archiveRel)) {
             throw new MWException(__METHOD__ . ':Validation error in $archiveRel');
         }
         $archivePath = "{$this->deletedDir}/{$archiveRel}";
         $archiveDir = dirname($archivePath);
         if (!is_dir($archiveDir)) {
             if (!wfMkdirParents($archiveDir)) {
                 $status->fatal('directorycreateerror', $archiveDir);
                 continue;
             }
             $this->initDeletedDir($archiveDir);
         }
         // Check if the archive directory is writable
         // This doesn't appear to work on NTFS
         if (!is_writable($archiveDir)) {
             $status->fatal('filedelete-archive-read-only', $archiveDir);
         }
     }
     if (!$status->ok) {
         // Abort early
         return $status;
     }
     /**
      * Move the files
      * We're now committed to returning an OK result, which will lead to
      * the files being moved in the DB also.
      */
     foreach ($sourceDestPairs as $pair) {
         list($srcRel, $archiveRel) = $pair;
         $srcPath = "{$this->directory}/{$srcRel}";
         $archivePath = "{$this->deletedDir}/{$archiveRel}";
         $good = true;
         if (file_exists($archivePath)) {
             # A file with this content hash is already archived
             if (!@unlink($srcPath)) {
                 $status->error('filedeleteerror', $srcPath);
                 $good = false;
             }
         } else {
             if (!@rename($srcPath, $archivePath)) {
                 $status->error('filerenameerror', $srcPath, $archivePath);
                 $good = false;
             } else {
                 @chmod($archivePath, 0644);
             }
         }
         if ($good) {
             $status->successCount++;
         } else {
             $status->failCount++;
         }
     }
     return $status;
 }