/** * Process internal links * * string $s string that includes internal wiki links * int $a_wiki_id wiki id * mode */ static function processInternalLinks($s, $a_wiki_id, $a_mode = IL_WIKI_MODE_REPLACE, $a_collect_non_ex = false, $a_offline = false) { $collect = array(); // both from mediawiki DefaulSettings.php $wgLegalTitleChars = " %!\"\$&'()*,\\-.\\/0-9:;=?@A-Z\\\\^_`a-z~\\x80-\\xFF+"; // Adapter for media wiki classes include_once "./Modules/Wiki/classes/class.ilMediaWikiAdapter.php"; $GLOBALS["wgContLang"] = new ilMediaWikiAdapter(); $GLOBALS["wgInterWikiCache"] = false; # the % is needed to support urlencoded titles as well //$tc = Title::legalChars().'#%'; $tc = $wgLegalTitleChars . '#%'; //$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 $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"; } # 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' ); /* $useLinkPrefixExtension = $wgContLang->linkPrefixExtension(); if( is_null( $this->mTitle ) ) { throw new MWException( __METHOD__.": \$this->mTitle is null\n" ); } $nottalk = !$this->mTitle->isTalkPage();*/ $nottalk = true; /* 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' ); */ $useSubpages = false; # 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('<', '>'), 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(?:' . ilWikiUtil::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" ); // todo include_once "./Modules/Wiki/mediawiki/Title.php"; include_once "./Services/Utilities/classes/Sanitizer.php"; //$nt = Title::newFromText( $this->mStripState->unstripNoWiki($link) ); // todo: check step by step //echo "<br>".htmlentities($link)."---"; $nt = Title::newFromText($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 ) { $s .= $this->makeKnownLinkHolder( $nt, $text, '', $trail, $prefix ); continue; } elseif( $ns == NS_IMAGE ) { $img = new Image( $nt ); if( $img->exists() ) { // 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; } }*/ // Media wiki performs an intermediate step here (Parser->makeLinkHolder) if ($a_mode == IL_WIKI_MODE_REPLACE) { $s .= ilWikiUtil::makeLink($nt, $a_wiki_id, $text, '', $trail, $prefix, $a_offline); //echo "<br>-".htmlentities($s)."-"; } if ($a_mode == IL_WIKI_MODE_EXT_COLLECT) { if (is_object($nt)) { $url_title = ilWikiUtil::makeUrlTitle($nt->mTextform); $db_title = ilWikiUtil::makeDbTitle($nt->mTextform); list($inside, $trail) = ilWikiUtil::splitTrail($trail); $collect[] = array("nt" => $nt, "text" => $text, "trail" => $trail, "db_title" => $db_title, "url_title" => $url_title); } } else { $url_title = ilWikiUtil::makeUrlTitle($nt->mTextform); $db_title = ilWikiUtil::makeDbTitle($nt->mTextform); //$s .= ilWikiUtil::makeLink($nt, $a_wiki_id, $text, '', $trail, $prefix); include_once "./Modules/Wiki/classes/class.ilWikiPage.php"; if ((ilWikiPage::_wikiPageExists($a_wiki_id, $db_title) || $a_collect_non_ex) && !in_array($db_title, $collect)) { $collect[] = $db_title; } } } //wfProfileOut( $fname ); if ($a_mode == IL_WIKI_MODE_COLLECT || $a_mode == IL_WIKI_MODE_EXT_COLLECT) { return $collect; } else { return $s; } }