protected function __construct() { $idFile = wfTempDir() . '/mw-' . __CLASS__ . '-UID-nodeid'; $nodeId = is_file( $idFile ) ? file_get_contents( $idFile ) : ''; // Try to get some ID that uniquely identifies this machine (RFC 4122)... if ( !preg_match( '/^[0-9a-f]{12}$/i', $nodeId ) ) { wfSuppressWarnings(); if ( wfIsWindows() ) { // http://technet.microsoft.com/en-us/library/bb490913.aspx $csv = trim( wfShellExec( 'getmac /NH /FO CSV' ) ); $line = substr( $csv, 0, strcspn( $csv, "\n" ) ); $info = str_getcsv( $line ); $nodeId = isset( $info[0] ) ? str_replace( '-', '', $info[0] ) : ''; } elseif ( is_executable( '/sbin/ifconfig' ) ) { // Linux/BSD/Solaris/OS X // See http://linux.die.net/man/8/ifconfig $m = array(); preg_match( '/\s([0-9a-f]{2}(:[0-9a-f]{2}){5})\s/', wfShellExec( '/sbin/ifconfig -a' ), $m ); $nodeId = isset( $m[1] ) ? str_replace( ':', '', $m[1] ) : ''; } wfRestoreWarnings(); if ( !preg_match( '/^[0-9a-f]{12}$/i', $nodeId ) ) { $nodeId = MWCryptRand::generateHex( 12, true ); $nodeId[1] = dechex( hexdec( $nodeId[1] ) | 0x1 ); // set multicast bit } file_put_contents( $idFile, $nodeId ); // cache } $this->nodeId32 = wfBaseConvert( substr( sha1( $nodeId ), 0, 8 ), 16, 2, 32 ); $this->nodeId48 = wfBaseConvert( $nodeId, 16, 2, 48 ); // If different processes run as different users, they may have different temp dirs. // This is dealt with by initializing the clock sequence number and counters randomly. $this->lockFile88 = wfTempDir() . '/mw-' . __CLASS__ . '-UID-88'; $this->lockFile128 = wfTempDir() . '/mw-' . __CLASS__ . '-UID-128'; }
/** * Make a new temporary file on the file system. * Temporary files may be purged when the file object falls out of scope. * * @param $prefix string * @param $extension string * @return TempFSFile|null */ public static function factory($prefix, $extension = '') { wfProfileIn(__METHOD__); $base = wfTempDir() . '/' . $prefix . wfRandomString(12); $ext = $extension != '' ? ".{$extension}" : ""; for ($attempt = 1; true; $attempt++) { $path = "{$base}-{$attempt}{$ext}"; wfSuppressWarnings(); $newFileHandle = fopen($path, 'x'); wfRestoreWarnings(); if ($newFileHandle) { fclose($newFileHandle); break; // got it } if ($attempt >= 5) { wfProfileOut(__METHOD__); return null; // give up } } $tmpFile = new self($path); $tmpFile->canDelete = true; // safely instantiated wfProfileOut(__METHOD__); return $tmpFile; }
protected function setUp() { global $wgFileBackends; parent::setUp(); # Forge a FSRepo object to not have to rely on local wiki settings $tmpPrefix = wfTempDir() . '/storebatch-test-' . time() . '-' . mt_rand(); if ($this->getCliArg('use-filebackend=')) { $name = $this->getCliArg('use-filebackend='); $useConfig = array(); foreach ($wgFileBackends as $conf) { if ($conf['name'] == $name) { $useConfig = $conf; } } $useConfig['name'] = 'local-testing'; // swap name $class = $useConfig['class']; $backend = new $class($useConfig); } else { $backend = new FSFileBackend(array('name' => 'local-testing', 'lockManager' => 'nullLockManager', 'containerPaths' => array('unittests-public' => "{$tmpPrefix}-public", 'unittests-thumb' => "{$tmpPrefix}-thumb", 'unittests-temp' => "{$tmpPrefix}-temp", 'unittests-deleted' => "{$tmpPrefix}-deleted"))); } $this->repo = new FileRepo(array('name' => 'unittests', 'backend' => $backend)); $this->date = gmdate("YmdHis"); $this->createdFiles = array(); }
function setUp() { global $wgReadOnlyFile; $this->originals['wgReadOnlyFile'] = $wgReadOnlyFile; $wgReadOnlyFile = tempnam(wfTempDir(), "mwtest_readonly"); unlink($wgReadOnlyFile); }
private function createFileOfSize($size) { $filename = tempnam(wfTempDir(), "mwuploadtest"); $fh = fopen($filename, 'w'); ftruncate($fh, $size); fclose($fh); return $filename; }
protected function setUp() { parent::setUp(); // Setup a file for bug 29408 $this->bug29408File = wfTempDir() . '/bug29408'; file_put_contents($this->bug29408File, ""); self::$users = ['sysop' => new TestUser('Uploadstashtestsysop', 'Upload Stash Test Sysop', '*****@*****.**', ['sysop']), 'uploader' => new TestUser('Uploadstashtestuser', 'Upload Stash Test User', '*****@*****.**', [])]; }
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"); }
protected function doGetLocalCopyMulti(array $params) { $tmpFiles = array(); // (path => MockFSFile) foreach ($params['srcs'] as $src) { $tmpFiles[$src] = new MockFSFile(wfTempDir() . '/' . wfRandomString(32)); } return $tmpFiles; }
/** * @param $params array */ public function __construct($params) { global $wgDBAhandler; if (!isset($params['dir'])) { $params['dir'] = wfTempDir(); } $this->mFile = $params['dir'] . '/mw-cache-' . wfWikiID() . '.db'; wfDebug(__CLASS__ . ": using cache file {$this->mFile}\n"); $this->mHandler = $wgDBAhandler; }
private function populateCDB($thisSite, $local, $global) { $cdbFile = tempnam(wfTempDir(), 'MW-ClassicInterwikiLookupTest-') . '.cdb'; $cdb = \Cdb\Writer::open($cdbFile); $hash = $this->populateHash($thisSite, $local, $global); foreach ($hash as $key => $value) { $cdb->set($key, $value); } $cdb->close(); return $cdbFile; }
function setUp() { $this->save = array(); $saveVars = array('wgReadOnlyFile'); foreach ($saveVars as $var) { if (isset($GLOBALS[$var])) { $this->save[$var] = $GLOBALS[$var]; } } $GLOBALS['wgReadOnlyFile'] = wfTempDir() . '/testReadOnly-' . mt_rand(); }
/** * 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; }
/** * @param LocalFile $file * @param string $url * @param string $comment * @return FileRepoStatus */ private function uploadFromUrl($file, $url, $comment) { $tmpFile = tempnam(wfTempDir(), 'upload'); // fetch an asset $res = Http::get($url, 'default', ['noProxy' => true]); $this->assertTrue($res !== false, 'File from <' . $url . '> should be uploaded'); file_put_contents($tmpFile, $res); $this->assertTrue(is_readable($tmpFile), 'Temp file for HTTP upload should be created and readable'); Wikia::log(__METHOD__, false, sprintf('uploading %s (%.2f kB) as %s', $tmpFile, filesize($tmpFile) / 1024, $file->getName()), true); $res = $file->upload($tmpFile, $comment, ''); #unlink( $tmpFile ); return $res; }
function makeChunk( $content ) { $file = tempnam( wfTempDir(), "" ); $fh = fopen( $file, "wb" ); if ( $fh == false ) { $this->markTestIncomplete( "Couldn't open $file!\n" ); return; } fwrite( $fh, $content ); fclose( $fh ); $_FILES['chunk']['tmp_name'] = $file; $_FILES['chunk']['size'] = 3; $_FILES['chunk']['error'] = null; $_FILES['chunk']['name'] = "test.txt"; }
function setUp() { parent::setUp(); $this->filePath = dirname(__FILE__) . '/../../data/media/'; $this->handler = new BitmapHandler(); $this->repo = new FSRepo(array('name' => 'temp', 'directory' => wfTempDir() . '/exif-test-' . time() . '-' . mt_rand(), 'url' => 'http://localhost/thumbtest')); if (!wfDl('exif')) { $this->markTestSkipped("This test needs the exif extension."); } global $wgShowEXIF; $this->show = $wgShowEXIF; $wgShowEXIF = true; global $wgEnableAutoRotation; $this->oldAuto = $wgEnableAutoRotation; $wgEnableAutoRotation = true; }
function loadFile($type) { global $wgRequest, $wgUser; $ext = $type; $file_name = "Drawio_" . $wgRequest->getVal('drawio') . "." . $ext; $wgRequest->setVal('wpDestFile', $file_name); $wgRequest->setVal('wpIgnoreWarning', '1'); $wgRequest->setVal('wpDestFileWarningAck', '1'); $wgRequest->setVal('wpUploadDescription', ""); $wgRequest->setVal('action', ""); if ($type == "png") { $file_type = "image/png"; $pngval = $wgRequest->getVal($type); $comma_pos = strpos($pngval, ','); if ($comma_pos === false) { $file_body = stripslashes($pngval); } else { $file_body = base64_decode(substr($pngval, $comma_pos + 1)); } } else { $file_type = "text/xml"; $file_body = $wgRequest->getVal($type); } $file_len = strlen($file_body); if ($file_len > 0) { $_FILES['wpUploadFile']['name'] = $file_name; $_FILES['wpUploadFile']['type'] = $file_type; $_FILES['wpUploadFile']['error'] = 0; $_FILES['wpUploadFile']['size'] = $file_len; // $tmp_name = $_SERVER["DOCUMENT_ROOT"] . "tmp/tmp_".rand(0,1000).rand(0,1000).".".$ext; $tmp_name = wfTempDir() . "tmp_" . rand(0, 1000) . rand(0, 1000) . "." . $ext; $f = fopen($tmp_name, "w"); fwrite($f, $file_body); fclose($f); $_FILES['wpUploadFile']['tmp_name'] = $tmp_name; // Upload $form = UploadBase::createFromRequest($wgRequest, null); $outcome = $form->verifyUpload(); $res = $form->performUpload("", "", true, $wgUser); if (file_exists($tmp_name)) { unlink($tmp_name); } } // $outcome['request'] = $wgRequest; // $outcome['form'] = $form; return $outcome; }
/** * Fake an upload by dumping the file into temp space, and adding info to $_FILES. * (This is what PHP would normally do). * @param $fieldName String: name this would have in the upload form * @param $fileName String: name to title this * @param $type String: mime type * @param $filePath String: path where to find file contents */ function fakeUploadFile($fieldName, $fileName, $type, $filePath) { $tmpName = tempnam(wfTempDir(), ""); if (!file_exists($filePath)) { throw new Exception("{$filePath} doesn't exist!"); } if (!copy($filePath, $tmpName)) { throw new Exception("couldn't copy {$filePath} to {$tmpName}"); } clearstatcache(); $size = filesize($tmpName); if ($size === false) { throw new Exception("couldn't stat {$tmpName}"); } $_FILES[$fieldName] = array('name' => $fileName, 'type' => $type, 'tmp_name' => $tmpName, 'size' => $size, 'error' => null); return true; }
function setUp() { parent::setUp(); $this->handler = new BitmapHandler(); $filePath = dirname(__FILE__) . '/../../data/media'; $tmpDir = wfTempDir() . '/exif-test-' . time() . '-' . mt_rand(); $this->createdDirs[] = $tmpDir; $this->repo = new FSRepo(array('name' => 'temp', 'url' => 'http://localhost/thumbtest', 'backend' => new FSFileBackend(array('name' => 'localtesting', 'lockManager' => 'nullLockManager', 'containerPaths' => array('temp-thumb' => $tmpDir, 'data' => $filePath))))); if (!wfDl('exif')) { $this->markTestSkipped("This test needs the exif extension."); } global $wgShowEXIF; $this->show = $wgShowEXIF; $wgShowEXIF = true; global $wgEnableAutoRotation; $this->oldAuto = $wgEnableAutoRotation; $wgEnableAutoRotation = true; }
public function testCropping() { // requested crop size is 50 x 50 $im = new ImageServing(null, 50); $file = wfFindFile(self::FILE_NAME); // pass dimensions of full size image $cropUrl = $im->getUrl($file, $file->getWidth(), $file->getHeight()); $this->assertContains('/firefly/images/8/89/Wiki-wordmark.png/revision/latest/', $cropUrl); $this->assertContains('/width/50/', $cropUrl); // verify crop response $res = Http::get($cropUrl, 'default', ['noProxy' => true]); $this->assertTrue($res !== false, "<{$cropUrl}> should return HTTP 200"); // verify crop size $this->tmpFile = tempnam(wfTempDir(), 'img'); file_put_contents($this->tmpFile, $res); list($tmpWidth, $tmpHeight) = getimagesize($this->tmpFile); $this->assertEquals(50, $tmpWidth, 'expected crop width not matched - ' . $cropUrl); $this->assertEquals(49, $tmpHeight, 'expected crop height not matched - ' . $cropUrl); }
function setup() { putenv("http_proxy"); /* Remove any proxy env var, so curl doesn't get confused */ if (is_array(self::$content)) { return; } self::$has_curl = function_exists('curl_init'); self::$has_fopen = wfIniGetBool('allow_url_fopen'); if (!file_exists("/usr/bin/curl")) { $this->markTestIncomplete("This test requires the curl binary at /usr/bin/curl.\t If you have curl, please file a bug on this test, or, better yet, provide a patch."); } $content = tempnam(wfTempDir(), ""); $headers = tempnam(wfTempDir(), ""); if (!$content && !$headers) { die("Couldn't create temp file!"); } // This probably isn't the best test for a proxy, but it works on my system! system("curl -0 -o {$content} -s " . self::$proxy); $out = file_get_contents($content); if ($out) { self::$has_proxy = true; } /* Maybe use wget instead of curl here ... just to use a different codebase? */ foreach ($this->test_geturl as $u) { system("curl -0 -s -D {$headers} '{$u}' -o {$content}"); self::$content["GET {$u}"] = file_get_contents($content); self::$headers["GET {$u}"] = file_get_contents($headers); } foreach ($this->test_requesturl as $u) { system("curl -0 -s -X POST -H 'Content-Length: 0' -D {$headers} '{$u}' -o {$content}"); self::$content["POST {$u}"] = file_get_contents($content); self::$headers["POST {$u}"] = file_get_contents($headers); } foreach ($this->test_posturl as $u => $postData) { system("curl -0 -s -X POST -d '{$postData}' -D {$headers} '{$u}' -o {$content}"); self::$content["POST {$u} => {$postData}"] = file_get_contents($content); self::$headers["POST {$u} => {$postData}"] = file_get_contents($headers); } unlink($content); unlink($headers); }
protected function setUp() { parent::setUp(); $filename = 'Foo.png'; $this->tmpPrefix = $this->getNewTempDirectory(); $backend = new FSFileBackend(['name' => 'local-migratefilerepolayouttest', 'wikiId' => wfWikiID(), 'containerPaths' => ['migratefilerepolayouttest-original' => "{$this->tmpPrefix}-original", 'migratefilerepolayouttest-public' => "{$this->tmpPrefix}-public", 'migratefilerepolayouttest-thumb' => "{$this->tmpPrefix}-thumb", 'migratefilerepolayouttest-temp' => "{$this->tmpPrefix}-temp", 'migratefilerepolayouttest-deleted' => "{$this->tmpPrefix}-deleted"]]); $dbMock = $this->getMockBuilder('DatabaseMysql')->disableOriginalConstructor()->getMock(); $imageRow = new stdClass(); $imageRow->img_name = $filename; $imageRow->img_sha1 = sha1($this->text); $dbMock->expects($this->any())->method('select')->will($this->onConsecutiveCalls(new FakeResultWrapper([$imageRow]), new FakeResultWrapper([]), new FakeResultWrapper([]))); $repoMock = $this->getMock('LocalRepo', ['getMasterDB'], [['name' => 'migratefilerepolayouttest', 'backend' => $backend]]); $repoMock->expects($this->any())->method('getMasterDB')->will($this->returnValue($dbMock)); $this->migratorMock = $this->getMock('MigrateFileRepoLayout', ['getRepo']); $this->migratorMock->expects($this->any())->method('getRepo')->will($this->returnValue($repoMock)); $this->tmpFilepath = TempFSFile::factory('migratefilelayout-test-', 'png', wfTempDir())->getPath(); file_put_contents($this->tmpFilepath, $this->text); $hashPath = $repoMock->getHashPath($filename); $status = $repoMock->store($this->tmpFilepath, 'public', $hashPath . $filename, FileRepo::OVERWRITE); }
/** * Make a new temporary file on the file system. * Temporary files may be purged when the file object falls out of scope. * * @param string $prefix * @param string $extension * @return TempFSFile|null */ public static function factory($prefix, $extension = '') { $ext = $extension != '' ? ".{$extension}" : ''; $attempts = 5; while ($attempts--) { $path = wfTempDir() . '/' . $prefix . wfRandomString(12) . $ext; MediaWiki\suppressWarnings(); $newFileHandle = fopen($path, 'x'); MediaWiki\restoreWarnings(); if ($newFileHandle) { fclose($newFileHandle); $tmpFile = new self($path); $tmpFile->autocollect(); // Safely instantiated, end loop. return $tmpFile; } } // Give up return null; }
/** * @param array $info * @throws MWException */ function __construct(array $info) { if (!isset($info['backend'])) { // B/C settings... $directory = $info['directory']; $deletedDir = isset($info['deletedDir']) ? $info['deletedDir'] : false; $thumbDir = isset($info['thumbDir']) ? $info['thumbDir'] : "{$directory}/thumb"; $transcodedDir = isset($info['transcodedDir']) ? $info['transcodedDir'] : "{$directory}/transcoded"; $fileMode = isset($info['fileMode']) ? $info['fileMode'] : 0644; $repoName = $info['name']; // Get the FS backend configuration $backend = new FSFileBackend(['name' => $info['name'] . '-backend', 'wikiId' => wfWikiID(), 'lockManager' => LockManagerGroup::singleton(wfWikiID())->get('fsLockManager'), 'containerPaths' => ["{$repoName}-public" => "{$directory}", "{$repoName}-temp" => "{$directory}/temp", "{$repoName}-thumb" => $thumbDir, "{$repoName}-transcoded" => $transcodedDir, "{$repoName}-deleted" => $deletedDir], 'fileMode' => $fileMode, 'tmpDirectory' => wfTempDir()]); // Update repo config to use this backend $info['backend'] = $backend; } parent::__construct($info); if (!$this->backend instanceof FSFileBackend) { throw new MWException("FSRepo only supports FSFileBackend."); } }
public function testCdb() { $dir = wfTempDir(); if (!is_writable($dir)) { $this->markTestSkipped("Temp dir isn't writable"); } $w1 = new CdbWriter_PHP("{$dir}/php.cdb"); $w2 = new CdbWriter_DBA("{$dir}/dba.cdb"); $data = array(); for ($i = 0; $i < 1000; $i++) { $key = $this->randomString(); $value = $this->randomString(); $w1->set($key, $value); $w2->set($key, $value); if (!isset($data[$key])) { $data[$key] = $value; } } $w1->close(); $w2->close(); $this->assertEquals(md5_file("{$dir}/dba.cdb"), md5_file("{$dir}/php.cdb"), 'same hash'); $r1 = new CdbReader_PHP("{$dir}/php.cdb"); $r2 = new CdbReader_DBA("{$dir}/dba.cdb"); foreach ($data as $key => $value) { if ($key === '') { // Known bug continue; } $v1 = $r1->get($key); $v2 = $r2->get($key); $v1 = $v1 === false ? '(not found)' : $v1; $v2 = $v2 === false ? '(not found)' : $v2; # cdbAssert( 'Mismatch', $key, $v1, $v2 ); $this->cdbAssert("PHP error", $key, $v1, $value); $this->cdbAssert("DBA error", $key, $v2, $value); } unlink("{$dir}/dba.cdb"); unlink("{$dir}/php.cdb"); }
/** * Return metrics for given URL from phantomjs-powered JS script * * @see http://code.google.com/p/phantomjs/wiki/BuildInstructions * * @param string $url page URL * @param array $options additional options * @return mixed report */ public function getReport($url, array $options = array()) { // form command to be executed $dir = dirname(__FILE__); $cookiesFile = escapeshellcmd(tempnam(wfTempDir(), 'phantom')); $urlEscaped = escapeshellcmd($url); $cmd = "phantomjs --cookies-file={$cookiesFile} {$dir}/phantomjs/metrics.js {$urlEscaped}"; // support for logged-in metrics if (!empty($options['loggedIn'])) { $account = $this->getCredentials(); $cmd .= ' --username='******'username']); $cmd .= ' --password='******'password']); } // support for A/B testing if (!empty($options['abGroup'])) { $cmd .= ' --abGroup=' . $options['abGroup']; } exec($cmd, $output, $retVal); // decode the last line $report = json_decode(end($output), true); return $report; }
/** * Make a new temporary file on the file system. * Temporary files may be purged when the file object falls out of scope. * * @param string $prefix * @param string $extension Optional file extension * @param string|null $tmpDirectory Optional parent directory * @return TempFSFile|null */ public static function factory($prefix, $extension = '', $tmpDirectory = null) { $ext = $extension != '' ? ".{$extension}" : ''; $attempts = 5; while ($attempts--) { $hex = sprintf('%06x%06x', mt_rand(0, 0xffffff), mt_rand(0, 0xffffff)); if (!is_string($tmpDirectory)) { $tmpDirectory = self::getUsableTempDirectory(); } $path = wfTempDir() . '/' . $prefix . $hex . $ext; MediaWiki\suppressWarnings(); $newFileHandle = fopen($path, 'x'); MediaWiki\restoreWarnings(); if ($newFileHandle) { fclose($newFileHandle); $tmpFile = new self($path); $tmpFile->autocollect(); // Safely instantiated, end loop. return $tmpFile; } } // Give up return null; }
/** * Make a new temporary file on the file system. * Temporary files may be purged when the file object falls out of scope. * * @param string $prefix * @param string $extension * @return TempFSFile|null */ public static function factory($prefix, $extension = '') { $base = wfTempDir() . '/' . $prefix . wfRandomString(12); $ext = $extension != '' ? ".{$extension}" : ""; for ($attempt = 1; true; $attempt++) { $path = "{$base}-{$attempt}{$ext}"; MediaWiki\suppressWarnings(); $newFileHandle = fopen($path, 'x'); MediaWiki\restoreWarnings(); if ($newFileHandle) { fclose($newFileHandle); break; // got it } if ($attempt >= 5) { return null; // give up } } $tmpFile = new self($path); $tmpFile->autocollect(); // safely instantiated return $tmpFile; }
/** * Make a new temporary file on the file system. * Temporary files may be purged when the file object falls out of scope. * * @param $prefix string * @param $extension string * @return TempFSFile|null */ public static function factory($prefix, $extension = '') { $base = wfTempDir() . '/' . $prefix . dechex(mt_rand(0, 99999999)); $ext = $extension != '' ? ".{$extension}" : ""; for ($attempt = 1; true; $attempt++) { $path = "{$base}-{$attempt}{$ext}"; wfSuppressWarnings(); $newFileHandle = fopen($path, 'x'); wfRestoreWarnings(); if ($newFileHandle) { fclose($newFileHandle); break; // got it } if ($attempt >= 15) { return null; // give up } } $tmpFile = new self($path); $tmpFile->canDelete = true; // safely instantiated return $tmpFile; }
/** * Merge the current backoff expiries from persistent storage * * The $deltas map is set to an empty array on success. * On I/O or lock acquisition failure this returns the original $backoffs. * * @param array $backoffs Map of (job type => UNIX timestamp) * @param array $deltas Map of (job type => seconds) * @param string $mode Lock wait mode - "wait" or "nowait" * @return array The new backoffs account for $backoffs and the latest file data */ private function syncBackoffDeltas(array $backoffs, array &$deltas, $mode = 'wait') { if (!$deltas) { return $this->loadBackoffs($backoffs, $mode); } $noblock = $mode === 'nowait' ? LOCK_NB : 0; $file = wfTempDir() . '/mw-runJobs-backoffs.json'; $handle = fopen($file, 'wb+'); if (!flock($handle, LOCK_EX | $noblock)) { fclose($handle); return $backoffs; // don't wait on lock } $ctime = microtime(true); $content = stream_get_contents($handle); $cBackoffs = json_decode($content, true) ?: array(); foreach ($deltas as $type => $seconds) { $cBackoffs[$type] = isset($cBackoffs[$type]) && $cBackoffs[$type] >= $ctime ? $cBackoffs[$type] + $seconds : $ctime + $seconds; } foreach ($cBackoffs as $type => $timestamp) { if ($timestamp < $ctime) { unset($cBackoffs[$type]); } } ftruncate($handle, 0); fwrite($handle, json_encode($cBackoffs)); flock($handle, LOCK_UN); fclose($handle); $deltas = array(); return $cBackoffs; }
/** * Generate a diff, no caching * * @todo move this to TextDifferenceEngine, make DifferenceEngine abstract. At some point. * * @param string $otext Old text, must be already segmented * @param string $ntext New text, must be already segmented * * @return bool|string */ public function generateTextDiffBody($otext, $ntext) { global $wgExternalDiffEngine, $wgContLang; $otext = str_replace("\r\n", "\n", $otext); $ntext = str_replace("\r\n", "\n", $ntext); if ($wgExternalDiffEngine == 'wikidiff' && function_exists('wikidiff_do_diff')) { # For historical reasons, external diff engine expects # input text to be HTML-escaped already $otext = htmlspecialchars($wgContLang->segmentForDiff($otext)); $ntext = htmlspecialchars($wgContLang->segmentForDiff($ntext)); return $wgContLang->unsegmentForDiff(wikidiff_do_diff($otext, $ntext, 2)) . $this->debug('wikidiff1'); } if ($wgExternalDiffEngine == 'wikidiff2' && function_exists('wikidiff2_do_diff')) { # Better external diff engine, the 2 may some day be dropped # This one does the escaping and segmenting itself $text = wikidiff2_do_diff($otext, $ntext, 2); $text .= $this->debug('wikidiff2'); return $text; } if ($wgExternalDiffEngine != 'wikidiff3' && $wgExternalDiffEngine !== false) { # Diff via the shell $tmpDir = wfTempDir(); $tempName1 = tempnam($tmpDir, 'diff_'); $tempName2 = tempnam($tmpDir, 'diff_'); $tempFile1 = fopen($tempName1, "w"); if (!$tempFile1) { return false; } $tempFile2 = fopen($tempName2, "w"); if (!$tempFile2) { return false; } fwrite($tempFile1, $otext); fwrite($tempFile2, $ntext); fclose($tempFile1); fclose($tempFile2); $cmd = wfEscapeShellArg($wgExternalDiffEngine, $tempName1, $tempName2); $difftext = wfShellExec($cmd); $difftext .= $this->debug("external {$wgExternalDiffEngine}"); unlink($tempName1); unlink($tempName2); return $difftext; } # Native PHP diff $ota = explode("\n", $wgContLang->segmentForDiff($otext)); $nta = explode("\n", $wgContLang->segmentForDiff($ntext)); $diffs = new Diff($ota, $nta); $formatter = new TableDiffFormatter(); $difftext = $wgContLang->unsegmentForDiff($formatter->format($diffs)); return $difftext; }