/**
  * @param ResourceLoaderContext $context
  * @return array
  */
 protected function getConfig($context)
 {
     $hash = $context->getHash();
     if (isset($this->configVars[$hash])) {
         return $this->configVars[$hash];
     }
     global $wgLoadScript, $wgScript, $wgStylePath, $wgScriptExtension, $wgArticlePath, $wgScriptPath, $wgServer, $wgContLang, $wgVariantArticlePath, $wgActionPaths, $wgVersion, $wgEnableAPI, $wgEnableWriteAPI, $wgDBname, $wgSitename, $wgFileExtensions, $wgExtensionAssetsPath, $wgCookiePrefix, $wgResourceLoaderMaxQueryLength, $wgResourceLoaderStorageEnabled, $wgResourceLoaderStorageVersion, $wgSearchType;
     $mainPage = Title::newMainPage();
     /**
      * Namespace related preparation
      * - wgNamespaceIds: Key-value pairs of all localized, canonical and aliases for namespaces.
      * - wgCaseSensitiveNamespaces: Array of namespaces that are case-sensitive.
      */
     $namespaceIds = $wgContLang->getNamespaceIds();
     $caseSensitiveNamespaces = array();
     foreach (MWNamespace::getCanonicalNamespaces() as $index => $name) {
         $namespaceIds[$wgContLang->lc($name)] = $index;
         if (!MWNamespace::isCapitalized($index)) {
             $caseSensitiveNamespaces[] = $index;
         }
     }
     // Build list of variables
     $vars = array('wgLoadScript' => $wgLoadScript, 'debug' => $context->getDebug(), 'skin' => $context->getSkin(), 'stylepath' => $wgStylePath, 'wgUrlProtocols' => wfUrlProtocols(), 'wgArticlePath' => $wgArticlePath, 'wgScriptPath' => $wgScriptPath, 'wgScriptExtension' => $wgScriptExtension, 'wgScript' => $wgScript, 'wgSearchType' => $wgSearchType, 'wgVariantArticlePath' => $wgVariantArticlePath, 'wgActionPaths' => (object) $wgActionPaths, 'wgServer' => $wgServer, 'wgUserLanguage' => $context->getLanguage(), 'wgContentLanguage' => $wgContLang->getCode(), 'wgVersion' => $wgVersion, 'wgEnableAPI' => $wgEnableAPI, 'wgEnableWriteAPI' => $wgEnableWriteAPI, 'wgMainPageTitle' => $mainPage->getPrefixedText(), 'wgFormattedNamespaces' => $wgContLang->getFormattedNamespaces(), 'wgNamespaceIds' => $namespaceIds, 'wgContentNamespaces' => MWNamespace::getContentNamespaces(), 'wgSiteName' => $wgSitename, 'wgFileExtensions' => array_values(array_unique($wgFileExtensions)), 'wgDBname' => $wgDBname, 'wgFileCanRotate' => BitmapHandler::canRotate(), 'wgAvailableSkins' => Skin::getSkinNames(), 'wgExtensionAssetsPath' => $wgExtensionAssetsPath, 'wgCookiePrefix' => $wgCookiePrefix, 'wgResourceLoaderMaxQueryLength' => $wgResourceLoaderMaxQueryLength, 'wgCaseSensitiveNamespaces' => $caseSensitiveNamespaces, 'wgLegalTitleChars' => Title::convertByteClassToUnicodeClass(Title::legalChars()), 'wgResourceLoaderStorageVersion' => $wgResourceLoaderStorageVersion, 'wgResourceLoaderStorageEnabled' => $wgResourceLoaderStorageEnabled);
     wfRunHooks('ResourceLoaderGetConfigVars', array(&$vars));
     $this->configVars[$hash] = $vars;
     return $this->configVars[$hash];
 }
	public function readFromVariable( $data ) {
		# Authors first
		$matches = array();
		preg_match_all( '/^ \* @author\s+(.+)$/m', $data, $matches );
		$authors = $matches[1];

		# Then messages
		$matches = array();
		$regex = '/^\$(.*?)\s*=\s*[\'"](.*?)[\'"];.*?$/mus';
		preg_match_all( $regex, $data, $matches, PREG_SET_ORDER );
		$messages = array();

		foreach ( $matches as $_ ) {
			$legal = Title::legalChars();
			$key = preg_replace( "/([^$legal]|\\\\)/ue", '\'\x\'.' . "dechex(ord('\\0'))", $_[1] );
			$value = str_replace( array( "\'", "\\\\" ), array( "'", "\\" ), $_[2] );
			$messages[$key] = $value;
		}

		$messages = $this->group->getMangler()->mangle( $messages );

		return array(
			'AUTHORS' => $authors,
			'MESSAGES' => $messages,
		);
	}
 /**
  * @param ResourceLoaderContext $context
  * @return array
  */
 protected function getConfigSettings($context)
 {
     $hash = $context->getHash();
     if (isset($this->configVars[$hash])) {
         return $this->configVars[$hash];
     }
     global $wgContLang;
     $mainPage = Title::newMainPage();
     /**
      * Namespace related preparation
      * - wgNamespaceIds: Key-value pairs of all localized, canonical and aliases for namespaces.
      * - wgCaseSensitiveNamespaces: Array of namespaces that are case-sensitive.
      */
     $namespaceIds = $wgContLang->getNamespaceIds();
     $caseSensitiveNamespaces = array();
     foreach (MWNamespace::getCanonicalNamespaces() as $index => $name) {
         $namespaceIds[$wgContLang->lc($name)] = $index;
         if (!MWNamespace::isCapitalized($index)) {
             $caseSensitiveNamespaces[] = $index;
         }
     }
     $conf = $this->getConfig();
     // Build list of variables
     $vars = array('wgLoadScript' => wfScript('load'), 'debug' => $context->getDebug(), 'skin' => $context->getSkin(), 'stylepath' => $conf->get('StylePath'), 'wgUrlProtocols' => wfUrlProtocols(), 'wgArticlePath' => $conf->get('ArticlePath'), 'wgScriptPath' => $conf->get('ScriptPath'), 'wgScriptExtension' => '.php', 'wgScript' => wfScript(), 'wgSearchType' => $conf->get('SearchType'), 'wgVariantArticlePath' => $conf->get('VariantArticlePath'), 'wgActionPaths' => (object) $conf->get('ActionPaths'), 'wgServer' => $conf->get('Server'), 'wgServerName' => $conf->get('ServerName'), 'wgUserLanguage' => $context->getLanguage(), 'wgContentLanguage' => $wgContLang->getCode(), 'wgTranslateNumerals' => $conf->get('TranslateNumerals'), 'wgVersion' => $conf->get('Version'), 'wgEnableAPI' => $conf->get('EnableAPI'), 'wgEnableWriteAPI' => $conf->get('EnableWriteAPI'), 'wgMainPageTitle' => $mainPage->getPrefixedText(), 'wgFormattedNamespaces' => $wgContLang->getFormattedNamespaces(), 'wgNamespaceIds' => $namespaceIds, 'wgContentNamespaces' => MWNamespace::getContentNamespaces(), 'wgSiteName' => $conf->get('Sitename'), 'wgDBname' => $conf->get('DBname'), 'wgExtraSignatureNamespaces' => $conf->get('ExtraSignatureNamespaces'), 'wgAvailableSkins' => Skin::getSkinNames(), 'wgExtensionAssetsPath' => $conf->get('ExtensionAssetsPath'), 'wgCookiePrefix' => $conf->get('CookiePrefix'), 'wgCookieDomain' => $conf->get('CookieDomain'), 'wgCookiePath' => $conf->get('CookiePath'), 'wgCookieExpiration' => $conf->get('CookieExpiration'), 'wgResourceLoaderMaxQueryLength' => $conf->get('ResourceLoaderMaxQueryLength'), 'wgCaseSensitiveNamespaces' => $caseSensitiveNamespaces, 'wgLegalTitleChars' => Title::convertByteClassToUnicodeClass(Title::legalChars()), 'wgResourceLoaderStorageVersion' => $conf->get('ResourceLoaderStorageVersion'), 'wgResourceLoaderStorageEnabled' => $conf->get('ResourceLoaderStorageEnabled'), 'wgResourceLoaderLegacyModules' => self::getLegacyModules(), 'wgForeignUploadTargets' => $conf->get('ForeignUploadTargets'), 'wgEnableUploads' => $conf->get('EnableUploads'));
     Hooks::run('ResourceLoaderGetConfigVars', array(&$vars));
     $this->configVars[$hash] = $vars;
     return $this->configVars[$hash];
 }
 /**
  * Parse title and return article metadata
  * @param string $title
  * @return array article metadata (type, namespace, page_title, product, manual, topic, base_version)
  */
 public static function getArticleMetadataFromTitle($title)
 {
     $meta = array();
     if (preg_match('/^' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . ':(([' . PONYDOCS_PRODUCT_LEGALCHARS . ']*):([' . PONYDOCS_PRODUCTMANUAL_LEGALCHARS . ']*):([' . Title::legalChars() . ']*):([' . PONYDOCS_PRODUCTVERSION_LEGALCHARS . ']*))/i', $title, $match)) {
         // matched topic regex
         $meta['type'] = self::ARTICLE_TYPE_TOPIC;
         $meta['namespace'] = PONYDOCS_DOCUMENTATION_NAMESPACE_NAME;
         $meta['title'] = $title;
         $meta['page_title'] = $match[1];
         $meta['product'] = $match[2];
         $meta['manual'] = $match[3];
         $meta['topic'] = $match[4];
         $meta['base_version'] = $match[5];
     } elseif (preg_match('/' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . ':(([' . PONYDOCS_PRODUCT_LEGALCHARS . ']*):([' . PONYDOCS_PRODUCTMANUAL_LEGALCHARS . ']*)TOC([' . PONYDOCS_PRODUCTVERSION_LEGALCHARS . ']*))/i', $title, $match)) {
         // matched TOC regex
         $meta['type'] = self::ARTICLE_TYPE_TOC;
         $meta['namespace'] = PONYDOCS_DOCUMENTATION_NAMESPACE_NAME;
         $meta['title'] = $title;
         $meta['page_title'] = $match[1];
         $meta['product'] = $match[2];
         $meta['manual'] = $match[3];
         $meta['base_version'] = $match[4];
     } else {
         // no match
         $meta['type'] = self::ARTICLE_TYPE_OTHER;
     }
     return $meta;
 }
	public function parseNext( $text, WikiObjectModelCollection $parentObj, $offset = 0 ) {
		$text = substr( $text, $offset );
		$r = preg_match( '/^(\{\{\{([^{|}]+))([|}])/', $text, $m );

		if ( $r ) {
			if ( !preg_match( '/[^' . Title::legalChars() . ']/', trim( $m[2] ) ) )
//			if(!preg_match(Title::getTitleInvalidRegex(), trim($m[2])))
				return array( 'len' => ( $m[3] == '|' ) ? strlen( $m[0] ) : strlen( $m[1] ), 'obj' => new WOMTemplateFieldHolderModel( trim( $m[2] ) ) );
		}
		return null;
	}
 function testLegalChars()
 {
     $titlechars = Title::legalChars();
     foreach (range(1, 255) as $num) {
         $chr = chr($num);
         if (strpos("#[]{}<>|", $chr) !== false || preg_match("/[\\x00-\\x1f\\x7f]/", $chr)) {
             $this->assertFalse((bool) preg_match("/[{$titlechars}]/", $chr), "chr({$num}) = {$chr} is not a valid titlechar");
         } else {
             $this->assertTrue((bool) preg_match("/[{$titlechars}]/", $chr), "chr({$num}) = {$chr} is a valid titlechar");
         }
     }
 }
	/**
	 * Checks if the translation uses links that are discouraged. Valid links are
	 * those that link to Special: or {{ns:special}}: or project pages trough
	 * MediaWiki messages like {{MediaWiki:helppage-url}}:. Also links in the
	 * definition are allowed.
	 *
	 * @param $messages \array Iterable list of TMessage objects.
	 * @param $code \string Language code of the translations.
	 * @param $warnings \array Array where warnings are appended to.
	 */
	protected function wikiLinksCheck( $messages, $code, &$warnings ) {
		$tc = Title::legalChars() . '#%{}';

		foreach ( $messages as $message ) {
			$key = $message->key();
			$definition = $message->definition();
			$translation = $message->translation();

			$subcheck = 'extra';
			$matches = $links = array();
			preg_match_all( "/\[\[([{$tc}]+)(\\|(.+?))?]]/sDu", $translation, $matches );
			for ( $i = 0; $i < count( $matches[0] ); $i++ ) {
				$backMatch = preg_quote( $matches[1][$i], '/' );

				if ( preg_match( "/\[\[$backMatch/", $definition ) ) {
					continue;
				}

				$links[] = "[[{$matches[1][$i]}{$matches[2][$i]}]]";
			}

			if ( count( $links ) ) {
				$warnings[$key][] = array(
					array( 'links', $subcheck, $key, $code ),
					'translate-checks-links',
					array( 'PARAMS', $links ),
					array( 'COUNT', count( $links ) ),
				);
			}

			$subcheck = 'missing';
			$matches = $links = array();
			preg_match_all( "/\[\[([{$tc}]+)(\\|(.+?))?]]/sDu", $definition, $matches );
			for ( $i = 0; $i < count( $matches[0] ); $i++ ) {
				$backMatch = preg_quote( $matches[1][$i], '/' );

				if ( preg_match( "/\[\[$backMatch/", $translation ) ) {
					continue;
				}

				$links[] = "[[{$matches[1][$i]}{$matches[2][$i]}]]";
			}

			if ( count( $links ) ) {
				$warnings[$key][] = array(
					array( 'links', $subcheck, $key, $code ),
					'translate-checks-links-missing',
					array( 'PARAMS', $links ),
					array( 'COUNT', count( $links ) ),
				);
			}
		}
	}
Example #8
0
 /**
  * Returns a simple regex that will match on characters and sequences invalid in titles.
  * Note that this doesn't pick up many things that could be wrong with titles, but that
  * replacing this regex with something valid will make many titles valid.
  *
  * @return String regex string
  */
 static function getTitleInvalidRegex()
 {
     static $rxTc = false;
     if (!$rxTc) {
         # Matching titles will be held as illegal.
         $rxTc = '/' . '[^' . Title::legalChars() . ']' . '|%[0-9A-Fa-f]{2}' . '|&[A-Za-z0-9\\x80-\\xff]+;' . '|&#[0-9]+;' . '|&#x[0-9A-Fa-f]+;' . '/S';
     }
     return $rxTc;
 }
Example #9
0
 /**
  * Secure and split - main initialisation function for this object
  *
  * Assumes that mDbkeyform has been set, and is urldecoded
  * and uses underscores, but not otherwise munged.  This function
  * removes illegal characters, splits off the interwiki and
  * namespace prefixes, sets the other forms, and canonicalizes
  * everything.
  * @return bool true on success
  */
 private function secureAndSplit()
 {
     global $wgContLang, $wgLocalInterwiki, $wgCapitalLinks;
     # Initialisation
     static $rxTc = false;
     if (!$rxTc) {
         # Matching titles will be held as illegal.
         $rxTc = '/' . '[^' . Title::legalChars() . ']' . '|%[0-9A-Fa-f]{2}' . '|&[A-Za-z0-9\\x80-\\xff]+;' . '|&#[0-9]+;' . '|&#x[0-9A-Fa-f]+;' . '/S';
     }
     $this->mInterwiki = $this->mFragment = '';
     $this->mNamespace = $this->mDefaultNamespace;
     # Usually NS_MAIN
     $dbkey = $this->mDbkeyform;
     # Strip Unicode bidi override characters.
     # Sometimes they slip into cut-n-pasted page titles, where the
     # override chars get included in list displays.
     $dbkey = str_replace("‎", '', $dbkey);
     // 200E LEFT-TO-RIGHT MARK
     $dbkey = str_replace("‏", '', $dbkey);
     // 200F RIGHT-TO-LEFT MARK
     # Clean up whitespace
     #
     // XXCHANGED don't replace _ with - screws up namespaces
     $dbkey = preg_replace('/[ ]+/', '-', $this->mDbkeyform);
     $dbkey = trim($dbkey, '-');
     if ('' == $dbkey) {
         return false;
     }
     if (false !== strpos($dbkey, UTF8_REPLACEMENT)) {
         # Contained illegal UTF-8 sequences or forbidden Unicode chars.
         return false;
     }
     $this->mDbkeyform = $dbkey;
     # Initial colon indicates main namespace rather than specified default
     # but should not create invalid {ns,title} pairs such as {0,Project:Foo}
     if (':' == $dbkey[0]) {
         $this->mNamespace = NS_MAIN;
         $dbkey = substr($dbkey, 1);
         # remove the colon but continue processing
         $dbkey = trim($dbkey, '-');
         # remove any subsequent whitespace
     }
     # Namespace or interwiki prefix
     $firstPass = true;
     do {
         $m = array();
         if (preg_match("/^(.+?)_*:_*(.*)\$/S", $dbkey, $m)) {
             $p = $m[1];
             if ($ns = $wgContLang->getNsIndex($p)) {
                 # Ordinary namespace
                 $dbkey = $m[2];
                 $this->mNamespace = $ns;
             } elseif ($this->getInterwikiLink($p)) {
                 if (!$firstPass) {
                     # Can't make a local interwiki link to an interwiki link.
                     # That's just crazy!
                     return false;
                 }
                 # Interwiki link
                 $dbkey = $m[2];
                 $this->mInterwiki = $wgContLang->lc($p);
                 # Redundant interwiki prefix to the local wiki
                 if (0 == strcasecmp($this->mInterwiki, $wgLocalInterwiki)) {
                     if ($dbkey == '') {
                         # Can't have an empty self-link
                         return false;
                     }
                     $this->mInterwiki = '';
                     $firstPass = false;
                     # Do another namespace split...
                     continue;
                 }
                 # If there's an initial colon after the interwiki, that also
                 # resets the default namespace
                 if ($dbkey !== '' && $dbkey[0] == ':') {
                     $this->mNamespace = NS_MAIN;
                     $dbkey = substr($dbkey, 1);
                 }
             }
             # If there's no recognized interwiki or namespace,
             # then let the colon expression be part of the title.
         }
         break;
     } while (true);
     # We already know that some pages won't be in the database!
     #
     if ('' != $this->mInterwiki || NS_SPECIAL == $this->mNamespace) {
         $this->mArticleID = 0;
     }
     $fragment = strstr($dbkey, '#');
     if (false !== $fragment) {
         $this->setFragment($fragment);
         $dbkey = substr($dbkey, 0, strlen($dbkey) - strlen($fragment));
         # remove whitespace again: prevents "Foo_bar_#"
         # becoming "Foo_bar_"
         $dbkey = preg_replace('/_*$/', '', $dbkey);
     }
     # Reject illegal characters.
     #
     if (preg_match($rxTc, $dbkey)) {
         return false;
     }
     /**
      * Pages with "/./" or "/../" appearing in the URLs will
      * often be unreachable due to the way web browsers deal
      * with 'relative' URLs. Forbid them explicitly.
      */
     if (strpos($dbkey, '.') !== false && ($dbkey === '.' || $dbkey === '..' || strpos($dbkey, './') === 0 || strpos($dbkey, '../') === 0 || strpos($dbkey, '/./') !== false || strpos($dbkey, '/../') !== false || substr($dbkey, -2) == '/.' || substr($dbkey, -3) == '/..')) {
         return false;
     }
     /**
      * Magic tilde sequences? Nu-uh!
      */
     if (strpos($dbkey, '~~~') !== false) {
         return false;
     }
     /**
      * Limit the size of titles to 255 bytes.
      * This is typically the size of the underlying database field.
      * We make an exception for special pages, which don't need to be stored
      * in the database, and may edge over 255 bytes due to subpage syntax 
      * for long titles, e.g. [[Special:Block/Long name]]
      */
     if ($this->mNamespace != NS_SPECIAL && strlen($dbkey) > 255 || strlen($dbkey) > 512) {
         return false;
     }
     /**
      * Normally, all wiki links are forced to have
      * an initial capital letter so [[foo]] and [[Foo]]
      * point to the same place.
      *
      * Don't force it for interwikis, since the other
      * site might be case-sensitive.
      */
     $this->mUserCaseDBKey = $dbkey;
     // INTL: By default, capitalize first letter of titles with namespace of NS_MEDIAWIKI.  A little bit of a hack
     // to get around the fact that we set wgCapitalLinks to false to international sites.  We do this because not all
     // languages capitalize the first letter of a title
     if ($this->mNamespace == NS_MEDIAWIKI || $wgCapitalLinks && $this->mInterwiki == '') {
         $dbkey = $wgContLang->ucfirst($dbkey);
     }
     /**
      * Can't make a link to a namespace alone...
      * "empty" local links can only be self-links
      * with a fragment identifier.
      */
     if ($dbkey == '' && $this->mInterwiki == '' && $this->mNamespace != NS_MAIN) {
         return false;
     }
     // Allow IPv6 usernames to start with '::' by canonicalizing IPv6 titles.
     // IP names are not allowed for accounts, and can only be referring to
     // edits from the IP. Given '::' abbreviations and caps/lowercaps,
     // there are numerous ways to present the same IP. Having sp:contribs scan
     // them all is silly and having some show the edits and others not is
     // inconsistent. Same for talk/userpages. Keep them normalized instead.
     $dbkey = $this->mNamespace == NS_USER || $this->mNamespace == NS_USER_TALK ? IP::sanitizeIP($dbkey) : $dbkey;
     // Any remaining initial :s are illegal.
     if ($dbkey !== '' && ':' == $dbkey[0]) {
         return false;
     }
     # Fill fields
     $this->mDbkeyform = $dbkey;
     $this->mUrlform = wfUrlencode($dbkey);
     //XXCHANGED
     $this->mTextform = str_replace('-', ' ', $dbkey);
     return true;
 }
function wfIFI_handleUpload($f, $import)
{
    global $wgRequest, $wgUser, $wgOut, $wgTmpDirectory;
    global $wgIFI_GetOriginal, $wgIFI_CreditsTemplate, $wgIFI_AppendRandomNumber;
    # Check token, to preven Cross Site Request Forgeries
    $token = $wgRequest->getVal('token');
    if (!$wgUser->matchEditToken($token)) {
        $wgOut->addWikitext(wfMsg('sessionfailure'));
        return false;
    }
    $id = $wgRequest->getVal('id');
    $ititle = $wgRequest->getVal('ititle');
    $owner = $wgRequest->getVal('owner');
    $name = $wgRequest->getVal('name');
    if ($wgIFI_GetOriginal) {
        // get URL of original :1
        $sizes = $f->photos_getSizes($id);
        $original = '';
        foreach ($sizes as $size) {
            if ($size['label'] == 'Original') {
                $original = $size['source'];
                $import = $size['source'];
            } else {
                if ($size['label'] == 'Large') {
                    $large = $size['source'];
                }
            }
        }
        //somtimes Large is returned but no Original!
        if ($original == '' && $large != '') {
            $import = $large;
        }
    }
    if (!preg_match('/^http:\\/\\/farm[0-9]+\\.static\\.flickr\\.com\\/.*\\.(jpg|gif|png)$/', $import, $matches)) {
        $wgOut->showErrorPage('error', 'importfreeimages_invalidurl', array(wfEscapeWikiText($import)));
        return true;
    }
    $fileext = '.' . $matches[1];
    // store the contents of the file
    $pageContents = file_get_contents($import);
    $tempname = tempnam($wgTmpDirectory, 'flickr');
    $r = fopen($tempname, 'wb');
    if ($r === FALSE) {
        # Could not open temporary file to write in
        $wgOut->errorPage('upload-file-error', 'upload-file-error-text');
        return true;
    }
    $size = fwrite($r, $pageContents);
    fclose($r);
    $info = $f->photos_getInfo($id);
    $name_wiki = wfEscapeWikiText($name);
    if (!empty($wgIFI_CreditsTemplate)) {
        $owner_wiki = wfEscapeWikiText($owner);
        $id_wiki = wfEscapeWikiText($id);
        $caption = "{{" . $wgIFI_CreditsTemplate . intval($info['license']) . "|1={$id_wiki}|2={$owner_wiki}|3={$name_wiki}}}";
    } else {
        // TODO: this is totally wrong: The whole message should be configurable, we shouldn't include arbitrary templates
        // additionally, the license information is not correct (we are not guaranteed to get "CC by 2.0" images only)
        $caption = wfMsgForContent('importfreeimages_filefromflickr', $ititle, "http://www.flickr.com/people/" . urlencode($owner) . " " . $name_wiki) . " <nowiki>{$import}</nowiki>. {{CC by 2.0}} ";
        $caption = trim($caption);
    }
    if (!class_exists("UploadForm")) {
        require_once 'includes/SpecialUpload.php';
    }
    $u = new UploadForm($wgRequest);
    // TODO: we should use FauxRequest here instead of accessing member variables.
    // But FauxRequest doesn't yet allow us to pass files around
    $u->mTempPath = $tempname;
    $u->mFileSize = $size;
    $u->mComment = $caption;
    $u->mRemoveTempFile = true;
    $u->mIgnoreWarning = true;
    $filename = $ititle . ($wgIFI_AppendRandomNumber ? "-" . rand(0, 9999) : "") . $fileext;
    $filename = preg_replace('/ +/', ' ', $filename);
    /**
     * Filter out illegal characters, and try to make a legible name
     * out of it. We'll strip some silently that Title would die on.
     * This is taken from SpecialUpload::internalProcessUploads()
     */
    $filename = preg_replace("/[^" . Title::legalChars() . "]|:/", '-', $filename);
    $nt = Title::makeTitleSafe(NS_IMAGE, $filename);
    if (is_null($nt)) {
        $wgOut->showErrorPage('error', 'illegalfilename', array(wfEscapeWikiText($filename)));
        return false;
    }
    $u->mSrcName = $filename;
    if ($nt->getArticleID() > 0) {
        $sk = $wgUser->getSkin();
        $dlink = $sk->makeKnownLinkObj($t);
        $warning = '<li>' . wfMsgExt('fileexists', '', $dlink) . '</li>';
        // use our own upload warning as we dont have a 'reupload' feature
        wfIFI_uploadWarning($u, $warning);
        return true;
    } elseif (!$nt->userCan('create')) {
        $wgOut->showPermissionsErrorPage($nt->getUserPermissionsErrors('create', $wgUser));
        return false;
    } else {
        $u->execute();
        return true;
    }
}
Example #11
0
/**
 * Replace all invalid characters with '-'.
 * Additional characters can be defined in $wgIllegalFileChars (see T22489).
 * By default, $wgIllegalFileChars includes ':', '/', '\'.
 *
 * @param string $name Filename to process
 * @return string
 */
function wfStripIllegalFilenameChars($name)
{
    global $wgIllegalFileChars;
    $illegalFileChars = $wgIllegalFileChars ? "|[" . $wgIllegalFileChars . "]" : '';
    $name = preg_replace("/[^" . Title::legalChars() . "]" . $illegalFileChars . "/", '-', $name);
    // $wgIllegalFileChars may not include '/' and '\', so we still need to do this
    $name = wfBaseName($name);
    return $name;
}
 /**
  * Really do the upload
  * Checks are made in SpecialUpload::execute()
  * @access private
  */
 function processUpload()
 {
     global $wgUser, $wgOut, $wgLang, $wgContLang;
     global $wgUploadDirectory;
     global $wgUseCopyrightUpload, $wgCheckCopyrightUpload;
     /**
      * If there was no filename or a zero size given, give up quick.
      */
     if (trim($this->mOname) == '' || empty($this->mUploadSize)) {
         return $this->mainUploadForm('<li>' . wfMsg('emptyfile') . '</li>');
     }
     # Chop off any directories in the given filename
     if ($this->mDestFile) {
         $basename = basename($this->mDestFile);
     } else {
         $basename = basename($this->mOname);
     }
     /**
      * We'll want to blacklist against *any* 'extension', and use
      * only the final one for the whitelist.
      */
     list($partname, $ext) = $this->splitExtensions($basename);
     if (count($ext)) {
         $finalExt = $ext[count($ext) - 1];
     } else {
         $finalExt = '';
     }
     $fullExt = implode('.', $ext);
     if (strlen($partname) < 3) {
         $this->mainUploadForm(wfMsg('minlength'));
         return;
     }
     /**
      * Filter out illegal characters, and try to make a legible name
      * out of it. We'll strip some silently that Title would die on.
      */
     $filtered = preg_replace("/[^" . Title::legalChars() . "]|:/", '-', $basename);
     $nt = Title::newFromText($filtered);
     if (is_null($nt)) {
         return $this->uploadError(wfMsg('illegalfilename', htmlspecialchars($filtered)));
     }
     $nt =& Title::makeTitle(NS_IMAGE, $nt->getDBkey());
     $this->mUploadSaveName = $nt->getDBkey();
     /**
      * If the image is protected, non-sysop users won't be able
      * to modify it by uploading a new revision.
      */
     if (!$nt->userCanEdit()) {
         return $this->uploadError(wfMsg('protectedpage'));
     }
     /* Don't allow users to override the blacklist (check file extension) */
     global $wgStrictFileExtensions;
     global $wgFileExtensions, $wgFileBlacklist;
     if ($this->checkFileExtensionList($ext, $wgFileBlacklist) || $wgStrictFileExtensions && !$this->checkFileExtension($finalExt, $wgFileExtensions)) {
         return $this->uploadError(wfMsg('badfiletype', htmlspecialchars($fullExt)));
     }
     /**
      * Look at the contents of the file; if we can recognize the
      * type but it's corrupt or data of the wrong type, we should
      * probably not accept it.
      */
     if (!$this->mStashed) {
         $veri = $this->verify($this->mUploadTempName, $finalExt);
         if ($veri !== true) {
             //it's a wiki error...
             return $this->uploadError($veri->toString());
         }
     }
     /**
      * Check for non-fatal conditions
      */
     if (!$this->mIgnoreWarning) {
         $warning = '';
         if ($this->mUploadSaveName != ucfirst($filtered)) {
             $warning .= '<li>' . wfMsg('badfilename', htmlspecialchars($this->mUploadSaveName)) . '</li>';
         }
         global $wgCheckFileExtensions;
         if ($wgCheckFileExtensions) {
             if (!$this->checkFileExtension($finalExt, $wgFileExtensions)) {
                 $warning .= '<li>' . wfMsg('badfiletype', htmlspecialchars($fullExt)) . '</li>';
             }
         }
         global $wgUploadSizeWarning;
         if ($wgUploadSizeWarning && $this->mUploadSize > $wgUploadSizeWarning) {
             # TODO: Format $wgUploadSizeWarning to something that looks better than the raw byte
             # value, perhaps add GB,MB and KB suffixes?
             $warning .= '<li>' . wfMsg('largefile', $wgUploadSizeWarning, $this->mUploadSize) . '</li>';
         }
         if ($this->mUploadSize == 0) {
             $warning .= '<li>' . wfMsg('emptyfile') . '</li>';
         }
         if ($nt->getArticleID()) {
             global $wgUser;
             $sk = $wgUser->getSkin();
             $dlink = $sk->makeKnownLinkObj($nt);
             $warning .= '<li>' . wfMsg('fileexists', $dlink) . '</li>';
         }
         if ($warning != '') {
             /**
              * Stash the file in a temporary location; the user can choose
              * to let it through and we'll complete the upload then.
              */
             return $this->uploadWarning($warning);
         }
     }
     /**
      * Try actually saving the thing...
      * It will show an error form on failure.
      */
     if ($this->saveUploadedFile($this->mUploadSaveName, $this->mUploadTempName, !empty($this->mSessionKey))) {
         /**
          * Update the upload log and create the description page
          * if it's a new file.
          */
         $img = Image::newFromName($this->mUploadSaveName);
         $success = $img->recordUpload($this->mUploadOldVersion, $this->mUploadDescription, $this->mUploadCopyStatus, $this->mUploadSource);
         if ($success) {
             $this->showSuccess();
         } else {
             // Image::recordUpload() fails if the image went missing, which is
             // unlikely, hence the lack of a specialised message
             $wgOut->fileNotFoundError($this->mUploadSaveName);
         }
     }
 }
 /** I BORROWED THIS FUNCTION FROM SpecialUpload.php!! CHECK FOR EACH VERSION OF MEDIAWIKI, IF
  *  THIS FUNCTION STILL MAKES SENSE!
  *
  */
 function processUpload()
 {
     global $wgUser, $wgUploadDirectory, $wgRequest;
     $fname = "AnyWikiDraw_body::processUpload";
     // Retrieve form fields
     $drawingName = $wgRequest->getText('DrawingName');
     $drawingWidth = $wgRequest->getText('DrawingWidth');
     $drawingHeight = $wgRequest->getText('DrawingHeight');
     $drawingTempFile = $wgRequest->getFileTempName('DrawingData');
     $drawingFileSize = $wgRequest->getFileSize('DrawingData');
     $drawingUploadError = $wgRequest->getUploadError('DrawingData');
     $renderedTempFile = $wgRequest->getFileTempName('RenderedImageData');
     $renderedFileSize = $wgRequest->getFileSize('RenderedImageData');
     $renderedUploadError = $wgRequest->getUploadError('RenderedImageData');
     $imageMapTempFile = $wgRequest->getFileTempName('ImageMapData');
     $imageMapFileSize = $wgRequest->getFileSize('ImageMapData');
     $imageMapUploadError = $wgRequest->getUploadError('ImageMapData');
     $uploadSummary = $wgRequest->getText('UploadSummary');
     // validate image dimension
     if (!is_numeric($drawingWidth) || $drawingWidth < 1) {
         $drawingWidth = null;
     }
     if (!is_numeric($drawingHeight) || $drawingHeight < 1) {
         $drawingHeight = null;
     }
     # If there was no filename or no image data, give up quickly.
     if (strlen($drawingName) == 0 || $drawingFileSize == 0) {
         wfDebug('[client ' . $_SERVER["REMOTE_ADDR"] . ']' . '[user ' . $wgUser->getName() . '] ' . $fname . ' received bad request [DrawingName=' . $drawingName . ']' . '[fileSize(DrawingData)=' . $drawingFileSize . ']');
         header('HTTP/1.0 400 Bad Request');
         exit("\n\n" + '<html><body>DrawingName and DrawingData must be supplied.</body></html>');
     }
     // Verify filename
     # Chop off any directories in the given filename.
     $drawingName = wfBaseName($drawingName);
     $imageExtension = substr(strrchr($drawingName, '.'), 1);
     # Only allow filenames with known extensions
     $allowedExtensions = array('svg', 'svgz', 'png', 'jpg');
     if (!in_array($imageExtension, $allowedExtensions)) {
         wfDebug('[client ' . $_SERVER["REMOTE_ADDR"] . ']' . '[user ' . $wgUser->getName() . '] ' . $fname . ' Received bad image extension [DrawingName=' . $drawingName . ']');
         header('HTTP/1.0 400 Bad Request');
         exit("\n\n" + '<html><body>DrawingName must have one of the following extensions: ' . implode(',', $allowedExtensions) . '.</body></html>');
     }
     /**
      * Filter out illegal characters, and try to make a legible name
      * out of it. We'll strip some silently that Title would die on.
      */
     $filtered = preg_replace("/[^" . Title::legalChars() . "]|:/", '-', $drawingName);
     $nt = Title::newFromText($filtered);
     if (is_null($nt)) {
         wfDebug('[client ' . $_SERVER["REMOTE_ADDR"] . ']' . '[user ' . $wgUser->getName() . '] ' . $fname . ' Received bad image name [DrawingName=' . $drawingName . ']');
         header('HTTP/1.0 400 Bad Request');
         exit("\n\n" + '<html><body>DrawingName must contain legible characters only.</body></html>');
     }
     $nt =& Title::makeTitle(NS_IMAGE, $nt->getDBkey());
     $uploadSaveName = $nt->getDBkey();
     /**
      * If the image is protected, non-sysop users won't be able
      * to modify it by uploading a new revision.
      */
     if (!$nt->userCanEdit()) {
         wfDebug('[client ' . $_SERVER["REMOTE_ADDR"] . ']' . '[user ' . $wgUser->getName() . '] ' . $fname . ' image is protected [DrawingName=' . $drawingName . ']');
         header('HTTP/1.0 403 Forbidden');
         exit("\n\n" + '<html><body>You are not allowed to edit this image.</body></html>');
     }
     /**
      * In some cases we may forbid overwriting of existing files.
      */
     if (!$this->userCanOverwrite($uploadSaveName)) {
         wfDebug('[client ' . $_SERVER["REMOTE_ADDR"] . ']' . '[user ' . $wgUser->getName() . '] ' . $fname . ' image may not be overwritten [DrawingName=' . $drawingName . ']');
         header('HTTP/1.0 403 Forbidden');
         exit("\n\n" + '<html><body>You are not allowed to overwrite this image.</body></html>');
     }
     /** Check if the image directory is writeable, this is a common mistake */
     if (!is_writeable($wgUploadDirectory)) {
         header('HTTP/1.0 403 Forbidden');
         exit("\n\n" + '<html><body>The upload directory on the server is read only.</body></html>');
     }
     /**
      * Upload the file into the temp directory, so that we can scrutinize its content
      */
     $archive = wfImageArchiveDir($uploadSaveName, 'temp');
     /**
      * Look at the contents of the file; if we can recognize the
      * type but it's corrupt or data of the wrong type, we should
      * probably not accept it.
      */
     $veri = $this->verify($drawingTempFile, $imageExtension);
     if ($veri !== true) {
         wfDebug('[client ' . $_SERVER["REMOTE_ADDR"] . ']' . '[user ' . $wgUser->getName() . '] ' . $fname . ' image failed verification [DrawingName=' . $drawingName . '][DrawingTempFile=' . $drawingTempFile . ']');
         unlink($drawingTempFile);
         header('HTTP/1.0 400 Bad Request');
         exit("\n\n" + '<html><body>The image data is corrupt.</body></html>');
     }
     /**
      * Provide an opportunity for extensions to add further checks
      */
     $error = '';
     if (!wfRunHooks('UploadVerification', array($uploadSaveName, $drawingTempFile, &$error))) {
         wfDebug('[client ' . $_SERVER["REMOTE_ADDR"] . ']' . '[user ' . $wgUser->getName() . '] ' . $fname . ' image failed extended verification [DrawingName=' . $drawingName . ']');
         unlink($drawingTempFile);
         header('HTTP/1.0 400 Bad Request');
         exit("\n\n" + '<html><body>The image data does not match the image name extension.</body></html>');
     }
     /**
      * Try actually saving the thing...
      * It will show an error form on failure.
      */
     if ($this->saveUploadedFile($uploadSaveName, $drawingTempFile, true)) {
         /**
          * Update the upload log and create the description page
          * if it's a new file.
          */
         $img = Image::newFromName($uploadSaveName);
         if ($drawingWidth != null) {
             $img->width = $drawingWidth;
         }
         if ($drawingHeight != null) {
             $img->height = $drawingHeight;
         }
         $this->mUploadDescription = $uploadSummary;
         $success = $img->recordUpload($this->mUploadOldVersion, $this->mUploadDescription, $this->mLicense, $this->mUploadCopyStatus, $this->mUploadSource, $this->mWatchthis);
         /**
          * Save the rendered image, if one was provided
          */
         if ($renderedTempFile != null && $drawingWidth != null) {
             $thumbName = $img->thumbName($drawingWidth, $img->fromSharedDirectory);
             $thumbDir = wfImageThumbDir($img->name, $img->fromSharedDirectory);
             $thumbPath = $thumbDir . '/' . $thumbName;
             wfDebug("we have a rendered image: " . $renderedTempFile . ' width=' . $drawingWidth . ' height=' . $drawingHeight . ' thumbName=' . $thumbPath);
             if (!file_exists(dirname($thumbPath))) {
                 mkdir(dirname($thumbPath), 0777, true);
             }
             // Look at the contents of the file; if we can recognize the
             // type but it's corrupt or data of the wrong type, we should
             // probably not accept it.
             $veri = $this->verify($renderedTempFile, 'png');
             if ($veri !== true) {
                 wfDebug('[client ' . $_SERVER["REMOTE_ADDR"] . ']' . '[user ' . $wgUser->getName() . '] ' . $fname . ' rendered image failed verification [DrawingName=' . $drawingName . '][RenderedTempFile=' . $renderedTempFile . ']');
                 unlink($renderedTempFile);
             } else {
                 move_uploaded_file($renderedTempFile, $thumbPath);
             }
         } else {
             if ($renderedTempFile != null) {
                 unlink($renderedTempFile);
             }
         }
         /**
          * Save the image map, if one was provided
          */
         if ($imageMapTempFile != null && $drawingWidth != null) {
             $thumbName = $img->thumbName($drawingWidth, $img->fromSharedDirectory);
             $thumbDir = wfImageThumbDir($img->name, $img->fromSharedDirectory);
             $imageMapPath = $thumbDir . '/' . $thumbName . '.map';
             wfDebug("we have an image map: " . $imageMapTempFile);
             if (!file_exists(dirname($imageMapPath))) {
                 mkdir(dirname($imageMapPath), 0777, true);
             }
             // Look at the contents of the file; if we can recognize the
             // type but it's corrupt or data of the wrong type, we should
             // probably not accept it.
             $hasScript = $this->detectScript($imageMapTempFile, 'text/html', 'html');
             if ($hasScript !== false) {
                 wfDebug('[client ' . $_SERVER["REMOTE_ADDR"] . ']' . '[user ' . $wgUser->getName() . '] ' . $fname . ' image map failed verification [DrawingName=' . $drawingName . '][ImageMapTempFile=' . $imageMapTempFile . ']');
                 unlink($imageMapTempFile);
             } else {
                 move_uploaded_file($imageMapTempFile, $imageMapPath);
             }
         } else {
             if ($imageMapTempFile != null) {
                 unlink($imageMapTempFile);
             }
         }
         if ($success) {
             $this->showSuccess();
             wfRunHooks('UploadComplete', array(&$img));
         } else {
             // Image::recordUpload() fails if the image went missing, which is
             // unlikely, hence the lack of a specialised message
             $wgOut->showFileNotFoundError($this->mUploadSaveName);
         }
     }
     if ($renderedTempFile != null) {
         unlink($renderedTempFile);
     }
     if ($imageMapTempFile != null) {
         unlink($imageMapTempFile);
     }
 }
Example #14
0
 /**
  * Process [[ ]] wikilinks (RIL)
  * @return LinkHolderArray
  *
  * @private
  */
 function replaceInternalLinks2(&$s)
 {
     global $wgContLang;
     wfProfileIn(__METHOD__);
     wfProfileIn(__METHOD__ . '-setup');
     static $tc = FALSE, $e1, $e1_img;
     # the % is needed to support urlencoded titles as well
     if (!$tc) {
         $tc = Title::legalChars() . '#%';
         # Match a link having the form [[namespace:link|alternate]]trail
         $e1 = "/^([{$tc}]+)(?:\\|(.+?))?]](.*)\$/sD";
         # Match cases where there is no "]]", which might still be images
         $e1_img = "/^([{$tc}]+)\\|(.*)\$/sD";
     }
     $sk = $this->mOptions->getSkin();
     $holders = new LinkHolderArray($this);
     #split the entire text string on occurences of [[
     $a = StringUtils::explode('[[', ' ' . $s);
     #get the first element (all text up to first [[), and remove the space we added
     $s = $a->current();
     $a->next();
     $line = $a->current();
     # Workaround for broken ArrayIterator::next() that returns "void"
     $s = substr($s, 1);
     $useLinkPrefixExtension = $wgContLang->linkPrefixExtension();
     $e2 = null;
     if ($useLinkPrefixExtension) {
         # Match the end of a line for a word that's not followed by whitespace,
         # e.g. in the case of 'The Arab al[[Razi]]', 'al' will be matched
         $e2 = wfMsgForContent('linkprefix');
     }
     if (is_null($this->mTitle)) {
         wfProfileOut(__METHOD__ . '-setup');
         wfProfileOut(__METHOD__);
         throw new MWException(__METHOD__ . ": \$this->mTitle is null\n");
     }
     $nottalk = !$this->mTitle->isTalkPage();
     if ($useLinkPrefixExtension) {
         $m = array();
         if (preg_match($e2, $s, $m)) {
             $first_prefix = $m[2];
         } else {
             $first_prefix = false;
         }
     } else {
         $prefix = '';
     }
     if ($wgContLang->hasVariants()) {
         $selflink = $wgContLang->convertLinkToAllVariants($this->mTitle->getPrefixedText());
     } else {
         $selflink = array($this->mTitle->getPrefixedText());
     }
     $useSubpages = $this->areSubpagesAllowed();
     wfProfileOut(__METHOD__ . '-setup');
     # Loop for each link
     for (; $line !== false && $line !== null; $a->next(), $line = $a->current()) {
         # Check for excessive memory usage
         if ($holders->isBig()) {
             # Too big
             # Do the existence check, replace the link holders and clear the array
             $holders->replace($s);
             $holders->clear();
         }
         if ($useLinkPrefixExtension) {
             wfProfileIn(__METHOD__ . '-prefixhandling');
             if (preg_match($e2, $s, $m)) {
                 $prefix = $m[2];
                 $s = $m[1];
             } else {
                 $prefix = '';
             }
             # first link
             if ($first_prefix) {
                 $prefix = $first_prefix;
                 $first_prefix = false;
             }
             wfProfileOut(__METHOD__ . '-prefixhandling');
         }
         $might_be_img = false;
         wfProfileIn(__METHOD__ . "-e1");
         if (preg_match($e1, $line, $m)) {
             # page with normal text or alt
             $text = $m[2];
             # If we get a ] at the beginning of $m[3] that means we have a link that's something like:
             # [[Image:Foo.jpg|[http://example.com desc]]] <- having three ] in a row f***s up,
             # the real problem is with the $e1 regex
             # See bug 1300.
             #
             # Still some problems for cases where the ] is meant to be outside punctuation,
             # and no image is in sight. See bug 2095.
             #
             if ($text !== '' && substr($m[3], 0, 1) === ']' && strpos($text, '[') !== false) {
                 $text .= ']';
                 # so that replaceExternalLinks($text) works later
                 $m[3] = substr($m[3], 1);
             }
             # fix up urlencoded title texts
             if (strpos($m[1], '%') !== false) {
                 # Should anchors '#' also be rejected?
                 $m[1] = str_replace(array('<', '>'), array('&lt;', '&gt;'), urldecode($m[1]));
             }
             $trail = $m[3];
         } elseif (preg_match($e1_img, $line, $m)) {
             # Invalid, but might be an image with a link in its caption
             $might_be_img = true;
             $text = $m[2];
             if (strpos($m[1], '%') !== false) {
                 $m[1] = urldecode($m[1]);
             }
             $trail = "";
         } else {
             # Invalid form; output directly
             $s .= $prefix . '[[' . $line;
             wfProfileOut(__METHOD__ . "-e1");
             continue;
         }
         wfProfileOut(__METHOD__ . "-e1");
         wfProfileIn(__METHOD__ . "-misc");
         # Don't allow internal links to pages containing
         # PROTO: where PROTO is a valid URL protocol; these
         # should be external links.
         if (preg_match('/^\\b(?:' . wfUrlProtocols() . ')/', $m[1])) {
             $s .= $prefix . '[[' . $line;
             wfProfileOut(__METHOD__ . "-misc");
             continue;
         }
         # Make subpage if necessary
         if ($useSubpages) {
             $link = $this->maybeDoSubpageLink($m[1], $text);
         } else {
             $link = $m[1];
         }
         $noforce = substr($m[1], 0, 1) !== ':';
         if (!$noforce) {
             # Strip off leading ':'
             $link = substr($link, 1);
         }
         wfProfileOut(__METHOD__ . "-misc");
         wfProfileIn(__METHOD__ . "-title");
         $nt = Title::newFromText($this->mStripState->unstripNoWiki($link));
         if ($nt === NULL) {
             $s .= $prefix . '[[' . $line;
             wfProfileOut(__METHOD__ . "-title");
             continue;
         }
         $ns = $nt->getNamespace();
         $iw = $nt->getInterWiki();
         wfProfileOut(__METHOD__ . "-title");
         if ($might_be_img) {
             # if this is actually an invalid link
             wfProfileIn(__METHOD__ . "-might_be_img");
             if ($ns == NS_FILE && $noforce) {
                 #but might be an image
                 $found = false;
                 while (true) {
                     #look at the next 'line' to see if we can close it there
                     $a->next();
                     $next_line = $a->current();
                     if ($next_line === false || $next_line === null) {
                         break;
                     }
                     $m = explode(']]', $next_line, 3);
                     if (count($m) == 3) {
                         # the first ]] closes the inner link, the second the image
                         $found = true;
                         $text .= "[[{$m[0]}]]{$m[1]}";
                         $trail = $m[2];
                         break;
                     } elseif (count($m) == 2) {
                         #if there's exactly one ]] that's fine, we'll keep looking
                         $text .= "[[{$m[0]}]]{$m[1]}";
                     } else {
                         #if $next_line is invalid too, we need look no further
                         $text .= '[[' . $next_line;
                         break;
                     }
                 }
                 if (!$found) {
                     # we couldn't find the end of this imageLink, so output it raw
                     #but don't ignore what might be perfectly normal links in the text we've examined
                     $holders->merge($this->replaceInternalLinks2($text));
                     $s .= "{$prefix}[[{$link}|{$text}";
                     # note: no $trail, because without an end, there *is* no trail
                     wfProfileOut(__METHOD__ . "-might_be_img");
                     continue;
                 }
             } else {
                 #it's not an image, so output it raw
                 $s .= "{$prefix}[[{$link}|{$text}";
                 # note: no $trail, because without an end, there *is* no trail
                 wfProfileOut(__METHOD__ . "-might_be_img");
                 continue;
             }
             wfProfileOut(__METHOD__ . "-might_be_img");
         }
         $wasblank = '' == $text;
         if ($wasblank) {
             $text = $link;
         }
         # Link not escaped by : , create the various objects
         if ($noforce) {
             # Interwikis
             wfProfileIn(__METHOD__ . "-interwiki");
             if ($iw && $this->mOptions->getInterwikiMagic() && $nottalk && $wgContLang->getLanguageName($iw)) {
                 $this->mOutput->addLanguageLink($nt->getFullText());
                 $s = rtrim($s . $prefix);
                 $s .= trim($trail, "\n") == '' ? '' : $prefix . $trail;
                 wfProfileOut(__METHOD__ . "-interwiki");
                 continue;
             }
             wfProfileOut(__METHOD__ . "-interwiki");
             if ($ns == NS_FILE) {
                 wfProfileIn(__METHOD__ . "-image");
                 if (!wfIsBadImage($nt->getDBkey(), $this->mTitle)) {
                     # recursively parse links inside the image caption
                     # actually, this will parse them in any other parameters, too,
                     # but it might be hard to fix that, and it doesn't matter ATM
                     $text = $this->replaceExternalLinks($text);
                     $holders->merge($this->replaceInternalLinks2($text));
                     # cloak any absolute URLs inside the image markup, so replaceExternalLinks() won't touch them
                     $s .= $prefix . $this->armorLinks($this->makeImage($nt, $text, $holders)) . $trail;
                 }
                 $this->mOutput->addImage($nt->getDBkey());
                 wfProfileOut(__METHOD__ . "-image");
                 continue;
             }
             if ($ns == NS_CATEGORY) {
                 wfProfileIn(__METHOD__ . "-category");
                 $s = rtrim($s . "\n");
                 # bug 87
                 if ($wasblank) {
                     $sortkey = $this->getDefaultSort();
                 } else {
                     $sortkey = $text;
                 }
                 $sortkey = Sanitizer::decodeCharReferences($sortkey);
                 $sortkey = str_replace("\n", '', $sortkey);
                 $sortkey = $wgContLang->convertCategoryKey($sortkey);
                 $this->mOutput->addCategory($nt->getDBkey(), $sortkey);
                 /**
                  * Strip the whitespace Category links produce, see bug 87
                  * @todo We might want to use trim($tmp, "\n") here.
                  */
                 $s .= trim($prefix . $trail, "\n") == '' ? '' : $prefix . $trail;
                 wfProfileOut(__METHOD__ . "-category");
                 continue;
             }
         }
         # Self-link checking
         if ($nt->getFragment() === '' && $ns != NS_SPECIAL) {
             if (in_array($nt->getPrefixedText(), $selflink, true)) {
                 $s .= $prefix . $sk->makeSelfLinkObj($nt, $text, '', $trail);
                 continue;
             }
         }
         # NS_MEDIA is a pseudo-namespace for linking directly to a file
         # FIXME: Should do batch file existence checks, see comment below
         if ($ns == NS_MEDIA) {
             wfProfileIn(__METHOD__ . "-media");
             # Give extensions a chance to select the file revision for us
             $skip = $time = false;
             wfRunHooks('BeforeParserMakeImageLinkObj', array(&$this, &$nt, &$skip, &$time));
             if ($skip) {
                 $link = $sk->link($nt);
             } else {
                 $link = $sk->makeMediaLinkObj($nt, $text, $time);
             }
             # Cloak with NOPARSE to avoid replacement in replaceExternalLinks
             $s .= $prefix . $this->armorLinks($link) . $trail;
             $this->mOutput->addImage($nt->getDBkey());
             wfProfileOut(__METHOD__ . "-media");
             continue;
         }
         wfProfileIn(__METHOD__ . "-always_known");
         # Some titles, such as valid special pages or files in foreign repos, should
         # be shown as bluelinks even though they're not included in the page table
         #
         # FIXME: isAlwaysKnown() can be expensive for file links; we should really do
         # batch file existence checks for NS_FILE and NS_MEDIA
         if ($iw == '' && $nt->isAlwaysKnown()) {
             $this->mOutput->addLink($nt);
             $s .= $this->makeKnownLinkHolder($nt, $text, '', $trail, $prefix);
         } else {
             # Links will be added to the output link list after checking
             $s .= $holders->makeHolder($nt, $text, '', $trail, $prefix);
         }
         wfProfileOut(__METHOD__ . "-always_known");
     }
     wfProfileOut(__METHOD__);
     return $holders;
 }
 /**
  * This functions handle the third step of the WMU, image insertion
  *
  * @return bool|String
  */
 function insertImage()
 {
     global $wgRequest, $wgUser, $wgContLang;
     $type = $wgRequest->getVal('type');
     $name = $wgRequest->getVal('name');
     $mwname = $wgRequest->getVal('mwname');
     $tempid = $wgRequest->getVal('tempid');
     $gallery = $wgRequest->getVal('gallery', '');
     $title_main = urldecode($wgRequest->getVal('article', ''));
     $ns = $wgRequest->getVal('ns', '');
     $link = urldecode($wgRequest->getVal('link', ''));
     // Are we in the ck editor?
     $ck = $wgRequest->getVal('ck');
     $extraId = $wgRequest->getVal('extraId');
     $newFile = true;
     $file = null;
     if ($name !== NULL) {
         $name = urldecode($name);
         if ($name == '') {
             header('X-screen-type: error');
             return WfMsg('wmu-warn3');
         } else {
             $name = preg_replace("/[^" . Title::legalChars() . "]|:/", '-', $name);
             // did they give no extension at all when they changed the name?
             $ext = explode('.', $name);
             array_shift($ext);
             if (count($ext)) {
                 $finalExt = $ext[count($ext) - 1];
             } else {
                 $finalExt = '';
             }
             if ('' == $finalExt) {
                 header('X-screen-type: error');
                 return wfMsg('wmu-filetype-missing');
             }
             $title = Title::makeTitleSafe(NS_IMAGE, $name);
             if (is_null($title)) {
                 header('X-screen-type: error');
                 return wfMsg('wmu-filetype-incorrect');
             }
             if ($title->exists()) {
                 if ($type == 'overwrite') {
                     $title = Title::newFromText($name, 6);
                     // is the target protected?
                     $permErrors = $title->getUserPermissionsErrors('edit', $wgUser);
                     $permErrorsUpload = $title->getUserPermissionsErrors('upload', $wgUser);
                     $permErrorsCreate = $title->exists() ? array() : $title->getUserPermissionsErrors('create', $wgUser);
                     if ($permErrors || $permErrorsUpload || $permErrorsCreate) {
                         header('X-screen-type: error');
                         return wfMsg('wmu-file-protected');
                     }
                     $file_name = new LocalFile($title, RepoGroup::singleton()->getLocalRepo());
                     $file_mwname = new FakeLocalFile(Title::newFromText($mwname, 6), RepoGroup::singleton()->getLocalRepo());
                     if (!empty($extraId)) {
                         $flickrResult = $this->getFlickrPhotoInfo($extraId);
                         $nsid = $flickrResult['owner']['nsid'];
                         // e.g. 49127042@N00
                         $username = $flickrResult['owner']['username'];
                         // e.g. bossa67
                         $license = $flickrResult['license'];
                         $caption = '{{MediaWiki:Flickr' . intval($license) . '|1=' . wfEscapeWikiText($extraId) . '|2=' . wfEscapeWikiText($nsid) . '|3=' . wfEscapeWikiText($username) . '}}';
                     } else {
                         $caption = '';
                     }
                     $file_name->upload($file_mwname->getPath(), '', $caption);
                     $file_mwname->delete('');
                     $this->tempFileClearInfo($tempid);
                     $newFile = false;
                 } else {
                     if ($type == 'existing') {
                         $file = wfFindFile(Title::newFromText($name, 6));
                         if (!empty($file)) {
                             header('X-screen-type: existing');
                             $props = array();
                             $props['file'] = $file;
                             $props['mwname'] = $name;
                             $props['default_caption'] = Wikia::getProps($file->getTitle()->getArticleID(), 'default_caption');
                             return $this->detailsPage($props);
                         } else {
                             header('X-screen-type: error');
                             return wfMsg('wmu-file-error');
                         }
                     } else {
                         header('X-screen-type: conflict');
                         $tmpl = new EasyTemplate(dirname(__FILE__) . '/templates/');
                         // extensions check
                         list($partname, $ext) = UploadBase::splitExtensions($name);
                         if (count($ext)) {
                             $finalExt = $ext[count($ext) - 1];
                         } else {
                             $finalExt = '';
                         }
                         // for more than one "extension"
                         if (count($ext) > 1) {
                             for ($i = 0; $i < count($ext) - 1; $i++) {
                                 $partname .= '.' . $ext[$i];
                             }
                         }
                         $tmpl->set_vars(array('partname' => $partname, 'extension' => strtolower($finalExt), 'mwname' => $mwname, 'extraId' => $extraId));
                         return $tmpl->render('conflict');
                     }
                 }
             } else {
                 // is the target protected?
                 $permErrors = $title->getUserPermissionsErrors('edit', $wgUser);
                 $permErrorsUpload = $title->getUserPermissionsErrors('upload', $wgUser);
                 $permErrorsCreate = $title->exists() ? array() : $title->getUserPermissionsErrors('create', $wgUser);
                 if ($permErrors || $permErrorsUpload || $permErrorsCreate) {
                     header('X-screen-type: error');
                     return wfMsg('wmu-file-protected');
                 }
                 $temp_file = new FakeLocalFile(Title::newFromText($mwname, 6), RepoGroup::singleton()->getLocalRepo());
                 $file = new LocalFile($title, RepoGroup::singleton()->getLocalRepo());
                 if (!empty($extraId)) {
                     $flickrResult = $this->getFlickrPhotoInfo($extraId);
                     $nsid = $flickrResult['owner']['nsid'];
                     // e.g. 49127042@N00
                     $username = $flickrResult['owner']['username'];
                     // e.g. bossa67
                     $license = $flickrResult['license'];
                     $caption = '{{MediaWiki:Flickr' . intval($license) . '|1=' . wfEscapeWikiText($extraId) . '|2=' . wfEscapeWikiText($nsid) . '|3=' . wfEscapeWikiText($username) . '}}';
                 } else {
                     // get the supplied license value
                     $license = $wgRequest->getVal('ImageUploadLicense');
                     if ($license != '') {
                         $caption = '== ' . wfMsgForContent('license') . " ==\n" . '{{' . $license . '}}' . "\n";
                     } else {
                         $caption = "";
                     }
                 }
                 $file->upload($temp_file->getPath(), '', $caption);
                 $temp_file->delete('');
                 $this->tempFileClearInfo($tempid);
             }
             if ($wgUser->getGLobalPreference('watchdefault') || $newFile && $wgUser->getGlobalPreference('watchcreations')) {
                 $wgUser->addWatch($title);
             }
             $db =& wfGetDB(DB_MASTER);
             $db->commit();
         }
     } else {
         $title = Title::newFromText($mwname, 6);
     }
     if (is_null($file)) {
         $file = wfFindFile($title);
     }
     if (!is_object($file)) {
         header('X-screen-type: error');
         return wfMessage('wmu-file-not-found')->plain();
     }
     // Test if this violates the size requirements we've been given
     if ($msg = $this->invalidSize($file)) {
         header('X-screen-type: error');
         return $msg;
     }
     $ns_img = $wgContLang->getFormattedNsText(NS_IMAGE);
     if (-2 == $gallery && !$ck) {
         // this went in from the single placeholder...
         $name = $title->getText();
         $size = $wgRequest->getVal('size');
         $width = $wgRequest->getVal('width');
         $layout = $wgRequest->getVal('layout');
         // clear the old caption for upload
         $caption = $wgRequest->getVal('caption');
         $slider = $wgRequest->getVal('slider');
         $title_obj = Title::newFromText($title_main, $ns);
         $article_obj = new Article($title_obj);
         $text = $article_obj->getContent();
         wfRunHooks('WikiaMiniUpload::fetchTextForImagePlaceholder', array(&$title_obj, &$text));
         $box = $wgRequest->getVal('box', '');
         $placeholder = MediaPlaceholderMatch($text, $box);
         $success = false;
         if ($placeholder) {
             $our_gallery = $placeholder[0];
             $gallery_split = explode(':', $our_gallery);
             $thumb = false;
             $tag = $gallery_split[0] . ":" . $name;
             if ($size != 'full') {
                 $tag .= '|thumb';
                 $thumb = true;
             }
             if (isset($width)) {
                 $tag .= '|' . $width;
             }
             $tag .= '|' . $layout;
             if ($link != '') {
                 $tag .= '|link=' . $link;
             }
             if ($caption != '') {
                 $tag .= '|' . $caption;
             }
             $tag .= "]]";
             $text = substr_replace($text, $tag, $placeholder[1], strlen($our_gallery));
             // return the proper embed code with all fancies around it
             $embed_code = $this->generateImage($file, $name, $title_obj, $thumb, (int) str_replace('px', '', $width), $layout, $caption);
             $message = wfMsg('wmu-success');
             Wikia::setVar('EditFromViewMode', true);
             $summary = wfMsg('wmu-added-from-plc');
             $success = $article_obj->doEdit($text, $summary);
         }
         if ($success) {
             header('X-screen-type: summary');
         } else {
             // failure signal opens js alert (BugId:4935)
             header('X-screen-type: error');
             return;
         }
     } else {
         header('X-screen-type: summary');
         $size = $wgRequest->getVal('size');
         $width = $wgRequest->getVal('width');
         $layout = $wgRequest->getVal('layout');
         $caption = $wgRequest->getVal('caption');
         $slider = $wgRequest->getVal('slider');
         $tag = '[[' . $ns_img . ':' . $title->getDBkey();
         if ($size != 'full' && ($file->getMediaType() == 'BITMAP' || $file->getMediaType() == 'DRAWING')) {
             $tag .= '|thumb';
             if ($layout != 'right') {
                 $tag .= '|' . $layout;
             }
             if ($slider == 'true') {
                 $tag .= '|' . $width;
             }
         }
         if ($link != '' && $size == 'full') {
             $tag .= '|link=' . $link;
         }
         if ($caption != '') {
             if ($size == 'full') {
                 $tag .= '|frame';
                 if ($layout != 'right') {
                     $tag .= '|' . $layout;
                 }
             }
             $tag .= '|' . $caption . ']]';
         } else {
             if ($size == 'full') {
                 $tag .= '|' . $layout;
             }
             $tag .= ']]';
         }
     }
     $message = wfMsg('wmu-success');
     if ($wgRequest->getVal('update_caption') == 'on') {
         Wikia::setProps($title->getArticleID(), array('default_caption' => $caption));
     }
     $tmpl = new EasyTemplate(dirname(__FILE__) . '/templates/');
     $tmpl->set_vars(array('tag' => $tag, 'filename' => $ns_img . ':' . $title->getDBkey(), 'message' => $message, 'code' => isset($embed_code) ? $embed_code : ''));
     return $tmpl->render('summary');
 }
 /**
  * This hook is called before any form of substitution or parsing is done on the text.  $text is modifiable -- we can do
  * any sort of substitution, addition/deleting, replacement, etc. on it and it will be reflected in our output.  This is
  * perfect to doing wiki link substitution for URL rewriting and so forth.
  *
  * @static
  * @param Parser $parser
  * @param string $text
  * @return boolean|string
  */
 public static function onParserBeforeStrip(&$parser, &$text)
 {
     global $action, $wgTitle, $wgArticlePath, $wgOut, $wgPonyDocs, $action;
     $dbr = wfGetDB(DB_SLAVE);
     if (empty($wgTitle)) {
         return true;
     }
     // We want to do link substitution in all namespaces now.
     $doWikiLinkSubstitution = true;
     $matches = array('/^' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . ':(.*):(.*):(.*):(.*)/');
     $doStripH1 = false;
     foreach ($matches as $m) {
         if (preg_match($m, $wgTitle->__toString())) {
             $doStripH1 = true;
         }
     }
     if (!strcmp($action, 'submit') && preg_match('/^Someone else has changed this page/i', $text)) {
         $text = '';
         return true;
     }
     /**
      * Strip out ANY H1 HEADER.  This has the nice effect of only stripping it out during render and not during edit or
      * anything.  We should only be doing this for Documentation namespace?
      *
      * Note, we've put false into the if statement, because we're 
      * disabling this "feature", per WEB-2890.
      *
      * Keeping the code in, just in case we want to re-enable.
      */
     if ($doStripH1 && false) {
         $text = preg_replace('/^\\s*=.*=.*\\n?/', '', $text);
     }
     /**
      * Handle our wiki links, which are always of the form [[<blah>]].  There are built-in functions however that also use
      * this structure (like Category tags).  We need to filter these out AND filter out any external links.  The rest we
      * need to grab and produce proper anchor's and replace in the output.  In each:
      * 	0=Entire string to match
      *  1=Title
      *  2=Ignore
      *  3=Display Text (optional)
      * Possible forms:
      *	[[TopicName]]								Translated to Documentation:<currentManual>:<topicName>:<selectedVersion>
      *	[[Documentation:<manual>:<topic>]]			Translated to Documentation:<manual>:<topic>:<selectedVersion>
      *	[[Documentation:<manual>:<topic>:<version>]]No translation done -- exact link.
      *	[[Namespace:Topic]]							No translation done -- exact link.
      *  [[:Topic]]									Link to topic in global namespace - preceding colon required!
      */
     //if( $doWikiLinkSubstitution && preg_match_all( "/\[\[([A-Za-z0-9,:._ -]*)([|]?([A-Za-z0-9,:.'_!@\"()#$ -]*))\]\]/", $text, $matches, PREG_SET_ORDER ))
     if ($doWikiLinkSubstitution && preg_match_all("/\\[\\[([A-Za-z0-9,:._ -]*)(\\#[A-Za-z0-9 ._-]+)?([|]?([A-Za-z0-9,:.'_?!@\\/\"()#\$ -{}]*))\\]\\]/", $text, $matches, PREG_SET_ORDER)) {
         //echo '<pre>'; print_r( $matches ); die();
         /**
          * For each, find the topic in categorylinks which is tagged with currently selected version then produce
          * link and replace in output ($text).  Simple!
          */
         $selectedProduct = PonyDocsProduct::GetSelectedProduct();
         $selectedVersion = PonyDocsProductVersion::GetSelectedVersion($selectedProduct);
         $pManual = PonyDocsProductManual::GetCurrentManual($selectedProduct);
         // No longer bail on $pManual not being set.  We should only need it
         // for [[Namespace:Topic]]
         foreach ($matches as $match) {
             /**
              * Namespace used.  If NOT Documentation, just output the link.
              */
             if (strpos($match[1], ':') !== false && strpos($match[1], PONYDOCS_DOCUMENTATION_NAMESPACE_NAME) === 0) {
                 $pieces = explode(':', $match[1]);
                 /**
                  * [[Documentation:Manual:Topic]] => Documentation/<currentProduct>/<currentVersion>/Manual/Topic
                  */
                 if (3 == sizeof($pieces)) {
                     $res = $dbr->select('categorylinks', 'cl_from', array("cl_to = 'V:" . $selectedProduct . ":" . $selectedVersion . "'", 'cl_type = "page"', 'cl_sortkey LIKE "' . $dbr->strencode(strtoupper("{$pieces[1]}:{$pieces[2]}")) . ':%"'), __METHOD__);
                     if ($res->numRows()) {
                         global $title;
                         // Our title is our url.  We should check to see if
                         // latest is our version.  If so, we want to FORCE
                         // the URL to include /latest/ as the version
                         // instead of the version that the user is
                         // currently in.
                         $tempParts = explode("/", $title);
                         $latest = false;
                         if (!empty($tempParts[1]) && !strcmp($tempParts[1], "latest")) {
                             $latest = true;
                         }
                         // Okay, let's determine if the VERSION that the user is in is latest,
                         // if so, we should set latest to true.
                         if ($selectedVersion == PonyDocsProductVersion::GetLatestReleasedVersion($selectedProduct)) {
                             $latest = true;
                         }
                         $href = str_replace('$1', PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . '/' . $selectedProduct . '/' . ($latest ? "latest" : $selectedVersion) . '/' . $pieces[2] . '/' . preg_replace('/([^' . str_replace(' ', '', Title::legalChars()) . '])/', '', $pieces[3]), $wgArticlePath);
                         $href .= $match[2];
                         if (isset($_SERVER['SERVER_NAME'])) {
                             $text = str_replace($match[0], "[http://{$_SERVER['SERVER_NAME']}{$href} " . (strlen($match[4]) ? $match[4] : $match[1]) . ']', $text);
                         }
                     }
                     /**
                      * [[Documentation:Product:Manual:Topic]] => Documentation/Product/<latest_or_selected>/Manual/Topic
                      * If linking within same product, stay on selected version; otherwise use "latest" for cross-product link
                      */
                 } else {
                     if (4 == sizeof($pieces)) {
                         $linkProduct = $pieces[1];
                         // set product in link for legibility
                         // If this is a link to the current project, use the selected version. Otherwise set version to latest.
                         if (!strcmp($selectedProduct, $linkProduct)) {
                             $version = $selectedVersion;
                         } else {
                             $version = 'latest';
                         }
                         // If the version is "latest", translate that to a real version number. Use product that was in the link.
                         if ($version == 'latest') {
                             PonyDocsProductVersion::LoadVersionsForProduct($linkProduct);
                             $versionObj = PonyDocsProductVersion::GetLatestReleasedVersion($linkProduct);
                             $dbVersion = $versionObj === NULL ? NULL : $versionObj->getVersionName();
                         } else {
                             $dbVersion = $version;
                         }
                         // Database call to see if this topic exists in the product/version specified in the link
                         $res = $dbr->select('categorylinks', 'cl_from', array("cl_to = 'V:" . $linkProduct . ":" . $dbVersion . "'", 'cl_type = "page"', "cl_sortkey LIKE '" . $dbr->strencode(strtoupper(implode(":", array_slice($pieces, 1)))) . ":%'"), __METHOD__);
                         if (!$res->numRows()) {
                             // This article is not found.
                             continue;
                         }
                         $href = str_replace('$1', PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . '/' . $linkProduct . '/' . $version . '/' . $pieces[2] . '/' . preg_replace('/([^' . str_replace(' ', '', Title::legalChars()) . '])/', '', $pieces[3]), $wgArticlePath);
                         $href .= $match[2];
                         $text = str_replace($match[0], "[http://{$_SERVER['SERVER_NAME']}{$href} " . (strlen($match[4]) ? $match[4] : $match[1]) . ']', $text);
                     } else {
                         if (5 == sizeof($pieces)) {
                             $href = str_replace('$1', PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . '/' . $pieces[1] . '/' . $pieces[4] . '/' . $pieces[2] . '/' . preg_replace('/([^' . str_replace(' ', '', Title::legalChars()) . '])/', '', $pieces[3]), $wgArticlePath);
                             $href .= $match[2];
                             $text = str_replace($match[0], '[http://' . $_SERVER['SERVER_NAME'] . $href . ' ' . (strlen($match[4]) ? $match[4] : $match[1]) . ']', $text);
                         }
                     }
                 }
             } else {
                 // Check if our title is in Documentation and manual is set, if not, don't modify the match.
                 if (!preg_match('/^' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . ':.*:.*:.*:.*/i', $wgTitle->__toString()) || !isset($pManual)) {
                     continue;
                 }
                 $res = $dbr->select('categorylinks', 'cl_from', array("cl_to = 'V:" . $selectedProduct . ":" . $selectedVersion . "'", 'cl_type = "page"', "cl_sortkey LIKE '" . $dbr->strencode(strtoupper($selectedProduct . ':' . $pManual->getShortName() . ':' . $match[1])) . ":%'"), __METHOD__);
                 /**
                  * We might need to make it a "non-link" at this point instead of skipping it.
                  */
                 if (!$res->numRows()) {
                     continue;
                 }
                 $href = str_replace('$1', PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . '/' . $selectedProduct . '/' . $selectedVersion . '/' . $pManual->getShortName() . '/' . preg_replace('/([^' . str_replace(' ', '', Title::legalChars()) . '])/', '', $match[1]), $wgArticlePath);
                 $href .= $match[2];
                 $text = str_replace($match[0], "[http://{$_SERVER['SERVER_NAME']}{$href} " . (strlen($match[4]) ? $match[4] : $match[1]) . ']', $text);
             }
         }
     }
     return true;
 }
Example #17
0
 /**
  * Process [[ ]] wikilinks
  *
  * @private
  */
 function replaceInternalLinks($s)
 {
     global $wgContLang;
     static $fname = 'Parser::replaceInternalLinks';
     wfProfileIn($fname);
     wfProfileIn($fname . '-setup');
     static $tc = FALSE;
     # the % is needed to support urlencoded titles as well
     if (!$tc) {
         $tc = Title::legalChars() . '#%';
     }
     $sk = $this->mOptions->getSkin();
     #split the entire text string on occurences of [[
     $a = explode('[[', ' ' . $s);
     #get the first element (all text up to first [[), and remove the space we added
     $s = array_shift($a);
     $s = substr($s, 1);
     # Match a link having the form [[namespace:link|alternate]]trail
     static $e1 = FALSE;
     if (!$e1) {
         $e1 = "/^([{$tc}]+)(?:\\|(.+?))?]](.*)\$/sD";
     }
     # Match cases where there is no "]]", which might still be images
     static $e1_img = FALSE;
     if (!$e1_img) {
         $e1_img = "/^([{$tc}]+)\\|(.*)\$/sD";
     }
     $useLinkPrefixExtension = $wgContLang->linkPrefixExtension();
     $e2 = null;
     if ($useLinkPrefixExtension) {
         # Match the end of a line for a word that's not followed by whitespace,
         # e.g. in the case of 'The Arab al[[Razi]]', 'al' will be matched
         $e2 = wfMsgForContent('linkprefix');
     }
     if (is_null($this->mTitle)) {
         throw new MWException(__METHOD__ . ": \$this->mTitle is null\n");
     }
     $nottalk = !$this->mTitle->isTalkPage();
     if ($useLinkPrefixExtension) {
         $m = array();
         if (preg_match($e2, $s, $m)) {
             $first_prefix = $m[2];
         } else {
             $first_prefix = false;
         }
     } else {
         $prefix = '';
     }
     if ($wgContLang->hasVariants()) {
         $selflink = $wgContLang->convertLinkToAllVariants($this->mTitle->getPrefixedText());
     } else {
         $selflink = array($this->mTitle->getPrefixedText());
     }
     $useSubpages = $this->areSubpagesAllowed();
     wfProfileOut($fname . '-setup');
     # Loop for each link
     for ($k = 0; isset($a[$k]); $k++) {
         $line = $a[$k];
         if ($useLinkPrefixExtension) {
             wfProfileIn($fname . '-prefixhandling');
             if (preg_match($e2, $s, $m)) {
                 $prefix = $m[2];
                 $s = $m[1];
             } else {
                 $prefix = '';
             }
             # first link
             if ($first_prefix) {
                 $prefix = $first_prefix;
                 $first_prefix = false;
             }
             wfProfileOut($fname . '-prefixhandling');
         }
         $might_be_img = false;
         wfProfileIn("{$fname}-e1");
         if (preg_match($e1, $line, $m)) {
             # page with normal text or alt
             $text = $m[2];
             # If we get a ] at the beginning of $m[3] that means we have a link that's something like:
             # [[Image:Foo.jpg|[http://example.com desc]]] <- having three ] in a row f***s up,
             # the real problem is with the $e1 regex
             # See bug 1300.
             #
             # Still some problems for cases where the ] is meant to be outside punctuation,
             # and no image is in sight. See bug 2095.
             #
             if ($text !== '' && substr($m[3], 0, 1) === ']' && strpos($text, '[') !== false) {
                 $text .= ']';
                 # so that replaceExternalLinks($text) works later
                 $m[3] = substr($m[3], 1);
             }
             # fix up urlencoded title texts
             if (strpos($m[1], '%') !== false) {
                 # Should anchors '#' also be rejected?
                 $m[1] = str_replace(array('<', '>'), array('&lt;', '&gt;'), urldecode($m[1]));
             }
             $trail = $m[3];
         } elseif (preg_match($e1_img, $line, $m)) {
             # Invalid, but might be an image with a link in its caption
             $might_be_img = true;
             $text = $m[2];
             if (strpos($m[1], '%') !== false) {
                 $m[1] = urldecode($m[1]);
             }
             $trail = "";
         } else {
             # Invalid form; output directly
             $s .= $prefix . '[[' . $line;
             wfProfileOut("{$fname}-e1");
             continue;
         }
         wfProfileOut("{$fname}-e1");
         wfProfileIn("{$fname}-misc");
         # Don't allow internal links to pages containing
         # PROTO: where PROTO is a valid URL protocol; these
         # should be external links.
         if (preg_match('/^\\b(?:' . wfUrlProtocols() . ')/', $m[1])) {
             $s .= $prefix . '[[' . $line;
             continue;
         }
         # Make subpage if necessary
         if ($useSubpages) {
             $link = $this->maybeDoSubpageLink($m[1], $text);
         } else {
             $link = $m[1];
         }
         $noforce = substr($m[1], 0, 1) != ':';
         if (!$noforce) {
             # Strip off leading ':'
             $link = substr($link, 1);
         }
         wfProfileOut("{$fname}-misc");
         wfProfileIn("{$fname}-title");
         $nt = Title::newFromText($this->mStripState->unstripNoWiki($link));
         if (!$nt) {
             $s .= $prefix . '[[' . $line;
             wfProfileOut("{$fname}-title");
             continue;
         }
         $ns = $nt->getNamespace();
         $iw = $nt->getInterWiki();
         wfProfileOut("{$fname}-title");
         if ($might_be_img) {
             # if this is actually an invalid link
             wfProfileIn("{$fname}-might_be_img");
             if ($ns == NS_IMAGE && $noforce) {
                 #but might be an image
                 $found = false;
                 while (isset($a[$k + 1])) {
                     #look at the next 'line' to see if we can close it there
                     $spliced = array_splice($a, $k + 1, 1);
                     $next_line = array_shift($spliced);
                     $m = explode(']]', $next_line, 3);
                     if (count($m) == 3) {
                         # the first ]] closes the inner link, the second the image
                         $found = true;
                         $text .= "[[{$m[0]}]]{$m[1]}";
                         $trail = $m[2];
                         break;
                     } elseif (count($m) == 2) {
                         #if there's exactly one ]] that's fine, we'll keep looking
                         $text .= "[[{$m[0]}]]{$m[1]}";
                     } else {
                         #if $next_line is invalid too, we need look no further
                         $text .= '[[' . $next_line;
                         break;
                     }
                 }
                 if (!$found) {
                     # we couldn't find the end of this imageLink, so output it raw
                     #but don't ignore what might be perfectly normal links in the text we've examined
                     $text = $this->replaceInternalLinks($text);
                     $s .= "{$prefix}[[{$link}|{$text}";
                     # note: no $trail, because without an end, there *is* no trail
                     wfProfileOut("{$fname}-might_be_img");
                     continue;
                 }
             } else {
                 #it's not an image, so output it raw
                 $s .= "{$prefix}[[{$link}|{$text}";
                 # note: no $trail, because without an end, there *is* no trail
                 wfProfileOut("{$fname}-might_be_img");
                 continue;
             }
             wfProfileOut("{$fname}-might_be_img");
         }
         $wasblank = '' == $text;
         if ($wasblank) {
             $text = $link;
         }
         # Link not escaped by : , create the various objects
         if ($noforce) {
             # Interwikis
             wfProfileIn("{$fname}-interwiki");
             if ($iw && $this->mOptions->getInterwikiMagic() && $nottalk && $wgContLang->getLanguageName($iw)) {
                 $this->mOutput->addLanguageLink($nt->getFullText());
                 $s = rtrim($s . $prefix);
                 $s .= trim($trail, "\n") == '' ? '' : $prefix . $trail;
                 wfProfileOut("{$fname}-interwiki");
                 continue;
             }
             wfProfileOut("{$fname}-interwiki");
             if ($ns == NS_IMAGE) {
                 wfProfileIn("{$fname}-image");
                 if (!wfIsBadImage($nt->getDBkey(), $this->mTitle)) {
                     # recursively parse links inside the image caption
                     # actually, this will parse them in any other parameters, too,
                     # but it might be hard to fix that, and it doesn't matter ATM
                     $text = $this->replaceExternalLinks($text);
                     $text = $this->replaceInternalLinks($text);
                     # cloak any absolute URLs inside the image markup, so replaceExternalLinks() won't touch them
                     $s .= $prefix . $this->armorLinks($this->makeImage($nt, $text)) . $trail;
                     $this->mOutput->addImage($nt->getDBkey());
                     wfProfileOut("{$fname}-image");
                     continue;
                 } else {
                     # We still need to record the image's presence on the page
                     $this->mOutput->addImage($nt->getDBkey());
                 }
                 wfProfileOut("{$fname}-image");
             }
             if ($ns == NS_CATEGORY) {
                 wfProfileIn("{$fname}-category");
                 $s = rtrim($s . "\n");
                 # bug 87
                 if ($wasblank) {
                     $sortkey = $this->getDefaultSort();
                 } else {
                     $sortkey = $text;
                 }
                 $sortkey = Sanitizer::decodeCharReferences($sortkey);
                 $sortkey = str_replace("\n", '', $sortkey);
                 $sortkey = $wgContLang->convertCategoryKey($sortkey);
                 $this->mOutput->addCategory($nt->getDBkey(), $sortkey);
                 /**
                  * Strip the whitespace Category links produce, see bug 87
                  * @todo We might want to use trim($tmp, "\n") here.
                  */
                 $s .= trim($prefix . $trail, "\n") == '' ? '' : $prefix . $trail;
                 wfProfileOut("{$fname}-category");
                 continue;
             }
         }
         # Self-link checking
         if ($nt->getFragment() === '') {
             if (in_array($nt->getPrefixedText(), $selflink, true)) {
                 $s .= $prefix . $sk->makeSelfLinkObj($nt, $text, '', $trail);
                 continue;
             }
         }
         # Special and Media are pseudo-namespaces; no pages actually exist in them
         if ($ns == NS_MEDIA) {
             $link = $sk->makeMediaLinkObj($nt, $text);
             # Cloak with NOPARSE to avoid replacement in replaceExternalLinks
             $s .= $prefix . $this->armorLinks($link) . $trail;
             $this->mOutput->addImage($nt->getDBkey());
             continue;
         } elseif ($ns == NS_SPECIAL) {
             if (SpecialPage::exists($nt->getDBkey())) {
                 $s .= $this->makeKnownLinkHolder($nt, $text, '', $trail, $prefix);
             } else {
                 $s .= $this->makeLinkHolder($nt, $text, '', $trail, $prefix);
             }
             continue;
         } elseif ($ns == NS_IMAGE) {
             $img = wfFindFile($nt);
             if ($img) {
                 // Force a blue link if the file exists; may be a remote
                 // upload on the shared repository, and we want to see its
                 // auto-generated page.
                 $s .= $this->makeKnownLinkHolder($nt, $text, '', $trail, $prefix);
                 $this->mOutput->addLink($nt);
                 continue;
             }
         }
         $s .= $this->makeLinkHolder($nt, $text, '', $trail, $prefix);
     }
     wfProfileOut($fname);
     return $s;
 }
 /**
  * Process [[ ]] wikilinks
  * @return LinkHolderArray
  *
  * @private
  */
 function replaceInternalLinks2(&$s)
 {
     wfProfileIn(__METHOD__);
     wfProfileIn(__METHOD__ . '-setup');
     static $tc = FALSE, $titleRegex;
     //$e1, $e1_img;
     if (!$tc) {
         # the % is needed to support urlencoded titles as well
         $tc = Title::legalChars() . '#%';
         # Match a link having the form [[namespace:link|alternate]]trail
         //$e1 = "/^([{$tc}]+)(?:\\|(.+?))?]](.*)\$/sD";
         # Match cases where there is no "]]", which might still be images
         //$e1_img = "/^([{$tc}]+)\\|(.*)\$/sD";
         # Match a valid plain title
         $titleRegex = "/^([{$tc}]+)\$/sD";
     }
     $holders = new LinkHolderArray($this);
     if (is_null($this->mTitle)) {
         wfProfileOut(__METHOD__);
         wfProfileOut(__METHOD__ . '-setup');
         throw new MWException(__METHOD__ . ": \$this->mTitle is null\n");
     }
     wfProfileOut(__METHOD__ . '-setup');
     $offset = 0;
     $offsetStack = array();
     $markers = new LinkMarkerReplacer($this, $holders, array(&$this, 'replaceInternalLinksCallback'));
     while (true) {
         $startBracketOffset = strpos($s, '[[', $offset);
         $endBracketOffset = strpos($s, ']]', $offset);
         # Finish when there are no more brackets
         if ($startBracketOffset === false && $endBracketOffset === false) {
             break;
         } elseif ($startBracketOffset !== false && $endBracketOffset !== false) {
             $isStart = $startBracketOffset <= $endBracketOffset;
         } else {
             $isStart = $startBracketOffset !== false;
         }
         $bracketOffset = $isStart ? $startBracketOffset : $endBracketOffset;
         if ($isStart) {
             /** Opening bracket **/
             # Just push our current offset in the string onto the stack
             $offsetStack[] = $startBracketOffset;
         } else {
             /** Closing bracket **/
             # Pop the start pos for our current link zone off the stack
             $startBracketOffset = array_pop($offsetStack);
             # Just to clean up the code, lets place offsets on the outer ends
             $endBracketOffset += 2;
             # Only do logic if we actually have a opening bracket for this
             if (isset($startBracketOffset)) {
                 # Extract text inside the link
                 @(list($titleText, $paramText) = explode('|', substr($s, $startBracketOffset + 2, $endBracketOffset - $startBracketOffset - 4), 2));
                 # Create markers only for valid links
                 if (preg_match($titleRegex, $titleText)) {
                     # Store the text for the marker
                     $marker = $markers->addMarker($titleText, $paramText);
                     # Replace the current link with the marker
                     $s = substr($s, 0, $startBracketOffset) . $marker . substr($s, $endBracketOffset);
                     # We have modified $s, because of this we need to set the
                     # offset manually since the end position is different now
                     $offset = $startBracketOffset + strlen($marker);
                     continue;
                 }
                 # ToDo: Some LinkHooks may allow recursive links inside of
                 # the link text, create a regex that also matches our
                 # <!-- LINKMARKER ### --> sequence in titles
                 # ToDO: Some LinkHooks use patterns rather than namespaces
                 # these need to be tested at this point here
             }
         }
         # Bump our offset to after our current bracket
         $offset = $bracketOffset + 2;
     }
     # Now expand our tree
     wfProfileIn(__METHOD__ . '-expand');
     $s = $markers->expand($s);
     wfProfileOut(__METHOD__ . '-expand');
     wfProfileOut(__METHOD__);
     return $holders;
 }
Example #19
0
 /**
  * Generate a new file name such as "foobar 2.jpg" if both filenames
  * "foobar.jpg" and "foobar 1.jpg" exist in the database.
  *
  * @param $name original filename
  * @return new, unique filename
  */
 public static function generateNewFilename($name)
 {
     $name = preg_replace('/[^' . Title::legalChars() . ']|[:\\/\\\\]|\\?/', '-', $name);
     $newName = $name;
     list($first, $ext) = self::splitFilenameExt($name);
     //blank name? give it a name!
     if (empty($first)) {
         $first = mt_rand(100000, 100000000);
     }
     $i = 1;
     do {
         $title = Title::newFromText($newName, NS_IMAGE);
         if (!$title->exists()) {
             break;
         }
         $newName = $first . ' ' . $i++ . '.' . $ext;
     } while ($i < 1000);
     return $newName;
 }
Example #20
0
 /**
  * Process [[ ]] wikilinks (RIL)
  * @return LinkHolderArray
  *
  * @private
  */
 function replaceInternalLinks2(&$s)
 {
     wfProfileIn(__METHOD__);
     # RTE (Rich Text Editor) - begin
     # @author: Inez Korczyński
     global $wgRTEParserEnabled;
     # RTE (Rich Text Editor) - end
     wfProfileIn(__METHOD__ . '-setup');
     static $tc = FALSE, $e1, $e1_img;
     # the % is needed to support urlencoded titles as well
     if (!$tc) {
         $tc = Title::legalChars() . '#%';
         # Match a link having the form [[namespace:link|alternate]]trail
         $e1 = "/^([{$tc}]+)(?:\\|(.+?))?]](.*)\$/sD";
         # Match cases where there is no "]]", which might still be images
         $e1_img = "/^([{$tc}]+)\\|(.*)\$/sD";
     }
     $holders = new LinkHolderArray($this);
     # split the entire text string on occurences of [[
     $a = StringUtils::explode('[[', ' ' . $s);
     # get the first element (all text up to first [[), and remove the space we added
     $s = $a->current();
     $a->next();
     $line = $a->current();
     # Workaround for broken ArrayIterator::next() that returns "void"
     $s = substr($s, 1);
     $useLinkPrefixExtension = $this->getTargetLanguage()->linkPrefixExtension();
     $e2 = null;
     if ($useLinkPrefixExtension) {
         # Match the end of a line for a word that's not followed by whitespace,
         # e.g. in the case of 'The Arab al[[Razi]]', 'al' will be matched
         $e2 = wfMsgForContent('linkprefix');
     }
     if (is_null($this->mTitle)) {
         wfProfileOut(__METHOD__ . '-setup');
         wfProfileOut(__METHOD__);
         throw new MWException(__METHOD__ . ": \$this->mTitle is null\n");
     }
     $nottalk = !$this->mTitle->isTalkPage();
     if ($useLinkPrefixExtension) {
         $m = array();
         if (preg_match($e2, $s, $m)) {
             $first_prefix = $m[2];
         } else {
             $first_prefix = false;
         }
     } else {
         $prefix = '';
     }
     if ($this->getConverterLanguage()->hasVariants()) {
         $selflink = $this->getConverterLanguage()->autoConvertToAllVariants($this->mTitle->getPrefixedText());
     } else {
         $selflink = array($this->mTitle->getPrefixedText());
     }
     $useSubpages = $this->areSubpagesAllowed();
     wfProfileOut(__METHOD__ . '-setup');
     # Loop for each link
     for (; $line !== false && $line !== null; $a->next(), $line = $a->current()) {
         # Check for excessive memory usage
         if ($holders->isBig()) {
             # Too big
             # Do the existence check, replace the link holders and clear the array
             $holders->replace($s);
             $holders->clear();
         }
         # RTE (Rich Text Editor) - begin
         # @author: Inez Korczyński
         if (!empty($wgRTEParserEnabled)) {
             $RTE_wikitextIdx = RTEMarker::getDataIdx(RTEMarker::INTERNAL_WIKITEXT, $line);
             // decode entities inside links wikimarkup (RT #38844)
             if ($pos = strpos($line, ']]')) {
                 // unmark entities inside link
                 $link = substr($line, 0, $pos);
                 $link = RTEParser::unmarkEntities($link);
                 // leave the rest of the line untouched
                 $line = $link . substr($line, $pos);
             }
         }
         # RTE - end
         if ($useLinkPrefixExtension) {
             wfProfileIn(__METHOD__ . '-prefixhandling');
             if (preg_match($e2, $s, $m)) {
                 $prefix = $m[2];
                 $s = $m[1];
             } else {
                 $prefix = '';
             }
             # first link
             if ($first_prefix) {
                 $prefix = $first_prefix;
                 $first_prefix = false;
             }
             wfProfileOut(__METHOD__ . '-prefixhandling');
         }
         $might_be_img = false;
         wfProfileIn(__METHOD__ . "-e1");
         if (preg_match($e1, $line, $m)) {
             # page with normal text or alt
             $text = $m[2];
             # If we get a ] at the beginning of $m[3] that means we have a link that's something like:
             # [[Image:Foo.jpg|[http://example.com desc]]] <- having three ] in a row f***s up,
             # the real problem is with the $e1 regex
             # See bug 1300.
             #
             # Still some problems for cases where the ] is meant to be outside punctuation,
             # and no image is in sight. See bug 2095.
             #
             if ($text !== '' && substr($m[3], 0, 1) === ']' && strpos($text, '[') !== false) {
                 $text .= ']';
                 # so that replaceExternalLinks($text) works later
                 $m[3] = substr($m[3], 1);
             }
             # fix up urlencoded title texts
             if (strpos($m[1], '%') !== false) {
                 # Should anchors '#' also be rejected?
                 $m[1] = str_replace(array('<', '>'), array('&lt;', '&gt;'), rawurldecode($m[1]));
             }
             $trail = $m[3];
         } elseif (preg_match($e1_img, $line, $m)) {
             # Invalid, but might be an image with a link in its caption
             $might_be_img = true;
             $text = $m[2];
             if (strpos($m[1], '%') !== false) {
                 $m[1] = rawurldecode($m[1]);
             }
             $trail = "";
         } else {
             # Invalid form; output directly
             $s .= $prefix . '[[' . $line;
             wfProfileOut(__METHOD__ . "-e1");
             continue;
         }
         wfProfileOut(__METHOD__ . "-e1");
         wfProfileIn(__METHOD__ . "-misc");
         # Don't allow internal links to pages containing
         # PROTO: where PROTO is a valid URL protocol; these
         # should be external links.
         if (preg_match('/^(?:' . wfUrlProtocols() . ')/', $m[1])) {
             $s .= $prefix . '[[' . $line;
             wfProfileOut(__METHOD__ . "-misc");
             continue;
         }
         # Make subpage if necessary
         if ($useSubpages) {
             $link = $this->maybeDoSubpageLink($m[1], $text);
         } else {
             $link = $m[1];
         }
         $noforce = substr($m[1], 0, 1) !== ':';
         if (!$noforce) {
             # Strip off leading ':'
             $link = substr($link, 1);
         }
         wfProfileOut(__METHOD__ . "-misc");
         wfProfileIn(__METHOD__ . "-title");
         $nt = Title::newFromText($this->mStripState->unstripNoWiki($link));
         if ($nt === null) {
             $s .= $prefix . '[[' . $line;
             wfProfileOut(__METHOD__ . "-title");
             continue;
         }
         $ns = $nt->getNamespace();
         $iw = $nt->getInterWiki();
         wfProfileOut(__METHOD__ . "-title");
         if ($might_be_img) {
             # if this is actually an invalid link
             wfProfileIn(__METHOD__ . "-might_be_img");
             if ($ns == NS_FILE && $noforce) {
                 # but might be an image
                 $found = false;
                 while (true) {
                     # look at the next 'line' to see if we can close it there
                     $a->next();
                     $next_line = $a->current();
                     if ($next_line === false || $next_line === null) {
                         break;
                     }
                     $m = explode(']]', $next_line, 3);
                     if (count($m) == 3) {
                         # the first ]] closes the inner link, the second the image
                         $found = true;
                         $text .= "[[{$m[0]}]]{$m[1]}";
                         $trail = $m[2];
                         break;
                     } elseif (count($m) == 2) {
                         # if there's exactly one ]] that's fine, we'll keep looking
                         $text .= "[[{$m[0]}]]{$m[1]}";
                     } else {
                         # if $next_line is invalid too, we need look no further
                         $text .= '[[' . $next_line;
                         break;
                     }
                 }
                 if (!$found) {
                     # we couldn't find the end of this imageLink, so output it raw
                     # but don't ignore what might be perfectly normal links in the text we've examined
                     $holders->merge($this->replaceInternalLinks2($text));
                     $s .= "{$prefix}[[{$link}|{$text}";
                     # note: no $trail, because without an end, there *is* no trail
                     wfProfileOut(__METHOD__ . "-might_be_img");
                     continue;
                 }
             } else {
                 # it's not an image, so output it raw
                 $s .= "{$prefix}[[{$link}|{$text}";
                 # note: no $trail, because without an end, there *is* no trail
                 wfProfileOut(__METHOD__ . "-might_be_img");
                 continue;
             }
             wfProfileOut(__METHOD__ . "-might_be_img");
         }
         $wasblank = $text == '';
         if ($wasblank) {
             $text = $link;
         } else {
             # Bug 4598 madness. Handle the quotes only if they come from the alternate part
             # [[Lista d''e paise d''o munno]] -> <a href="...">Lista d''e paise d''o munno</a>
             # [[Criticism of Harry Potter|Criticism of ''Harry Potter'']]
             #    -> <a href="Criticism of Harry Potter">Criticism of <i>Harry Potter</i></a>
             $text = $this->doQuotes($text);
         }
         # Link not escaped by : , create the various objects
         if ($noforce) {
             global $wgContLang;
             # Interwikis
             if (empty($wgRTEParserEnabled)) {
                 # wikia
                 wfProfileIn(__METHOD__ . "-interwiki");
                 if ($iw && $this->mOptions->getInterwikiMagic() && $nottalk && $wgContLang->getLanguageName($iw)) {
                     $this->mOutput->addLanguageLink($nt->getFullText());
                     $s = rtrim($s . $prefix);
                     $s .= trim($trail, "\n") == '' ? '' : $prefix . $trail;
                     wfProfileOut(__METHOD__ . "-interwiki");
                     continue;
                 }
                 wfProfileOut(__METHOD__ . "-interwiki");
             }
             # wikia
             if ($ns == NS_FILE) {
                 wfProfileIn(__METHOD__ . "-image");
                 if (!wfIsBadImage($nt->getDBkey(), $this->mTitle)) {
                     if ($wasblank) {
                         # if no parameters were passed, $text
                         # becomes something like "File:Foo.png",
                         # which we don't want to pass on to the
                         # image generator
                         $text = '';
                     } else {
                         # recursively parse links inside the image caption
                         # actually, this will parse them in any other parameters, too,
                         # but it might be hard to fix that, and it doesn't matter ATM
                         $text = $this->replaceExternalLinks($text);
                         $holders->merge($this->replaceInternalLinks2($text));
                     }
                     # RTE (Rich Text Editor) - begin
                     # @author: Inez Korczyński
                     if (!empty($wgRTEParserEnabled)) {
                         $text = RTEMarker::generate(RTEMarker::IMAGE_DATA, $RTE_wikitextIdx) . $text;
                     }
                     # RTE - end
                     # cloak any absolute URLs inside the image markup, so replaceExternalLinks() won't touch them
                     /** wikia
                     				$s .= $prefix . $this->armorLinks(
                     					$this->makeImage( $nt, $text, $holders ) ) . $trail;
                     				wikia **/
                     # cater for new placeholder-in-template namespace -  Bartek
                     # TODO: Get the hell out with this code from here this can be done in hook handler fired in makeImage function - Inez
                     if ("Template Placeholder" != $nt->getText()) {
                         $s .= $prefix . $this->armorLinks($this->makeImage($nt, $text, $holders)) . $trail;
                     } else {
                         $s .= $prefix . $this->armorLinks(ImagePlaceholder_makeDullImage($nt, $text, $holders)) . $trail;
                     }
                 } else {
                     $s .= $prefix . $trail;
                 }
                 wfProfileOut(__METHOD__ . "-image");
                 continue;
             }
             if ($ns == NS_CATEGORY) {
                 wfProfileIn(__METHOD__ . "-category");
                 # RTE (Rich Text Editor) - begin
                 # @author: Inez Korczyński
                 # Category handling
                 if (!empty($wgRTEParserEnabled)) {
                     $dataIdx = RTEData::put('placeholder', array('type' => 'category', 'wikitextIdx' => $RTE_wikitextIdx));
                     $s .= $prefix . RTEMarker::generate(RTEMarker::PLACEHOLDER, $dataIdx) . $trail;
                 } else {
                     $s = rtrim($s . "\n");
                     # bug 87
                     if ($wasblank) {
                         $sortkey = $this->getDefaultSort();
                     } else {
                         $sortkey = $text;
                     }
                     $sortkey = Sanitizer::decodeCharReferences($sortkey);
                     $sortkey = str_replace("\n", '', $sortkey);
                     $sortkey = $this->getConverterLanguage()->convertCategoryKey($sortkey);
                     $this->mOutput->addCategory($nt->getDBkey(), $sortkey);
                     /**
                      * Strip the whitespace Category links produce, see bug 87
                      * @todo We might want to use trim($tmp, "\n") here.
                      */
                     $s .= trim($prefix . $trail, "\n") == '' ? '' : $prefix . $trail;
                 }
                 wfProfileOut(__METHOD__ . "-category");
                 continue;
             }
             # Wikia change begin
             # @author macbre
             $hookRet = wfRunHooks('ParserReplaceInternalLinks2NoForce', array(&$s, $nt, $prefix, $trail, isset($RTE_wikitextIdx) ? $RTE_wikitextIdx : null));
             if ($hookRet === false) {
                 continue;
             }
             # Wikia change end
         }
         # RTE (Rich Text Editor) - begin
         # @author: Inez Korczyński
         # No special handling for self-linking in RTE mode
         # Self-link checking
         if (empty($wgRTEParserEnabled) && $nt->getFragment() === '' && $ns != NS_SPECIAL) {
             if (in_array($nt->getPrefixedText(), $selflink, true)) {
                 $s .= $prefix . Linker::makeSelfLinkObj($nt, $text, '', $trail);
                 continue;
             }
         }
         # RTE - end
         # NS_MEDIA is a pseudo-namespace for linking directly to a file
         # @todo FIXME: Should do batch file existence checks, see comment below
         if ($ns == NS_MEDIA) {
             # RTE (Rich Text Editor) - begin
             # @author: macbre
             # BugId:1694 - handle [[Media:xxx]] as placeholders
             if (!empty($wgRTEParserEnabled)) {
                 $dataIdx = RTEData::put('placeholder', array('type' => 'media', 'wikitextIdx' => $RTE_wikitextIdx));
                 $s .= $prefix . RTEMarker::generate(RTEMarker::PLACEHOLDER, $dataIdx) . $trail;
                 continue;
             }
             # RTE - end
             wfProfileIn(__METHOD__ . "-media");
             # Give extensions a chance to select the file revision for us
             $options = array();
             $descQuery = false;
             wfRunHooks('BeforeParserFetchFileAndTitle', array($this, $nt, &$options, &$descQuery));
             # Fetch and register the file (file title may be different via hooks)
             list($file, $nt) = $this->fetchFileAndTitle($nt, $options);
             # Cloak with NOPARSE to avoid replacement in replaceExternalLinks
             $s .= $prefix . $this->armorLinks(Linker::makeMediaLinkFile($nt, $file, $text)) . $trail;
             wfProfileOut(__METHOD__ . "-media");
             continue;
         }
         wfProfileIn(__METHOD__ . "-always_known");
         # RTE (Rich Text Editor) - begin
         # @author: Inez Korczyński
         if (!empty($wgRTEParserEnabled)) {
             $text = RTEMarker::generate(RTEMarker::INTERNAL_DATA, RTEData::put('data', array('type' => 'internal', 'wikitextIdx' => $RTE_wikitextIdx, 'text' => $text, 'link' => $link, 'wasblank' => $wasblank, 'noforce' => $noforce))) . $text;
         }
         # RTE - end
         # Some titles, such as valid special pages or files in foreign repos, should
         # be shown as bluelinks even though they're not included in the page table
         #
         # @todo FIXME: isAlwaysKnown() can be expensive for file links; we should really do
         # batch file existence checks for NS_FILE and NS_MEDIA
         if ($iw == '' && $nt->isAlwaysKnown()) {
             $this->mOutput->addLink($nt);
             $s .= $this->makeKnownLinkHolder($nt, $text, array(), $trail, $prefix);
         } else {
             # Links will be added to the output link list after checking
             $s .= $holders->makeHolder($nt, $text, array(), $trail, $prefix);
         }
         wfProfileOut(__METHOD__ . "-always_known");
     }
     wfProfileOut(__METHOD__);
     return $holders;
 }
Example #21
0
 /**
  * Secure and split - main initialisation function for this object
  *
  * Assumes that mDbkeyform has been set, and is urldecoded
  * and uses underscores, but not otherwise munged.  This function
  * removes illegal characters, splits off the interwiki and
  * namespace prefixes, sets the other forms, and canonicalizes
  * everything.
  * @return bool true on success
  */
 private function secureAndSplit()
 {
     global $wgContLang, $wgLocalInterwiki, $wgCapitalLinks;
     # Initialisation
     static $rxTc = false;
     if (!$rxTc) {
         # % is needed as well
         $rxTc = '/[^' . Title::legalChars() . ']|%[0-9A-Fa-f]{2}/S';
     }
     $this->mInterwiki = $this->mFragment = '';
     $this->mNamespace = $this->mDefaultNamespace;
     # Usually NS_MAIN
     $dbkey = $this->mDbkeyform;
     # Strip Unicode bidi override characters.
     # Sometimes they slip into cut-n-pasted page titles, where the
     # override chars get included in list displays.
     $dbkey = str_replace("‎", '', $dbkey);
     // 200E LEFT-TO-RIGHT MARK
     $dbkey = str_replace("‏", '', $dbkey);
     // 200F RIGHT-TO-LEFT MARK
     # Clean up whitespace
     #
     $dbkey = preg_replace('/[ _]+/', '_', $dbkey);
     $dbkey = trim($dbkey, '_');
     if ('' == $dbkey) {
         return false;
     }
     if (false !== strpos($dbkey, UTF8_REPLACEMENT)) {
         # Contained illegal UTF-8 sequences or forbidden Unicode chars.
         return false;
     }
     $this->mDbkeyform = $dbkey;
     # Initial colon indicates main namespace rather than specified default
     # but should not create invalid {ns,title} pairs such as {0,Project:Foo}
     if (':' == $dbkey[0]) {
         $this->mNamespace = NS_MAIN;
         $dbkey = substr($dbkey, 1);
         # remove the colon but continue processing
         $dbkey = trim($dbkey, '_');
         # remove any subsequent whitespace
     }
     # Namespace or interwiki prefix
     $firstPass = true;
     do {
         $m = array();
         if (preg_match("/^(.+?)_*:_*(.*)\$/S", $dbkey, $m)) {
             $p = $m[1];
             if ($ns = $wgContLang->getNsIndex($p)) {
                 # Ordinary namespace
                 $dbkey = $m[2];
                 $this->mNamespace = $ns;
             } elseif ($this->getInterwikiLink($p)) {
                 if (!$firstPass) {
                     # Can't make a local interwiki link to an interwiki link.
                     # That's just crazy!
                     return false;
                 }
                 # Interwiki link
                 $dbkey = $m[2];
                 $this->mInterwiki = $wgContLang->lc($p);
                 # Redundant interwiki prefix to the local wiki
                 if (0 == strcasecmp($this->mInterwiki, $wgLocalInterwiki)) {
                     if ($dbkey == '') {
                         # Can't have an empty self-link
                         return false;
                     }
                     $this->mInterwiki = '';
                     $firstPass = false;
                     # Do another namespace split...
                     continue;
                 }
                 # If there's an initial colon after the interwiki, that also
                 # resets the default namespace
                 if ($dbkey !== '' && $dbkey[0] == ':') {
                     $this->mNamespace = NS_MAIN;
                     $dbkey = substr($dbkey, 1);
                 }
             }
             # If there's no recognized interwiki or namespace,
             # then let the colon expression be part of the title.
         }
         break;
     } while (true);
     # We already know that some pages won't be in the database!
     #
     if ('' != $this->mInterwiki || NS_SPECIAL == $this->mNamespace) {
         $this->mArticleID = 0;
     }
     $fragment = strstr($dbkey, '#');
     if (false !== $fragment) {
         $this->setFragment($fragment);
         $dbkey = substr($dbkey, 0, strlen($dbkey) - strlen($fragment));
         # remove whitespace again: prevents "Foo_bar_#"
         # becoming "Foo_bar_"
         $dbkey = preg_replace('/_*$/', '', $dbkey);
     }
     # Reject illegal characters.
     #
     if (preg_match($rxTc, $dbkey)) {
         return false;
     }
     /**
      * Pages with "/./" or "/../" appearing in the URLs will
      * often be unreachable due to the way web browsers deal
      * with 'relative' URLs. Forbid them explicitly.
      */
     if (strpos($dbkey, '.') !== false && ($dbkey === '.' || $dbkey === '..' || strpos($dbkey, './') === 0 || strpos($dbkey, '../') === 0 || strpos($dbkey, '/./') !== false || strpos($dbkey, '/../') !== false)) {
         return false;
     }
     /**
      * Magic tilde sequences? Nu-uh!
      */
     if (strpos($dbkey, '~~~') !== false) {
         return false;
     }
     /**
      * Limit the size of titles to 255 bytes.
      * This is typically the size of the underlying database field.
      * We make an exception for special pages, which don't need to be stored
      * in the database, and may edge over 255 bytes due to subpage syntax 
      * for long titles, e.g. [[Special:Block/Long name]]
      */
     if ($this->mNamespace != NS_SPECIAL && strlen($dbkey) > 255 || strlen($dbkey) > 512) {
         return false;
     }
     /**
      * Normally, all wiki links are forced to have
      * an initial capital letter so [[foo]] and [[Foo]]
      * point to the same place.
      *
      * Don't force it for interwikis, since the other
      * site might be case-sensitive.
      */
     if ($wgCapitalLinks && $this->mInterwiki == '') {
         $dbkey = $wgContLang->ucfirst($dbkey);
     }
     /**
      * Can't make a link to a namespace alone...
      * "empty" local links can only be self-links
      * with a fragment identifier.
      */
     if ($dbkey == '' && $this->mInterwiki == '' && $this->mNamespace != NS_MAIN) {
         return false;
     }
     // Any remaining initial :s are illegal.
     if ($dbkey !== '' && ':' == $dbkey[0]) {
         return false;
     }
     # Fill fields
     $this->mDbkeyform = $dbkey;
     $this->mUrlform = ilWikiUtil::wfUrlencode($dbkey);
     $this->mTextform = str_replace('_', ' ', $dbkey);
     return true;
 }
Example #22
0
 /**
  * Really do the upload
  * Checks are made in SpecialUpload::execute()
  * @access private
  */
 function processUpload()
 {
     global $wgUser, $wgOut;
     /* Check for PHP error if any, requires php 4.2 or newer */
     if ($this->mUploadError == 1) {
         $this->mainUploadForm(wfMsgHtml('largefileserver'));
         return;
     }
     /**
      * If there was no filename or a zero size given, give up quick.
      */
     if (trim($this->mOname) == '' || empty($this->mUploadSize)) {
         $this->mainUploadForm(wfMsgHtml('emptyfile'));
         return;
     }
     # Chop off any directories in the given filename
     if ($this->mDestFile) {
         $basename = wfBaseName($this->mDestFile);
     } else {
         $basename = wfBaseName($this->mOname);
     }
     /**
      * We'll want to blacklist against *any* 'extension', and use
      * only the final one for the whitelist.
      */
     list($partname, $ext) = $this->splitExtensions($basename);
     if (count($ext)) {
         $finalExt = $ext[count($ext) - 1];
     } else {
         $finalExt = '';
     }
     $fullExt = implode('.', $ext);
     # If there was more than one "extension", reassemble the base
     # filename to prevent bogus complaints about length
     if (count($ext) > 1) {
         for ($i = 0; $i < count($ext) - 1; $i++) {
             $partname .= '.' . $ext[$i];
         }
     }
     if (strlen($partname) < 3) {
         $this->mainUploadForm(wfMsgHtml('minlength'));
         return;
     }
     // WERELATE - added validation tests
     if (!$this->mLicense && !$this->mReUploading) {
         $this->uploadError("You must select a license (press the \"back button\" on your browser to correct this)");
         return;
     }
     /**
      * Filter out illegal characters, and try to make a legible name
      * out of it. We'll strip some silently that Title would die on.
      */
     $filtered = preg_replace("/[^" . Title::legalChars() . "]|:/", '-', $basename);
     $nt = Title::newFromText($filtered);
     if (is_null($nt)) {
         $this->uploadError(wfMsgWikiHtml('illegalfilename', htmlspecialchars($filtered)));
         return;
     }
     $nt =& Title::makeTitle(NS_IMAGE, $nt->getDBkey());
     $this->mUploadSaveName = $nt->getDBkey();
     /**
      * If the image is protected, non-sysop users won't be able
      * to modify it by uploading a new revision.
      */
     if (!$nt->userCanEdit()) {
         return $this->uploadError(wfMsgWikiHtml('protectedpage'));
     }
     /**
      * In some cases we may forbid overwriting of existing files.
      */
     $overwrite = $this->checkOverwrite($this->mUploadSaveName);
     if (WikiError::isError($overwrite)) {
         return $this->uploadError($overwrite->toString());
     }
     /* Don't allow users to override the blacklist (check file extension) */
     global $wgStrictFileExtensions;
     global $wgFileExtensions, $wgFileBlacklist;
     if ($this->checkFileExtensionList($ext, $wgFileBlacklist) || $wgStrictFileExtensions && !$this->checkFileExtension($finalExt, $wgFileExtensions)) {
         return $this->uploadError(wfMsgHtml('badfiletype', htmlspecialchars($fullExt)));
     }
     /**
      * Look at the contents of the file; if we can recognize the
      * type but it's corrupt or data of the wrong type, we should
      * probably not accept it.
      */
     if (!$this->mStashed) {
         $this->checkMacBinary();
         $veri = $this->verify($this->mUploadTempName, $finalExt);
         if ($veri !== true) {
             //it's a wiki error...
             return $this->uploadError($veri->toString());
         }
     }
     /**
      * Provide an opportunity for extensions to add futher checks
      */
     $error = '';
     if (!wfRunHooks('UploadVerification', array($this->mUploadSaveName, $this->mUploadTempName, &$error))) {
         return $this->uploadError($error);
     }
     /**
      * Check for non-fatal conditions
      */
     if (!$this->mIgnoreWarning) {
         $warning = '';
         global $wgCapitalLinks;
         if ($wgCapitalLinks) {
             $filtered = ucfirst($filtered);
         }
         if ($this->mUploadSaveName != $filtered) {
             $warning .= '<li>' . wfMsgHtml('badfilename', htmlspecialchars($this->mUploadSaveName)) . '</li>';
         }
         global $wgCheckFileExtensions;
         if ($wgCheckFileExtensions) {
             if (!$this->checkFileExtension($finalExt, $wgFileExtensions)) {
                 $warning .= '<li>' . wfMsgHtml('badfiletype', htmlspecialchars($fullExt)) . '</li>';
             }
         }
         global $wgUploadSizeWarning;
         if ($wgUploadSizeWarning && $this->mUploadSize > $wgUploadSizeWarning) {
             # TODO: Format $wgUploadSizeWarning to something that looks better than the raw byte
             # value, perhaps add GB,MB and KB suffixes?
             $warning .= '<li>' . wfMsgHtml('largefile', $wgUploadSizeWarning, $this->mUploadSize) . '</li>';
         }
         if ($this->mUploadSize == 0) {
             $warning .= '<li>' . wfMsgHtml('emptyfile') . '</li>';
         }
         if ($nt->getArticleID()) {
             global $wgUser;
             $sk = $wgUser->getSkin();
             $dlink = $sk->makeKnownLinkObj($nt);
             $warning .= '<li>' . wfMsgHtml('fileexists', $dlink) . '</li>';
             // WERELATE: added fileexistsnoreupload warning; assume that if user entered license, then this isn't a case of purposeful re-uploading
             if ($this->mLicense) {
                 $warning .= '<li>' . wfMsgHtml('fileexistsnoreupload') . '</li>';
             }
         } else {
             # If the file existed before and was deleted, warn the user of this
             # Don't bother doing so if the image exists now, however
             // WERELATE: remove
             //				$image = new Image( $nt );
             //				if( $image->wasDeleted() ) {
             //					$skin = $wgUser->getSkin();
             //					$ltitle = Title::makeTitle( NS_SPECIAL, 'Log' );
             //					$llink = $skin->makeKnownLinkObj( $ltitle, wfMsgHtml( 'deletionlog' ), 'type=delete&page=' . $nt->getPrefixedUrl() );
             //					$warning .= wfOpenElement( 'li' ) . wfMsgWikiHtml( 'filewasdeleted', $llink ) . wfCloseElement( 'li' );
             //				}
         }
         if ($warning != '') {
             /**
              * Stash the file in a temporary location; the user can choose
              * to let it through and we'll complete the upload then.
              */
             return $this->uploadWarning($warning);
         }
     }
     /**
      * Try actually saving the thing...
      * It will show an error form on failure.
      */
     $hasBeenMunged = !empty($this->mSessionKey) || $this->mRemoveTempFile;
     if ($this->saveUploadedFile($this->mUploadSaveName, $this->mUploadTempName, $hasBeenMunged)) {
         /**
          * Update the upload log and create the description page
          * if it's a new file.
          */
         $img = Image::newFromName($this->mUploadSaveName);
         // WERELATE - changed - added getMetadata, null out license (because we capture it in metadata), redirect only if target is empty
         $success = $img->recordUpload($this->mUploadOldVersion, $this->mUploadDescription, '', $this->mUploadCopyStatus, $this->mUploadSource, $this->mWatchthis, $this->getMetadata(), !$this->mTarget);
         if ($success) {
             // WERELATE - if we're uploading for a P/F target, showSuccess, else just redirect
             if ($this->mTarget) {
                 $this->showSuccess();
             } else {
                 $article = new Article($img->getTitle());
                 $article->doRedirect();
             }
             wfRunHooks('UploadComplete', array(&$img));
         } else {
             // Image::recordUpload() fails if the image went missing, which is
             // unlikely, hence the lack of a specialised message
             $wgOut->showFileNotFoundError($this->mUploadSaveName);
         }
     }
 }
Example #23
0
/**
 * Replace all invalid characters with -
 * Additional characters can be defined in $wgIllegalFileChars (see bug 20489)
 * By default, $wgIllegalFileChars = ':'
 *
 * @param string $name Filename to process
 * @return string
 */
function wfStripIllegalFilenameChars($name)
{
    global $wgIllegalFileChars;
    $illegalFileChars = $wgIllegalFileChars ? "|[" . $wgIllegalFileChars . "]" : '';
    $name = wfBaseName($name);
    $name = preg_replace("/[^" . Title::legalChars() . "]" . $illegalFileChars . "/", '-', $name);
    return $name;
}
Example #24
0
 private function buildSafeTitle($name)
 {
     $x = preg_replace_callback('/([^' . Title::legalChars() . ']|~)/', array($this, 'hexChar'), $name);
     $test = Title::makeTitleSafe(NS_FILE, $x);
     if (is_null($test) || $test->getDBkey() !== $x) {
         $this->error("Unable to generate safe title from '{$name}', got '{$x}'");
         return false;
     }
     return $x;
 }
Example #25
0
 /**
  * Pre-save transform helper function
  *
  * @param $text string
  * @param $user User
  *
  * @return string
  */
 private function pstPass2($text, $user)
 {
     global $wgContLang;
     # Note: This is the timestamp saved as hardcoded wikitext to
     # the database, we use $wgContLang here in order to give
     # everyone the same signature and use the default one rather
     # than the one selected in each user's preferences.
     # (see also bug 12815)
     $ts = $this->mOptions->getTimestamp();
     $timestamp = MWTimestamp::getLocalInstance($ts);
     $ts = $timestamp->format('YmdHis');
     $tzMsg = $timestamp->format('T');
     # might vary on DST changeover!
     # Allow translation of timezones through wiki. format() can return
     # whatever crap the system uses, localised or not, so we cannot
     # ship premade translations.
     $key = 'timezone-' . strtolower(trim($tzMsg));
     $msg = wfMessage($key)->inContentLanguage();
     if ($msg->exists()) {
         $tzMsg = $msg->text();
     }
     $d = $wgContLang->timeanddate($ts, false, false) . " ({$tzMsg})";
     # Variable replacement
     # Because mOutputType is OT_WIKI, this will only process {{subst:xxx}} type tags
     $text = $this->replaceVariables($text);
     # This works almost by chance, as the replaceVariables are done before the getUserSig(),
     # which may corrupt this parser instance via its wfMessage()->text() call-
     # Signatures
     $sigText = $this->getUserSig($user);
     $text = strtr($text, array('~~~~~' => $d, '~~~~' => "{$sigText} {$d}", '~~~' => $sigText));
     # Context links ("pipe tricks"): [[|name]] and [[name (context)|]]
     $tc = '[' . Title::legalChars() . ']';
     $nc = '[ _0-9A-Za-z\\x80-\\xff-]';
     # Namespaces can use non-ascii!
     $p1 = "/\\[\\[(:?{$nc}+:|:|)({$tc}+?)( ?\\({$tc}+\\))\\|]]/";
     # [[ns:page (context)|]]
     $p4 = "/\\[\\[(:?{$nc}+:|:|)({$tc}+?)( ?({$tc}+))\\|]]/";
     # [[ns:page(context)|]] (double-width brackets, added in r40257)
     $p3 = "/\\[\\[(:?{$nc}+:|:|)({$tc}+?)( ?\\({$tc}+\\)|)((?:, |,){$tc}+|)\\|]]/";
     # [[ns:page (context), context|]] (using either single or double-width comma)
     $p2 = "/\\[\\[\\|({$tc}+)]]/";
     # [[|page]] (reverse pipe trick: add context from page title)
     # try $p1 first, to turn "[[A, B (C)|]]" into "[[A, B (C)|A, B]]"
     $text = preg_replace($p1, '[[\\1\\2\\3|\\2]]', $text);
     $text = preg_replace($p4, '[[\\1\\2\\3|\\2]]', $text);
     $text = preg_replace($p3, '[[\\1\\2\\3\\4|\\2]]', $text);
     $t = $this->mTitle->getText();
     $m = array();
     if (preg_match("/^({$nc}+:|){$tc}+?( \\({$tc}+\\))\$/", $t, $m)) {
         $text = preg_replace($p2, "[[{$m['1']}\\1{$m['2']}|\\1]]", $text);
     } elseif (preg_match("/^({$nc}+:|){$tc}+?(, {$tc}+|)\$/", $t, $m) && "{$m['1']}{$m['2']}" != '') {
         $text = preg_replace($p2, "[[{$m['1']}\\1{$m['2']}|\\1]]", $text);
     } else {
         # if there's no context, don't bother duplicating the title
         $text = preg_replace($p2, '[[\\1]]', $text);
     }
     # Trim trailing whitespace
     $text = rtrim($text);
     return $text;
 }
	/**
	 * Parses a media link.
	 * This is a very small subset of Parser::replaceInternalLinks() that
	 * parses a single image or media link, and returns the parsed text,
	 * as well as a File instance of the referenced media, if available.
	 *
	 * @return Three-element array containing the matched parts of the link,
	 *   and the file object, or NULL.
	 */
	private static function parseMediaLink( &$parser, $text ) {
		$tc = Title::legalChars();
		if ( !preg_match( "/\\[\\[([{$tc}]+)(?:\\|(.+?))?]]/", $text, $m ) )
			return null;

		$nt = Title::newFromText( $m[1] );
		if ( !$nt )
			return null;

		$ns = $nt->getNamespace();
		if ( $ns == NS_IMAGE || $ns == NS_MEDIA ) {
			$parser->mOutput->addLink( $nt );
			return @ array( $m[1], $m[2], wfFindFile( $nt ) );
		} else {
			return null;
		}
	}
Example #27
0
 protected function appendGeneralInfo($property)
 {
     global $wgContLang;
     $config = $this->getConfig();
     $data = array();
     $mainPage = Title::newMainPage();
     $data['mainpage'] = $mainPage->getPrefixedText();
     $data['base'] = wfExpandUrl($mainPage->getFullURL(), PROTO_CURRENT);
     $data['sitename'] = $config->get('Sitename');
     // wgLogo can either be a relative or an absolute path
     // make sure we always return an absolute path
     $data['logo'] = wfExpandUrl($config->get('Logo'), PROTO_RELATIVE);
     $data['generator'] = "MediaWiki {$config->get('Version')}";
     $data['phpversion'] = PHP_VERSION;
     $data['phpsapi'] = PHP_SAPI;
     if (defined('HHVM_VERSION')) {
         $data['hhvmversion'] = HHVM_VERSION;
     }
     $data['dbtype'] = $config->get('DBtype');
     $data['dbversion'] = $this->getDB()->getServerVersion();
     $allowFrom = array('');
     $allowException = true;
     if (!$config->get('AllowExternalImages')) {
         $data['imagewhitelistenabled'] = (bool) $config->get('EnableImageWhitelist');
         $allowFrom = $config->get('AllowExternalImagesFrom');
         $allowException = !empty($allowFrom);
     }
     if ($allowException) {
         $data['externalimages'] = (array) $allowFrom;
         ApiResult::setIndexedTagName($data['externalimages'], 'prefix');
     }
     $data['langconversion'] = !$config->get('DisableLangConversion');
     $data['titleconversion'] = !$config->get('DisableTitleConversion');
     if ($wgContLang->linkPrefixExtension()) {
         $linkPrefixCharset = $wgContLang->linkPrefixCharset();
         $data['linkprefixcharset'] = $linkPrefixCharset;
         // For backwards compatibility
         $data['linkprefix'] = "/^((?>.*[^{$linkPrefixCharset}]|))(.+)\$/sDu";
     } else {
         $data['linkprefixcharset'] = '';
         $data['linkprefix'] = '';
     }
     $linktrail = $wgContLang->linkTrail();
     $data['linktrail'] = $linktrail ?: '';
     $data['legaltitlechars'] = Title::legalChars();
     global $IP;
     $git = SpecialVersion::getGitHeadSha1($IP);
     if ($git) {
         $data['git-hash'] = $git;
         $data['git-branch'] = SpecialVersion::getGitCurrentBranch($GLOBALS['IP']);
     } else {
         $svn = SpecialVersion::getSvnRevision($IP);
         if ($svn) {
             $data['rev'] = $svn;
         }
     }
     // 'case-insensitive' option is reserved for future
     $data['case'] = $config->get('CapitalLinks') ? 'first-letter' : 'case-sensitive';
     $data['lang'] = $config->get('LanguageCode');
     $fallbacks = array();
     foreach ($wgContLang->getFallbackLanguages() as $code) {
         $fallbacks[] = array('code' => $code);
     }
     $data['fallback'] = $fallbacks;
     ApiResult::setIndexedTagName($data['fallback'], 'lang');
     if ($wgContLang->hasVariants()) {
         $variants = array();
         foreach ($wgContLang->getVariants() as $code) {
             $variants[] = array('code' => $code, 'name' => $wgContLang->getVariantname($code));
         }
         $data['variants'] = $variants;
         ApiResult::setIndexedTagName($data['variants'], 'lang');
     }
     $data['rtl'] = $wgContLang->isRTL();
     $data['fallback8bitEncoding'] = $wgContLang->fallback8bitEncoding();
     $data['readonly'] = wfReadOnly();
     if ($data['readonly']) {
         $data['readonlyreason'] = wfReadOnlyReason();
     }
     $data['writeapi'] = (bool) $config->get('EnableWriteAPI');
     $tz = $config->get('Localtimezone');
     $offset = $config->get('LocalTZoffset');
     if (is_null($tz)) {
         $tz = 'UTC';
         $offset = 0;
     } elseif (is_null($offset)) {
         $offset = 0;
     }
     $data['timezone'] = $tz;
     $data['timeoffset'] = intval($offset);
     $data['articlepath'] = $config->get('ArticlePath');
     $data['scriptpath'] = $config->get('ScriptPath');
     $data['script'] = $config->get('Script');
     $data['variantarticlepath'] = $config->get('VariantArticlePath');
     $data[ApiResult::META_BC_BOOLS][] = 'variantarticlepath';
     $data['server'] = $config->get('Server');
     $data['servername'] = $config->get('ServerName');
     $data['wikiid'] = wfWikiID();
     $data['time'] = wfTimestamp(TS_ISO_8601, time());
     $data['misermode'] = (bool) $config->get('MiserMode');
     $data['maxuploadsize'] = UploadBase::getMaxUploadSize();
     $data['minuploadchunksize'] = (int) $this->getConfig()->get('MinUploadChunkSize');
     $data['thumblimits'] = $config->get('ThumbLimits');
     ApiResult::setArrayType($data['thumblimits'], 'BCassoc');
     ApiResult::setIndexedTagName($data['thumblimits'], 'limit');
     $data['imagelimits'] = array();
     ApiResult::setArrayType($data['imagelimits'], 'BCassoc');
     ApiResult::setIndexedTagName($data['imagelimits'], 'limit');
     foreach ($config->get('ImageLimits') as $k => $limit) {
         $data['imagelimits'][$k] = array('width' => $limit[0], 'height' => $limit[1]);
     }
     $favicon = $config->get('Favicon');
     if (!empty($favicon)) {
         // wgFavicon can either be a relative or an absolute path
         // make sure we always return an absolute path
         $data['favicon'] = wfExpandUrl($favicon, PROTO_RELATIVE);
     }
     Hooks::run('APIQuerySiteInfoGeneralInfo', array($this, &$data));
     return $this->getResult()->addValue('query', $property, $data);
 }
Example #28
0
/**
 * Replace all invalid characters with -
 * @param mixed $title Filename to process
 */
function wfStripIllegalFilenameChars($name)
{
    $name = wfBaseName($name);
    $name = preg_replace("/[^" . Title::legalChars() . "]|:/", '-', $name);
    return $name;
}
Example #29
0
 public static function makeTitleValid($text)
 {
     $text = self::stripWikitext($text);
     $text = html_entity_decode($text, ENT_QUOTES, 'UTF-8');
     static $rxTc;
     if (is_callable('MediaWikiTitleCodec::getTitleInvalidRegex')) {
         $rxTc = MediaWikiTitleCodec::getTitleInvalidRegex();
     } elseif (is_callable(array('Title', 'getTitleInvalidRegex'))) {
         // Pre-1.25 compat
         $rxTc = Title::getTitleInvalidRegex();
     } elseif (!$rxTc) {
         // Back-compat
         $rxTc = '/' . '[^' . Title::legalChars() . ']' . '|%[0-9A-Fa-f]{2}' . '|&[A-Za-z0-9\\x80-\\xff]+;' . '|&#[0-9]+;' . '|&#x[0-9A-Fa-f]+;' . '/S';
     }
     $text = preg_replace($rxTc, '_', $text);
     return $text;
 }
Example #30
0
 /**
  * Add a new video file into the mediawiki infrastructure so that it can
  * be accessed as {{whvid|filename.mp4|Preview.jpg}}
  */
 public function addWikiHowVideo($articleId, &$video)
 {
     // find name for video; change filename to Filename 1.jpg if
     // Filename.jpg already existed
     $regexp = '/[^' . Title::legalChars() . ']+/';
     $first = preg_replace($regexp, '', $video['first']);
     // Let's also remove " and ' since s3 doesn't seem to like
     $first = preg_replace('/["\']+/', '', $first);
     $ext = $video['ext'];
     $newName = $first . '.' . $ext;
     $i = 1;
     do {
         if (!WikiVideo::fileExists($newName)) {
             break;
         }
         $newName = $first . ' Version ' . ++$i . '.' . $ext;
     } while ($i <= 1000);
     // Move the file from one s3 bucket to another
     $ret = WikiVideo::copyFileToProd(WikiVisualTranscoder::AWS_TRANSCODING_OUT_BUCKET, $video['aws_uri_out'], $newName);
     if ($ret['error']) {
         return $ret['error'];
     }
     // instruct later processing about which mediawiki name was used
     $video['mediawikiName'] = $newName;
     // Add preview image
     $img = $video;
     $img['ext'] = 'jpg';
     $err = Mp4Transcoder::addMediawikiImage($articleId, $img);
     if ($err) {
         return 'Unable to add preview image: ' . $err;
     } else {
         $video['previewMediawikiName'] = $img['mediawikiName'];
         // Cleanup temporary preview image
         if (!empty($img['filename'])) {
             $rmCmd = "rm " . $img['filename'];
             system($rmCmd);
         }
     }
     self::d(">>> addWikiHowVideo: video['mediawikiName']=" . $video['mediawikiName'] . ", video['previewMediawikiName']=" . $video['previewMediawikiName']);
     // Keep a log of where videos were uploaded in wikivideo_video_names table
     $dbw = WikiVisualTranscoder::getDB('write');
     $vidname = $articleID . '/' . $video['name'];
     $sql = 'INSERT INTO wikivisual_vid_names SET filename=' . $dbw->addQuotes($vidname) . ', wikiname=' . $dbw->addQuotes($video['mediawikiName']);
     $dbw->query($sql, __METHOD__);
     return '';
 }