コード例 #1
0
ファイル: DatabaseSqlite.php プロジェクト: D66Ha/mediawiki
 /**
  * Additional params include:
  *   - dbDirectory : directory containing the DB and the lock file directory
  *                   [defaults to $wgSQLiteDataDir]
  *   - dbFilePath  : use this to force the path of the DB file
  *   - trxMode     : one of (deferred, immediate, exclusive)
  * @param array $p
  */
 function __construct(array $p)
 {
     global $wgSharedDB, $wgSQLiteDataDir;
     $this->dbDir = isset($p['dbDirectory']) ? $p['dbDirectory'] : $wgSQLiteDataDir;
     if (isset($p['dbFilePath'])) {
         parent::__construct($p);
         // Standalone .sqlite file mode.
         // Super doesn't open when $user is false, but we can work with $dbName,
         // which is derived from the file path in this case.
         $this->openFile($p['dbFilePath']);
     } else {
         $this->mDBname = $p['dbname'];
         // Stock wiki mode using standard file names per DB.
         parent::__construct($p);
         // Super doesn't open when $user is false, but we can work with $dbName
         if ($p['dbname'] && !$this->isOpen()) {
             if ($this->open($p['host'], $p['user'], $p['password'], $p['dbname'])) {
                 if ($wgSharedDB) {
                     $this->attachDatabase($wgSharedDB);
                 }
             }
         }
     }
     $this->trxMode = isset($p['trxMode']) ? strtoupper($p['trxMode']) : null;
     if ($this->trxMode && !in_array($this->trxMode, array('DEFERRED', 'IMMEDIATE', 'EXCLUSIVE'))) {
         $this->trxMode = null;
         wfWarn("Invalid SQLite transaction mode provided.");
     }
     $this->lockMgr = new FSLockManager(array('lockDirectory' => "{$this->dbDir}/locks"));
 }
コード例 #2
0
 /**
  * Additional params include:
  *   - dbDirectory : directory containing the DB and the lock file directory
  *                   [defaults to $wgSQLiteDataDir]
  *   - dbFilePath  : use this to force the path of the DB file
  *   - trxMode     : one of (deferred, immediate, exclusive)
  * @param array $p
  */
 function __construct(array $p)
 {
     global $wgSharedDB, $wgSQLiteDataDir;
     $this->dbDir = isset($p['dbDirectory']) ? $p['dbDirectory'] : $wgSQLiteDataDir;
     if (isset($p['dbFilePath'])) {
         $this->mFlags = isset($p['flags']) ? $p['flags'] : 0;
         // Standalone .sqlite file mode
         $this->openFile($p['dbFilePath']);
         // @FIXME: clean up base constructor so this can call super instead
         $this->mTrxAtomicLevels = new SplStack();
     } else {
         $this->mDBname = $p['dbname'];
         // Stock wiki mode using standard file names per DB
         parent::__construct($p);
         // parent doesn't open when $user is false, but we can work with $dbName
         if ($p['dbname'] && !$this->isOpen()) {
             if ($this->open($p['host'], $p['user'], $p['password'], $p['dbname'])) {
                 if ($wgSharedDB) {
                     $this->attachDatabase($wgSharedDB);
                 }
             }
         }
     }
     $this->trxMode = isset($p['trxMode']) ? strtoupper($p['trxMode']) : null;
     if ($this->trxMode && !in_array($this->trxMode, array('DEFERRED', 'IMMEDIATE', 'EXCLUSIVE'))) {
         $this->trxMode = null;
         wfWarn("Invalid SQLite transaction mode provided.");
     }
     $this->lockMgr = new FSLockManager(array('lockDirectory' => "{$this->dbDir}/locks"));
 }
コード例 #3
0
 public function onAfterInsert($object, array $row, array $metadata)
 {
     if (!$object instanceof PostRevision) {
         wfWarn(__METHOD__ . ': Object is no PostRevision instance');
         return;
     }
     if (!isset($metadata['workflow'])) {
         wfWarn(__METHOD__ . ': Missing required metadata: workflow');
         return;
     }
     $workflow = $metadata['workflow'];
     if (!$workflow instanceof Workflow) {
         throw new InvalidDataException('Workflow metadata is not Workflow instance');
     }
     if ($workflow->getType() !== 'topic') {
         wfWarn(__METHOD__ . ': Expected "topic" workflow but received "' . $workflow->getType() . '"');
         return;
     }
     /** @var $title Title */
     $title = $workflow->getArticleTitle();
     if (!$title) {
         return;
     }
     $this->onAfterInsertExpectedChange($row['rev_change_type'], $metadata['workflow']);
 }
コード例 #4
0
 /**
  * Use the HTML tidy extension to use the tidy library in-process,
  * saving the overhead of spawning a new process.
  *
  * @param string $text HTML to check
  * @param bool $stderr Whether to read result from error status instead of output
  * @param int &$retval Exit code (-1 on internal error)
  * @return string|null
  */
 protected function cleanWrapped($text, $stderr = false, &$retval = null)
 {
     if (!class_exists('tidy')) {
         wfWarn("Unable to load internal tidy class.");
         $retval = -1;
         return null;
     }
     $tidy = new \tidy();
     $tidy->parseString($text, $this->config['tidyConfigFile'], 'utf8');
     if ($stderr) {
         $retval = $tidy->getStatus();
         return $tidy->errorBuffer;
     }
     $tidy->cleanRepair();
     $retval = $tidy->getStatus();
     if ($retval == 2) {
         // 2 is magic number for fatal error
         // http://www.php.net/manual/en/function.tidy-get-status.php
         $cleansource = null;
     } else {
         $cleansource = tidy_get_output($tidy);
         if (!empty($this->config['debugComment']) && $retval > 0) {
             $cleansource .= "<!--\nTidy reports:\n" . str_replace('-->', '--&gt;', $tidy->errorBuffer) . "\n-->";
         }
     }
     return $cleansource;
 }
コード例 #5
0
 /**
  * Registeres a feature for a service object.
  * Registers a warning when the service is not registered, but does not give an error.
  * 
  * @since 0.6.6
  * 
  * @param $serviceIdentifier String: internal service identifier
  * @param $featureName String
  * @param $featureClassName String
  */
 public static function registerServiceFeature($serviceIdentifier, $featureName, $featureClassName)
 {
     if (array_key_exists($serviceIdentifier, self::$registeredServices)) {
         $service = self::getServiceInstance($serviceIdentifier);
         $service->addFeature($featureName, $featureClassName);
     } else {
         // If the feature is not registered, register a warning. This is not an error though!
         wfWarn("Tried to register feature '{$featureName}' with class '{$featureClassName}' to non-registered service '{$serviceIdentifier}'.");
     }
 }
コード例 #6
0
 function __construct()
 {
     $this->cliMode = true;
     $this->connLogger = new \Psr\Log\NullLogger();
     $this->queryLogger = new \Psr\Log\NullLogger();
     $this->errorLogger = function (Exception $e) {
         wfWarn(get_class($e) . ": {$e->getMessage()}");
     };
     $this->currentDomain = DatabaseDomain::newUnspecified();
 }
コード例 #7
0
 public function __construct($text, $model_id = CONTENT_MODEL_TEXT)
 {
     parent::__construct($model_id);
     if ($text === null || $text === false) {
         wfWarn("TextContent constructed with \$text = " . var_export($text, true) . "! " . "This may indicate an error in the caller's scope.");
         $text = '';
     }
     if (!is_string($text)) {
         throw new MWException("TextContent expects a string in the constructor.");
     }
     $this->mText = $text;
 }
コード例 #8
0
 public function __construct($testName, array $opts = [])
 {
     $this->testName = $testName;
     $this->profiler = new ProfilerStub([]);
     $this->trxProfiler = new TransactionProfiler();
     $this->cliMode = isset($opts['cliMode']) ? $opts['cliMode'] : true;
     $this->connLogger = new \Psr\Log\NullLogger();
     $this->queryLogger = new \Psr\Log\NullLogger();
     $this->errorLogger = function (Exception $e) {
         wfWarn(get_class($e) . ": {$e->getMessage()}");
     };
     $this->currentDomain = DatabaseDomain::newUnspecified();
 }
コード例 #9
0
 /**
  * @see ParameterManipulation::manipulate
  * 
  * @since 0.7
  */
 public function manipulate(Parameter &$parameter, array &$parameters)
 {
     global $egMapsOLLayerGroups, $egMapsOLAvailableLayers;
     $layerDefs = array();
     $layerNames = array();
     foreach ($parameter->getValue() as $layerOrGroup) {
         $lcLayerOrGroup = strtolower($layerOrGroup);
         // Layer groups. Loop over all items and add them when not present yet.
         if (array_key_exists($lcLayerOrGroup, $egMapsOLLayerGroups)) {
             foreach ($egMapsOLLayerGroups[$lcLayerOrGroup] as $layerName) {
                 if (!in_array($layerName, $layerNames)) {
                     if (is_array($egMapsOLAvailableLayers[$layerName])) {
                         $layerDefs[] = 'new ' . $egMapsOLAvailableLayers[$layerName][0];
                     } else {
                         $layerDefs[] = 'new ' . $egMapsOLAvailableLayers[$layerName];
                     }
                     $layerNames[] = $layerName;
                 }
             }
         } elseif (array_key_exists($lcLayerOrGroup, $egMapsOLAvailableLayers)) {
             if (!in_array($lcLayerOrGroup, $layerNames)) {
                 if (is_array($egMapsOLAvailableLayers[$lcLayerOrGroup])) {
                     $layerDefs[] = 'new ' . $egMapsOLAvailableLayers[$lcLayerOrGroup][0];
                 } else {
                     $layerDefs[] = 'new ' . $egMapsOLAvailableLayers[$lcLayerOrGroup];
                 }
                 $layerNames[] = $lcLayerOrGroup;
             }
         } else {
             $title = Title::newFromText($layerOrGroup, Maps_NS_LAYER);
             if ($title->getNamespace() == Maps_NS_LAYER && $title->exists()) {
                 $layerPage = new MapsLayerPage($title);
                 if ($layerPage->hasValidDefinition('openlayers')) {
                     $layer = $layerPage->getLayer();
                     if (!in_array($layerOrGroup, $layerNames)) {
                         $layerDefs[] = $layer->getJavaScriptDefinition();
                         $layerNames[] = $layerOrGroup;
                     }
                 } else {
                     wfWarn("Invalid layer ({$layerOrGroup}) encountered after validation.");
                 }
             } else {
                 wfWarn("Invalid layer ({$layerOrGroup}) encountered after validation.");
             }
         }
     }
     $parameter->setValue($layerDefs);
     MapsMappingServices::getServiceInstance('openlayers')->addLayerDependencies($this->getDependencies($layerNames));
 }
コード例 #10
0
 /**
  * @param IContextSource $context
  * @param AbstractRevision $newRevision
  * @param AbstractRevision|null $oldRevision
  * @param Title $title
  * @return Status
  */
 public function validate(IContextSource $context, AbstractRevision $newRevision, AbstractRevision $oldRevision = null, Title $title)
 {
     $spamObj = BaseBlacklist::getInstance('spam');
     if (!$spamObj instanceof \SpamBlacklist) {
         wfWarn(__METHOD__ . ': Expected a SpamBlacklist instance but instead received: ' . get_class($spamObj));
         return Status::newFatal('something');
     }
     $links = $this->getLinks($newRevision, $title);
     $matches = $spamObj->filter($links, $title);
     if ($matches !== false) {
         $status = Status::newFatal('spamprotectiontext');
         foreach ($matches as $match) {
             $status->fatal('spamprotectionmatch', $match);
         }
         return $status;
     }
     return Status::newGood();
 }
 /**
  * Get the site ids of other projects to use.
  *
  * @param array $siteLinkGroups
  * @return string[]
  */
 public function getOtherProjectsSiteIds(array $siteLinkGroups)
 {
     $localSite = $this->getLocalSite();
     if ($localSite === null) {
         wfWarn('Site not found for ' . $this->localSiteId);
         return array();
     }
     $currentGroupId = $localSite->getGroup();
     $otherProjectsSiteIds = array();
     $this->expandSpecialGroups($siteLinkGroups);
     foreach ($siteLinkGroups as $groupId) {
         if ($groupId === $currentGroupId) {
             continue;
         }
         $siteToAdd = $this->getSiteForGroup($groupId, $localSite->getLanguageCode());
         if ($siteToAdd) {
             $otherProjectsSiteIds[] = $siteToAdd->getGlobalId();
         }
     }
     return $otherProjectsSiteIds;
 }
コード例 #12
0
 /**
  * Break down $job into approximately ($bSize/$cSize) leaf jobs and a single partition
  * job that covers the remaining backlink range (if needed). Jobs for the first $bSize
  * titles are collated ($cSize per job) into leaf jobs to do actual work. All the
  * resulting jobs are of the same class as $job. No partition job is returned if the
  * range covered by $job was less than $bSize, as the leaf jobs have full coverage.
  *
  * The leaf jobs have the 'pages' param set to a (<page ID>:(<namespace>,<DB key>),...)
  * map so that the run() function knows what pages to act on. The leaf jobs will keep
  * the same job title as the parent job (e.g. $job).
  *
  * The partition jobs have the 'range' parameter set to a map of the format
  * (start:<integer>, end:<integer>, batchSize:<integer>, subranges:((<start>,<end>),...)),
  * the 'table' parameter set to that of $job, and the 'recursive' parameter set to true.
  * This method can be called on the resulting job to repeat the process again.
  *
  * The job provided ($job) must have the 'recursive' parameter set to true and the 'table'
  * parameter must be set to a backlink table. The job title will be used as the title to
  * find backlinks for. Any 'range' parameter must follow the same format as mentioned above.
  * This should be managed by recursive calls to this method.
  *
  * The first jobs return are always the leaf jobs. This lets the caller use push() to
  * put them directly into the queue and works well if the queue is FIFO. In such a queue,
  * the leaf jobs have to get finished first before anything can resolve the next partition
  * job, which keeps the queue very small.
  *
  * $opts includes:
  *   - params : extra job parameters to include in each job
  *
  * @param Job $job
  * @param int $bSize BacklinkCache partition size; usually $wgUpdateRowsPerJob
  * @param int $cSize Max titles per leaf job; Usually 1 or a modest value
  * @param array $opts Optional parameter map
  * @return Job[] List of Job objects
  */
 public static function partitionBacklinkJob(Job $job, $bSize, $cSize, $opts = array())
 {
     $class = get_class($job);
     $title = $job->getTitle();
     $params = $job->getParams();
     if (isset($params['pages']) || empty($params['recursive'])) {
         $ranges = array();
         // sanity; this is a leaf node
         wfWarn(__METHOD__ . " called on {$job->getType()} leaf job (explosive recursion).");
     } elseif (isset($params['range'])) {
         // This is a range job to trigger the insertion of partitioned/title jobs...
         $ranges = $params['range']['subranges'];
         $realBSize = $params['range']['batchSize'];
     } else {
         // This is a base job to trigger the insertion of partitioned jobs...
         $ranges = $title->getBacklinkCache()->partition($params['table'], $bSize);
         $realBSize = $bSize;
     }
     $extraParams = isset($opts['params']) ? $opts['params'] : array();
     $jobs = array();
     // Combine the first range (of size $bSize) backlinks into leaf jobs
     if (isset($ranges[0])) {
         list($start, $end) = $ranges[0];
         $titles = $title->getBacklinkCache()->getLinks($params['table'], $start, $end);
         foreach (array_chunk(iterator_to_array($titles), $cSize) as $titleBatch) {
             $pages = array();
             foreach ($titleBatch as $tl) {
                 $pages[$tl->getArticleId()] = array($tl->getNamespace(), $tl->getDBKey());
             }
             $jobs[] = new $class($title, array('pages' => $pages) + $extraParams);
         }
     }
     // Take all of the remaining ranges and build a partition job from it
     if (isset($ranges[1])) {
         $jobs[] = new $class($title, array('recursive' => true, 'table' => $params['table'], 'range' => array('start' => $ranges[1][0], 'end' => $ranges[count($ranges) - 1][1], 'batchSize' => $realBSize, 'subranges' => array_slice($ranges, 1))) + $extraParams);
     }
     return $jobs;
 }
コード例 #13
0
 /**
  * Spawn an external HTML tidy process and get corrected markup back from it.
  * Also called in OutputHandler.php for full page validation
  *
  * @param string $text HTML to check
  * @param bool $stderr Whether to read result from STDERR rather than STDOUT
  * @param int &$retval Exit code (-1 on internal error)
  * @return string|null
  */
 protected function cleanWrapped($text, $stderr = false, &$retval = null)
 {
     $cleansource = '';
     $opts = ' -utf8';
     if ($stderr) {
         $descriptorspec = [0 => ['pipe', 'r'], 1 => ['file', wfGetNull(), 'a'], 2 => ['pipe', 'w']];
     } else {
         $descriptorspec = [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['file', wfGetNull(), 'a']];
     }
     $readpipe = $stderr ? 2 : 1;
     $pipes = [];
     $process = proc_open("{$this->config['tidyBin']} -config {$this->config['tidyConfigFile']} " . $this->config['tidyCommandLine'] . $opts, $descriptorspec, $pipes);
     // NOTE: At least on linux, the process will be created even if tidy is not installed.
     //      This means that missing tidy will be treated as a validation failure.
     if (is_resource($process)) {
         // Theoretically, this style of communication could cause a deadlock
         // here. If the stdout buffer fills up, then writes to stdin could
         // block. This doesn't appear to happen with tidy, because tidy only
         // writes to stdout after it's finished reading from stdin. Search
         // for tidyParseStdin and tidySaveStdout in console/tidy.c
         fwrite($pipes[0], $text);
         fclose($pipes[0]);
         while (!feof($pipes[$readpipe])) {
             $cleansource .= fgets($pipes[$readpipe], 1024);
         }
         fclose($pipes[$readpipe]);
         $retval = proc_close($process);
     } else {
         wfWarn("Unable to start external tidy process");
         $retval = -1;
     }
     if (!$stderr && $cleansource == '' && $text != '') {
         // Some kind of error happened, so we couldn't get the corrected text.
         // Just give up; we'll use the source text and append a warning.
         $cleansource = null;
     }
     return $cleansource;
 }
コード例 #14
0
ファイル: SRF_Graph.php プロジェクト: Tjorriemorrie/app
 protected function getResultText(SMWQueryResult $res, $outputmode)
 {
     if (!is_callable('renderGraphviz')) {
         wfWarn('The SRF Graph printer needs the GraphViz extension to be installed.');
         return '';
     }
     global $wgGraphVizSettings;
     $this->isHTML = true;
     $graphInput = "digraph {$this->m_graphName} {";
     if ($this->m_graphSize != '') {
         $graphInput .= "size=\"{$this->m_graphSize}\";";
     }
     if ($this->m_nodeShape) {
         $graphInput .= "node [shape={$this->m_nodeShape}];";
     }
     $graphInput .= "rankdir={$this->m_rankdir};";
     while ($row = $res->getNext()) {
         $graphInput .= $this->getGVForItem($row, $outputmode);
     }
     $graphInput .= "}";
     // Calls renderGraphViz function from MediaWiki GraphViz extension
     $result = renderGraphviz($graphInput);
     if ($this->m_graphLegend && $this->m_graphColor) {
         $arrayCount = 0;
         $arraySize = count($this->m_graphColors);
         $result .= "<P>";
         foreach ($this->m_labelArray as $m_label) {
             if ($arrayCount >= $arraySize) {
                 $arrayCount = 0;
             }
             $color = $this->m_graphColors[$arrayCount];
             $result .= "<font color={$color}>{$color}: {$m_label} </font><br />";
             $arrayCount += 1;
         }
         $result .= "</P>";
     }
     return $result;
 }
コード例 #15
0
 /**
  * @param DatabaseUpdater $updater
  */
 public function doSchemaUpdate(DatabaseUpdater $updater)
 {
     $db = $updater->getDB();
     $type = $db->getType();
     if ($type !== 'mysql' && $type !== 'sqlite') {
         wfWarn("Database type '{$type}' is not supported by the Wikibase repository.");
         return;
     }
     $this->addChangesTable($updater, $type);
     // Update from 0.1.
     if (!$db->tableExists('wb_terms')) {
         $updater->dropTable('wb_items_per_site');
         $updater->dropTable('wb_items');
         $updater->dropTable('wb_aliases');
         $updater->dropTable('wb_texts_per_lang');
         $updater->addExtensionTable('wb_terms', $this->getUpdateScriptPath('Wikibase', $db->getType()));
         $this->store->rebuild();
     }
     $this->updateEntityPerPageTable($updater, $db);
     $this->updateTermsTable($updater, $db);
     $this->updateItemsPerSiteTable($updater, $db);
     $this->updateChangesTable($updater, $db);
     $this->registerPropertyInfoTableUpdates($updater);
 }
コード例 #16
0
ファイル: Title.php プロジェクト: MediaWiki-stable/1.26.1
 /**
  * Create a new Title from text, such as what one would find in a link. De-
  * codes any HTML entities in the text.
  *
  * @param string $text The link text; spaces, prefixes, and an
  *   initial ':' indicating the main namespace are accepted.
  * @param int $defaultNamespace The namespace to use if none is specified
  *   by a prefix.  If you want to force a specific namespace even if
  *   $text might begin with a namespace prefix, use makeTitle() or
  *   makeTitleSafe().
  * @throws InvalidArgumentException
  * @return Title|null Title or null on an error.
  */
 public static function newFromText($text, $defaultNamespace = NS_MAIN)
 {
     if (is_object($text)) {
         throw new InvalidArgumentException('$text must be a string.');
     } elseif (!is_string($text)) {
         wfDebugLog('T76305', wfGetAllCallers(5));
         wfWarn(__METHOD__ . ': $text must be a string. This will throw an InvalidArgumentException in future.', 2);
     }
     try {
         return Title::newFromTextThrow($text, $defaultNamespace);
     } catch (MalformedTitleException $ex) {
         return null;
     }
 }
コード例 #17
0
ファイル: WikiPage.php プロジェクト: nahoj/mediawiki_ynh
	/**
	 * Returns the page's content model id (see the CONTENT_MODEL_XXX constants).
	 *
	 * Will use the revisions actual content model if the page exists,
	 * and the page's default if the page doesn't exist yet.
	 *
	 * @return String
	 *
	 * @since 1.21
	 */
	public function getContentModel() {
		if ( $this->exists() ) {
			// look at the revision's actual content model
			$rev = $this->getRevision();

			if ( $rev !== null ) {
				return $rev->getContentModel();
			} else {
				$title = $this->mTitle->getPrefixedDBkey();
				wfWarn( "Page $title exists but has no (visible) revisions!" );
			}
		}

		// use the default model for this page
		return $this->mTitle->getContentModel();
	}
コード例 #18
0
 /**
  * Get the local name for a specified canonical name
  *
  * @param string $name
  * @param string|bool $subpage
  * @return string
  */
 public static function getLocalNameFor($name, $subpage = false)
 {
     global $wgContLang;
     $aliases = $wgContLang->getSpecialPageAliases();
     $aliasList = self::getAliasList();
     // Find the first alias that maps back to $name
     if (isset($aliases[$name])) {
         $found = false;
         foreach ($aliases[$name] as $alias) {
             $caseFoldedAlias = $wgContLang->caseFold($alias);
             $caseFoldedAlias = str_replace(' ', '_', $caseFoldedAlias);
             if (isset($aliasList[$caseFoldedAlias]) && $aliasList[$caseFoldedAlias] === $name) {
                 $name = $alias;
                 $found = true;
                 break;
             }
         }
         if (!$found) {
             wfWarn("Did not find a usable alias for special page '{$name}'. " . "It seems all defined aliases conflict?");
         }
     } else {
         // Check if someone misspelled the correct casing
         if (is_array($aliases)) {
             foreach ($aliases as $n => $values) {
                 if (strcasecmp($name, $n) === 0) {
                     wfWarn("Found alias defined for {$n} when searching for " . "special page aliases for {$name}. Case mismatch?");
                     return self::getLocalNameFor($n, $subpage);
                 }
             }
         }
         wfWarn("Did not find alias for special page '{$name}'. " . "Perhaps no aliases are defined for it?");
     }
     if ($subpage !== false && !is_null($subpage)) {
         $name = "{$name}/{$subpage}";
     }
     return $wgContLang->ucfirst($name);
 }
コード例 #19
0
 /**
  * Get the local name for a specified canonical name
  *
  * @param $name String
  * @param $subpage String|Bool
  *
  * @return String
  */
 static function getLocalNameFor($name, $subpage = false)
 {
     global $wgContLang;
     $aliases = $wgContLang->getSpecialPageAliases();
     if (isset($aliases[$name][0])) {
         $name = $aliases[$name][0];
     } else {
         // Try harder in case someone misspelled the correct casing
         $found = false;
         foreach ($aliases as $n => $values) {
             if (strcasecmp($name, $n) === 0) {
                 wfWarn("Found alias defined for {$n} when searching for " . "special page aliases for {$name}. Case mismatch?");
                 $name = $values[0];
                 $found = true;
                 break;
             }
         }
         if (!$found) {
             wfWarn("Did not find alias for special page '{$name}'. " . "Perhaps no aliases are defined for it?");
         }
     }
     if ($subpage !== false && !is_null($subpage)) {
         $name = "{$name}/{$subpage}";
     }
     return $wgContLang->ucfirst($name);
 }
コード例 #20
0
ファイル: WikiPage.php プロジェクト: paladox/mediawiki
 /**
  * Returns the page's content model id (see the CONTENT_MODEL_XXX constants).
  *
  * Will use the revisions actual content model if the page exists,
  * and the page's default if the page doesn't exist yet.
  *
  * @return string
  *
  * @since 1.21
  */
 public function getContentModel()
 {
     if ($this->exists()) {
         $cache = ObjectCache::getMainWANInstance();
         return $cache->getWithSetCallback($cache->makeKey('page', 'content-model', $this->getLatest()), $cache::TTL_MONTH, function () {
             $rev = $this->getRevision();
             if ($rev) {
                 // Look at the revision's actual content model
                 return $rev->getContentModel();
             } else {
                 $title = $this->mTitle->getPrefixedDBkey();
                 wfWarn("Page {$title} exists but has no (visible) revisions!");
                 return $this->mTitle->getContentModel();
             }
         });
     }
     // use the default model for this page
     return $this->mTitle->getContentModel();
 }
コード例 #21
0
ファイル: Language.php プロジェクト: nanasess/mediawiki
 /**
  * Fill a MagicWord object with data from here
  *
  * @param MagicWord $mw
  */
 function getMagic($mw)
 {
     // Saves a function call
     if (!$this->mMagicHookDone) {
         $this->doMagicHook();
     }
     if (isset($this->mMagicExtensions[$mw->mId])) {
         $rawEntry = $this->mMagicExtensions[$mw->mId];
     } else {
         $rawEntry = self::$dataCache->getSubitem($this->mCode, 'magicWords', $mw->mId);
     }
     if (!is_array($rawEntry)) {
         wfWarn("\"{$rawEntry}\" is not a valid magic word for \"{$mw->mId}\"");
     } else {
         $mw->mCaseSensitive = $rawEntry[0];
         $mw->mSynonyms = array_slice($rawEntry, 1);
     }
 }
コード例 #22
0
ファイル: GlobalFunctions.php プロジェクト: D66Ha/mediawiki
/**
 * Returns message in the requested format
 *
 * @deprecated since 1.18
 *
 * @param string $key Key of the message
 * @param array $options Processing rules.
 *   Can take the following options:
 *     parse: parses wikitext to HTML
 *     parseinline: parses wikitext to HTML and removes the surrounding
 *       p's added by parser or tidy
 *     escape: filters message through htmlspecialchars
 *     escapenoentities: same, but allows entity references like &#160; through
 *     replaceafter: parameters are substituted after parsing or escaping
 *     parsemag: transform the message using magic phrases
 *     content: fetch message for content language instead of interface
 *   Also can accept a single associative argument, of the form 'language' => 'xx':
 *     language: Language object or language code to fetch message for
 *       (overridden by content).
 * Behavior for conflicting options (e.g., parse+parseinline) is undefined.
 *
 * @return string
 */
function wfMsgExt($key, $options)
{
    wfDeprecated(__METHOD__, '1.21');
    $args = func_get_args();
    array_shift($args);
    array_shift($args);
    $options = (array) $options;
    $validOptions = array('parse', 'parseinline', 'escape', 'escapenoentities', 'replaceafter', 'parsemag', 'content');
    foreach ($options as $arrayKey => $option) {
        if (!preg_match('/^[0-9]+|language$/', $arrayKey)) {
            // An unknown index, neither numeric nor "language"
            wfWarn("wfMsgExt called with incorrect parameter key {$arrayKey}", 1, E_USER_WARNING);
        } elseif (preg_match('/^[0-9]+$/', $arrayKey) && !in_array($option, $validOptions)) {
            // A numeric index with unknown value
            wfWarn("wfMsgExt called with incorrect parameter {$option}", 1, E_USER_WARNING);
        }
    }
    if (in_array('content', $options, true)) {
        $forContent = true;
        $langCode = true;
        $langCodeObj = null;
    } elseif (array_key_exists('language', $options)) {
        $forContent = false;
        $langCode = wfGetLangObj($options['language']);
        $langCodeObj = $langCode;
    } else {
        $forContent = false;
        $langCode = false;
        $langCodeObj = null;
    }
    $string = wfMsgGetKey($key, true, $langCode, false);
    if (!in_array('replaceafter', $options, true)) {
        $string = wfMsgReplaceArgs($string, $args);
    }
    $messageCache = MessageCache::singleton();
    $parseInline = in_array('parseinline', $options, true);
    if (in_array('parse', $options, true) || $parseInline) {
        $string = $messageCache->parse($string, null, true, !$forContent, $langCodeObj);
        if ($string instanceof ParserOutput) {
            $string = $string->getText();
        }
        if ($parseInline) {
            $string = Parser::stripOuterParagraph($string);
        }
    } elseif (in_array('parsemag', $options, true)) {
        $string = $messageCache->transform($string, !$forContent, $langCodeObj);
    }
    if (in_array('escape', $options, true)) {
        $string = htmlspecialchars($string);
    } elseif (in_array('escapenoentities', $options, true)) {
        $string = Sanitizer::escapeHtmlAllowEntities($string);
    }
    if (in_array('replaceafter', $options, true)) {
        $string = wfMsgReplaceArgs($string, $args);
    }
    return $string;
}
コード例 #23
0
 function getRow()
 {
     $id = $this->id();
     $dbw = wfGetDB(DB_MASTER);
     if (!$id) {
         $id = $dbw->nextSequenceValue('thread_thread_id');
     }
     // If there's no root, bail out with an error message
     if (!$this->rootId && !($this->type & Threads::TYPE_DELETED)) {
         throw new MWException("Non-deleted thread saved with empty root ID");
     }
     if ($this->replyCount < -1) {
         wfWarn("Saving thread {$id} with negative reply count {$this->replyCount} " . wfGetAllCallers());
         $this->replyCount = -1;
     }
     // Reflect schema changes here.
     return array('thread_id' => $id, 'thread_root' => $this->rootId, 'thread_parent' => $this->parentId, 'thread_article_namespace' => $this->articleNamespace, 'thread_article_title' => $this->articleTitle, 'thread_article_id' => $this->articleId, 'thread_modified' => $dbw->timestamp($this->modified), 'thread_created' => $dbw->timestamp($this->created), 'thread_ancestor' => $this->ancestorId, 'thread_type' => $this->type, 'thread_subject' => $this->subject, 'thread_author_id' => $this->authorId, 'thread_author_name' => $this->authorName, 'thread_summary_page' => $this->summaryId, 'thread_editedness' => $this->editedness, 'thread_sortkey' => $this->sortkey, 'thread_replies' => $this->replyCount, 'thread_signature' => $this->signature);
 }
コード例 #24
0
 /**
  * Format an auto summary argument
  *
  * @since 0.4
  *
  * @param mixed $arg
  *
  * @return string
  */
 protected function formatArg($arg)
 {
     try {
         if ($arg instanceof Snak) {
             return $this->snakFormatter->formatSnak($arg);
         } elseif ($arg instanceof EntityId) {
             return $this->idFormatter->formatEntityId($arg);
         } elseif ($arg instanceof DataValue) {
             return $this->valueFormatter->format($arg);
         } elseif (method_exists($arg, '__toString')) {
             return strval($arg);
         } elseif (is_object($arg)) {
             return '<' . get_class($arg) . '>';
         } elseif (is_array($arg)) {
             if (!empty($arg) && !isset($arg[0])) {
                 // turn assoc array into a list
                 $arg = $this->formatKeyValuePairs($arg);
             }
             $strings = $this->formatArgList($arg);
             return $this->language->commaList($strings);
         } else {
             return strval($arg);
         }
     } catch (Exception $ex) {
         wfWarn(__METHOD__ . ': failed to render value: ' . $ex->getMessage());
     }
     return '?';
 }
コード例 #25
0
ファイル: Autopromote.php プロジェクト: Tjorriemorrie/app
 /**
  * Recursively check a condition.  Conditions are in the form
  *   array( '&' or '|' or '^' or '!', cond1, cond2, ... )
  * where cond1, cond2, ... are themselves conditions; *OR*
  *   APCOND_EMAILCONFIRMED, *OR*
  *   array( APCOND_EMAILCONFIRMED ), *OR*
  *   array( APCOND_EDITCOUNT, number of edits ), *OR*
  *   array( APCOND_AGE, seconds since registration ), *OR*
  *   similar constructs defined by extensions.
  * This function evaluates the former type recursively, and passes off to
  * self::checkCondition for evaluation of the latter type.
  *
  * @param $cond Mixed: a condition, possibly containing other conditions
  * @param $user User The user to check the conditions against
  * @return bool Whether the condition is true
  */
 private static function recCheckCondition($cond, User $user)
 {
     $validOps = array('&', '|', '^', '!');
     if (is_array($cond) && count($cond) >= 2 && in_array($cond[0], $validOps)) {
         # Recursive condition
         if ($cond[0] == '&') {
             // AND (all conds pass)
             foreach (array_slice($cond, 1) as $subcond) {
                 if (!self::recCheckCondition($subcond, $user)) {
                     return false;
                 }
             }
             return true;
         } elseif ($cond[0] == '|') {
             // OR (at least one cond passes)
             foreach (array_slice($cond, 1) as $subcond) {
                 if (self::recCheckCondition($subcond, $user)) {
                     return true;
                 }
             }
             return false;
         } elseif ($cond[0] == '^') {
             // XOR (exactly one cond passes)
             if (count($cond) > 3) {
                 wfWarn('recCheckCondition() given XOR ("^") condition on three or more conditions. Check your $wgAutopromote and $wgAutopromoteOnce settings.');
             }
             return self::recCheckCondition($cond[1], $user) xor self::recCheckCondition($cond[2], $user);
         } elseif ($cond[0] == '!') {
             // NOT (no conds pass)
             foreach (array_slice($cond, 1) as $subcond) {
                 if (self::recCheckCondition($subcond, $user)) {
                     return false;
                 }
             }
             return true;
         }
     }
     # If we got here, the array presumably does not contain other condi-
     # tions; it's not recursive.  Pass it off to self::checkCondition.
     if (!is_array($cond)) {
         $cond = array($cond);
     }
     return self::checkCondition($cond, $user);
 }
コード例 #26
0
ファイル: MWTidy.php プロジェクト: whysasse/kmwiki
 /**
  * Use the HTML tidy extension to use the tidy library in-process,
  * saving the overhead of spawning a new process.
  *
  * @param string $text HTML to check
  * @param bool $stderr Whether to read result from error status instead of output
  * @param int &$retval Exit code (-1 on internal error)
  * @return string|null
  */
 private static function execInternalTidy($text, $stderr = false, &$retval = null)
 {
     global $wgTidyConf, $wgDebugTidy;
     wfProfileIn(__METHOD__);
     if (!class_exists('tidy')) {
         wfWarn("Unable to load internal tidy class.");
         $retval = -1;
         wfProfileOut(__METHOD__);
         return null;
     }
     $tidy = new tidy();
     $tidy->parseString($text, $wgTidyConf, 'utf8');
     if ($stderr) {
         $retval = $tidy->getStatus();
         wfProfileOut(__METHOD__);
         return $tidy->errorBuffer;
     }
     $tidy->cleanRepair();
     $retval = $tidy->getStatus();
     if ($retval == 2) {
         // 2 is magic number for fatal error
         // http://www.php.net/manual/en/function.tidy-get-status.php
         $cleansource = null;
     } else {
         $cleansource = tidy_get_output($tidy);
         if ($wgDebugTidy && $retval > 0) {
             $cleansource .= "<!--\nTidy reports:\n" . str_replace('-->', '--&gt;', $tidy->errorBuffer) . "\n-->";
         }
     }
     wfProfileOut(__METHOD__);
     return $cleansource;
 }
コード例 #27
0
ファイル: Setup.php プロジェクト: paladox/mediawiki
unset($serverParts);
// Set defaults for configuration variables
// that are derived from the server name by default
// Note: $wgEmergencyContact and $wgPasswordSender may be false or empty string (T104142)
if (!$wgEmergencyContact) {
    $wgEmergencyContact = 'wikiadmin@' . $wgServerName;
}
if (!$wgPasswordSender) {
    $wgPasswordSender = 'apache@' . $wgServerName;
}
if (!$wgNoReplyAddress) {
    $wgNoReplyAddress = $wgPasswordSender;
}
if ($wgSecureLogin && substr($wgServer, 0, 2) !== '//') {
    $wgSecureLogin = false;
    wfWarn('Secure login was enabled on a server that only supports ' . 'HTTP or HTTPS. Disabling secure login.');
}
$wgVirtualRestConfig['global']['domain'] = $wgCanonicalServer;
// Now that GlobalFunctions is loaded, set defaults that depend on it.
if ($wgTmpDirectory === false) {
    $wgTmpDirectory = wfTempDir();
}
// We don't use counters anymore. Left here for extensions still
// expecting this to exist. Should be removed sometime 1.26 or later.
if (!isset($wgDisableCounters)) {
    $wgDisableCounters = true;
}
if ($wgMainWANCache === false) {
    // Setup a WAN cache from $wgMainCacheType with no relayer.
    // Sites using multiple datacenters can configure a relayer.
    $wgMainWANCache = 'mediawiki-main-default';
コード例 #28
0
 /**
  * Coalesce consecutive changes by the same user to the same entity into one.
  * A run of changes may be broken if the action performed changes (e.g. deletion
  * instead of update) or if a sitelink pointing to the local wiki was modified.
  *
  * Some types of actions, like deletion, will break runs.
  * Interleaved changes to different items will break runs.
  *
  * @param EntityChange[] $changes
  *
  * @return EntityChange[] grouped changes
  */
 private function coalesceRuns(array $changes)
 {
     $coalesced = array();
     $currentRun = array();
     $currentUser = null;
     $currentEntity = null;
     $currentAction = null;
     $breakNext = false;
     foreach ($changes as $change) {
         try {
             $action = $change->getAction();
             $meta = $change->getMetadata();
             $user = $meta['user_text'];
             $entityId = $change->getEntityId()->__toString();
             $break = $breakNext || $currentAction !== $action || $currentUser !== $user || $currentEntity !== $entityId;
             $breakNext = false;
             if (!$break && $change instanceof ItemChange) {
                 $siteLinkDiff = $change->getSiteLinkDiff();
                 if (isset($siteLinkDiff[$this->localSiteId])) {
                     // TODO: don't break if only the link's badges changed
                     $break = true;
                     $breakNext = true;
                 }
             }
             if ($break) {
                 if (!empty($currentRun)) {
                     try {
                         $coalesced[] = $this->mergeChanges($currentRun);
                     } catch (MWException $ex) {
                         // Something went wrong while trying to merge the changes.
                         // Just keep the original run.
                         wfWarn($ex->getMessage());
                         $coalesced = array_merge($coalesced, $currentRun);
                     }
                 }
                 $currentRun = array();
                 $currentUser = $user;
                 $currentEntity = $entityId;
                 $currentAction = $action === EntityChange::ADD ? EntityChange::UPDATE : $action;
             }
             $currentRun[] = $change;
             // skip any change that failed to process in some way (bug T51417)
         } catch (Exception $ex) {
             wfLogWarning(__METHOD__ . ':' . $ex->getMessage());
         }
     }
     if (!empty($currentRun)) {
         try {
             $coalesced[] = $this->mergeChanges($currentRun);
         } catch (MWException $ex) {
             // Something went wrong while trying to merge the changes.
             // Just keep the original run.
             wfWarn($ex->getMessage());
             $coalesced = array_merge($coalesced, $currentRun);
         }
     }
     return $coalesced;
 }
コード例 #29
0
ファイル: Linker.php プロジェクト: paladox/2
 /**
  * Make a "broken" link to an image
  *
  * @param Title $title
  * @param string $label Link label (plain text)
  * @param string $query Query string
  * @param string $unused1 Unused parameter kept for b/c
  * @param string $unused2 Unused parameter kept for b/c
  * @param bool $time A file of a certain timestamp was requested
  * @return string
  */
 public static function makeBrokenImageLinkObj($title, $label = '', $query = '', $unused1 = '', $unused2 = '', $time = false)
 {
     if (!$title instanceof Title) {
         wfWarn(__METHOD__ . ': Requires $title to be a Title object.');
         return "<!-- ERROR -->" . htmlspecialchars($label);
     }
     global $wgEnableUploads, $wgUploadMissingFileUrl, $wgUploadNavigationUrl;
     if ($label == '') {
         $label = $title->getPrefixedText();
     }
     $encLabel = htmlspecialchars($label);
     $currentExists = $time ? wfFindFile($title) != false : false;
     if (($wgUploadMissingFileUrl || $wgUploadNavigationUrl || $wgEnableUploads) && !$currentExists) {
         $redir = RepoGroup::singleton()->getLocalRepo()->checkRedirect($title);
         if ($redir) {
             return self::linkKnown($title, $encLabel, array(), wfCgiToArray($query));
         }
         $href = self::getUploadUrl($title, $query);
         return '<a href="' . htmlspecialchars($href) . '" class="new" title="' . htmlspecialchars($title->getPrefixedText(), ENT_QUOTES) . '">' . $encLabel . '</a>';
     }
     return self::linkKnown($title, $encLabel, array(), wfCgiToArray($query));
 }
コード例 #30
0
 /**
  * Get URLs for icons if available.
  * @param MessageGroup $g
  * @param int $size Length of the edge of a bounding box to fit the icon.
  * @return null|array
  * @since 2013-04-01
  */
 public static function getIcon(MessageGroup $g, $size)
 {
     $icon = $g->getIcon();
     if (substr($icon, 0, 7) !== 'wiki://') {
         return null;
     }
     $formats = array();
     $filename = substr($icon, 7);
     $file = wfFindFile($filename);
     if (!$file) {
         wfWarn("Unknown message group icon file {$icon}");
         return null;
     }
     if ($file->isVectorized()) {
         $formats['vector'] = $file->getFullUrl();
     }
     $formats['raster'] = $file->createThumb($size, $size);
     return $formats;
 }