예제 #1
0
 /**
  * Lightweight method to get the parser output for a page, checking the parser cache
  * and so on. Doesn't consider most of the stuff that WikiPage::view is forced to
  * consider, so it's not appropriate to use there.
  *
  * @since 1.16 (r52326) for LiquidThreads
  *
  * @param $oldid mixed integer Revision ID or null
  * @param $user User The relevant user
  * @return ParserOutput or false if the given revsion ID is not found
  */
 public function getParserOutput($oldid = null, User $user = null)
 {
     global $wgEnableParserCache, $wgUser;
     $user = is_null($user) ? $wgUser : $user;
     wfProfileIn(__METHOD__);
     // Should the parser cache be used?
     $useParserCache = $wgEnableParserCache && $user->getStubThreshold() == 0 && $this->mPage->exists() && $oldid === null;
     wfDebug(__METHOD__ . ': using parser cache: ' . ($useParserCache ? 'yes' : 'no') . "\n");
     if ($user->getStubThreshold()) {
         wfIncrStats('pcache_miss_stub');
     }
     if ($useParserCache) {
         $parserOutput = ParserCache::singleton()->get($this, $this->mPage->getParserOptions());
         if ($parserOutput !== false) {
             wfProfileOut(__METHOD__);
             return $parserOutput;
         }
     }
     // Cache miss; parse and output it.
     if ($oldid === null) {
         $text = $this->mPage->getRawText();
     } else {
         $rev = Revision::newFromTitle($this->getTitle(), $oldid);
         if ($rev === null) {
             wfProfileOut(__METHOD__);
             return false;
         }
         $text = $rev->getText();
     }
     wfProfileOut(__METHOD__);
     return $this->getOutputFromWikitext($text, $useParserCache);
 }
 /**
  * Constructor
  *
  * @param WikiPage $page Page we are updating
  * @throws MWException
  */
 function __construct(WikiPage $page)
 {
     parent::__construct(false);
     // no implicit transaction
     $this->mPage = $page;
     if (!$page->exists()) {
         throw new MWException("Page ID not known, perhaps the page doesn't exist?");
     }
 }
예제 #3
0
function filter_antispam($formatter, $value, $options)
{
    global $Config;
    $blacklist_pages = array('BadContent', 'LocalBadContent');
    $whitelist_pages = array('GoodContent', 'LocalGoodContent');
    if (!in_array($formatter->page->name, $blacklist_pages) and !in_array($formatter->page->name, $whitelist_pages)) {
        $badcontents_file = !empty($options['.badcontents']) ? $options['.badcontents'] : $Config['badcontents'];
        if (!file_exists($badcontents_file)) {
            return $value;
        }
        $badcontent = file_get_contents($badcontents_file);
        foreach ($blacklist_pages as $list) {
            $p = new WikiPage($list);
            if ($p->exists()) {
                $badcontent .= $p->get_raw_body();
            }
        }
        if (!$badcontent) {
            return $value;
        }
        $badcontents = explode("\n", $badcontent);
        $pattern[0] = '';
        $i = 0;
        foreach ($badcontents as $line) {
            if (isset($line[0]) and $line[0] == '#') {
                continue;
            }
            $line = preg_replace('/[ ]*#.*$/', '', $line);
            $test = @preg_match("/{$line}/i", "");
            if ($test === false) {
                $line = preg_quote($line, '/');
            }
            if ($line) {
                $pattern[$i] .= $line . '|';
            }
            if (strlen($pattern[$i]) > 4000) {
                $i++;
                $pattern[$i] = '';
            }
        }
        for ($k = 0; $k <= $i; $k++) {
            $pattern[$k] = '/(' . substr($pattern[$k], 0, -1) . ')/i';
        }
        #foreach ($whitelist_pages as $list) {
        #    $p=new WikiPage($list);
        #    if ($p->exists()) $goodcontent.=$p->get_raw_body();
        #}
        #$goodcontents=explode("\n",$goodcontent);
        return preg_replace($pattern, "''''''[[HTML(<span class='blocked'>)]]\\1[[HTML(</span>)]]''''''", $value);
    }
    return $value;
}
예제 #4
0
 /**
  * @param WikiPage $page Page we are updating
  * @param integer|null $pageId ID of the page we are updating [optional]
  * @throws MWException
  */
 function __construct(WikiPage $page, $pageId = null)
 {
     parent::__construct(false);
     // no implicit transaction
     $this->page = $page;
     if ($page->exists()) {
         $this->pageId = $page->getId();
     } elseif ($pageId) {
         $this->pageId = $pageId;
     } else {
         throw new MWException("Page ID not known, perhaps the page doesn't exist?");
     }
 }
예제 #5
0
 /**
  * @param WikiPage $page Page we are updating
  * @param integer|null $pageId ID of the page we are updating [optional]
  * @param string|null $timestamp TS_MW timestamp of deletion
  * @throws MWException
  */
 function __construct(WikiPage $page, $pageId = null, $timestamp = null)
 {
     parent::__construct();
     $this->page = $page;
     if ($pageId) {
         $this->pageId = $pageId;
         // page ID at time of deletion
     } elseif ($page->exists()) {
         $this->pageId = $page->getId();
     } else {
         throw new InvalidArgumentException("Page ID not known. Page doesn't exist?");
     }
     $this->timestamp = $timestamp ?: wfTimestampNow();
 }
 protected function createPage($page, $text, $model = null)
 {
     if (is_string($page)) {
         $page = Title::newFromText($page);
     }
     if ($page instanceof Title) {
         $page = new WikiPage($page);
     }
     if ($page->exists()) {
         $page->doDeleteArticle("done");
     }
     $page->doEdit($text, "testing", EDIT_NEW);
     return $page;
 }
예제 #7
0
 protected function createPage($page, $text, $model = null)
 {
     if (is_string($page)) {
         if (!preg_match('/:/', $page) && ($model === null || $model === CONTENT_MODEL_WIKITEXT)) {
             $ns = $this->getDefaultWikitextNS();
             $page = MWNamespace::getCanonicalName($ns) . ':' . $page;
         }
         $page = Title::newFromText($page);
     }
     if ($page instanceof Title) {
         $page = new WikiPage($page);
     }
     if ($page->exists()) {
         $page->doDeleteArticle("done");
     }
     $content = ContentHandler::makeContent($text, $page->getTitle(), $model);
     $page->doEditContent($content, "testing", EDIT_NEW);
     return $page;
 }
예제 #8
0
 /**
  * Clear the cache when the page is edited
  */
 public static function onArticleSaveComplete(WikiPage &$page, &$user, $text, $summary, $minoredit, $watchthis, $sectionanchor, &$flags, $revision, &$status, $baseRevId)
 {
     /**
      * @var $service ArticleService
      */
     if ($page->exists()) {
         $id = $page->getId();
         F::app()->wg->Memc->delete(self::getCacheKey($id));
         if (array_key_exists($id, self::$localCache)) {
             unset(self::$localCache[$id]);
         }
     }
     return true;
 }
예제 #9
0
function macro_FullSearch($formatter, $value = "", &$opts)
{
    global $DBInfo;
    $needle = $value;
    if ($value === true) {
        $needle = $value = $formatter->page->name;
        $options['noexpr'] = 1;
    } else {
        # for MoinMoin compatibility with [[FullSearch("blah blah")]]
        #$needle = preg_replace("/^('|\")([^\\1]*)\\1/","\\2",$value);
        $needle = $value;
    }
    // for pagination
    $offset = '';
    if (!empty($opts['offset']) and is_numeric($opts['offset'])) {
        if ($opts['offset'] > 0) {
            $offset = $opts['offset'];
        }
    }
    $url = $formatter->link_url($formatter->page->urlname);
    $fneedle = _html_escape($needle);
    $tooshort = !empty($DBInfo->fullsearch_tooshort) ? $DBInfo->fullsearch_tooshort : 2;
    $m1 = _("Display context of search results");
    $m2 = _("Search BackLinks only");
    $m3 = _("Case-sensitive searching");
    $msg = _("Go");
    $bchecked = !empty($DBInfo->use_backlinks) ? 'checked="checked"' : '';
    $form = <<<EOF
<form method='get' action='{$url}'>
   <input type='hidden' name='action' value='fullsearch' />
   <input name='value' size='30' value="{$fneedle}" />
   <span class='button'><input type='submit' class='button' value='{$msg}' /></span><br />
   <input type='checkbox' name='backlinks' value='1' {$bchecked} />{$m2}<br />
   <input type='checkbox' name='context' value='20' />{$m1}<br />
   <input type='checkbox' name='case' value='1' />{$m3}<br />
   </form>
EOF;
    if (!isset($needle[0]) or !empty($opts['form'])) {
        # or blah blah
        $opts['msg'] = _("No search text");
        return $form;
    }
    $opts['form'] = $form;
    # XXX
    $excl = array();
    $incl = array();
    if (!empty($opts['noexpr'])) {
        $tmp = preg_split("/\\s+/", $needle);
        $needle = $value = join('|', $tmp);
        $raw_needle = implode(' ', $tmp);
        $needle = preg_quote($needle);
    } else {
        if (empty($opts['backlinks'])) {
            $terms = preg_split('/((?<!\\S)[-+]?"[^"]+?"(?!\\S)|\\S+)/s', $needle, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
            $common_words = array('the', 'that', 'where', 'what', 'who', 'how', 'too', 'are');
            $common = array();
            foreach ($terms as $term) {
                if (trim($term) == '') {
                    continue;
                }
                if (preg_match('/^([-+]?)("?)([^\\2]+?)\\2$/', $term, $match)) {
                    $word = str_replace(array('\\', '.', '*'), '', $match[3]);
                    $len = strlen($word);
                    if (!$match[1] and $match[2] != '"') {
                        if ($len < $tooshort or in_array($word, $common_words)) {
                            $common[] = $word;
                            continue;
                        }
                    }
                    if ($match[1] == '-') {
                        $excl[] = $word;
                    } else {
                        $incl[] = $word;
                    }
                }
            }
            $needle = implode('|', $incl);
            $needle = _preg_search_escape($needle);
            $raw_needle = implode(' ', $incl);
            $test = validate_needle($needle);
            if ($test === false) {
                // invalid regex
                $tmp = array_map('preg_quote', $incl);
                $needle = implode('|', $tmp);
            }
            $excl_needle = implode('|', $excl);
            $test = validate_needle($excl_needle);
            if ($test2 === false) {
                // invalid regex
                $tmp = array_map('preg_quote', $excl);
                $excl_needle = implode('|', $tmp);
            }
        } else {
            $cneedle = _preg_search_escape($needle);
            $test = validate_needle($cneedle);
            if ($test === false) {
                $needle = preg_quote($needle);
            } else {
                $needle = $cneedle;
            }
        }
    }
    $test3 = trim($needle);
    if (!isset($test3[0])) {
        $opts['msg'] = _("Empty expression");
        return $form;
    }
    # set arena and sid
    if (!empty($opts['backlinks'])) {
        $arena = 'backlinks';
    } else {
        if (!empty($opts['keywords'])) {
            $arena = 'keywords';
        } else {
            $arena = 'fullsearch';
        }
    }
    if ($arena == 'fullsearch') {
        $sid = md5($value . 'v' . $offset);
    } else {
        $sid = $value;
    }
    $delay = !empty($DBInfo->default_delaytime) ? $DBInfo->default_delaytime : 0;
    # retrieve cache
    $fc = new Cache_text($arena);
    if (!$formatter->refresh and $fc->exists($sid)) {
        $data = $fc->fetch($sid);
        if (!empty($opts['backlinks'])) {
            // backlinks are not needed to check it.
            $hits = $data;
            // also fetch redirects
            $r = new Cache_Text('redirects');
            $redirects = $r->fetch($sid);
        } else {
            if (is_array($data)) {
                # check cache mtime
                $cmt = $fc->mtime($sid);
                # check update or not
                $dmt = $DBInfo->mtime();
                if ($dmt > $cmt + $delay) {
                    # XXX crude method
                    $data = array();
                } else {
                    # XXX smart but incomplete method
                    if (isset($data['hits'])) {
                        $hits =& $data['hits'];
                    } else {
                        $hits =& $data;
                    }
                    foreach ($hits as $p => $c) {
                        $mp = $DBInfo->getPage($p);
                        $mt = $mp->mtime();
                        if ($mt > $cmt + $delay) {
                            $data = array();
                            break;
                        }
                    }
                }
                if (isset($data['searched'])) {
                    extract($data);
                } else {
                    if (!empty($data)) {
                        $hits = $data;
                    }
                }
            }
        }
    }
    $pattern = '/' . $needle . '/';
    if (!empty($excl_needle)) {
        $excl_pattern = '/' . $excl_needle . '/';
    }
    if (!empty($opts['case'])) {
        $pattern .= "i";
        $excl_pattern .= "i";
    }
    if (isset($hits)) {
        if (in_array($arena, array('backlinks', 'keywords'))) {
            $test = key($hits);
            if (is_int($test) and $hits[$test] != -1) {
                // fix compatible issue for keywords, backlinks
                $hits = array_flip($hits);
                foreach ($hits as $k => $v) {
                    $hits[$k] = -1;
                }
                reset($hits);
            }
            // check invert redirect index
            if (!empty($redirects)) {
                $redirects = array_flip($redirects);
                ksort($redirects);
                foreach ($redirects as $k => $v) {
                    $hits[$k] = -2;
                }
                reset($hits);
            }
        }
        //continue;
    } else {
        $hits = array();
        set_time_limit(0);
        if (!empty($opts['backlinks']) and empty($DBInfo->use_backlink_search)) {
            $hits = array();
        } else {
            if (!empty($opts['keywords']) and empty($DBInfo->use_keyword_search)) {
                $hits = array();
            } else {
                if (!empty($opts['backlinks'])) {
                    $pages = $DBInfo->getPageLists();
                    #$opts['context']=-1; # turn off context-matching
                    $cache = new Cache_text("pagelinks");
                    foreach ($pages as $page_name) {
                        $links = $cache->fetch($page_name);
                        if (is_array($links)) {
                            if (in_array($value, $links)) {
                                $hits[$page_name] = -1;
                            }
                            // ignore count if < 0
                        }
                    }
                } else {
                    if (!empty($opts['keywords'])) {
                        $pages = $DBInfo->getPageLists();
                        $opts['context'] = -1;
                        # turn off context-matching
                        $cache = new Cache_text("keyword");
                        foreach ($pages as $page_name) {
                            $links = $cache->fetch($page_name);
                            // XXX
                            if (is_array($links)) {
                                if (stristr(implode(' ', $links), $needle)) {
                                    $hits[$page_name] = -1;
                                }
                                // ignore count if < 0
                            }
                        }
                    } else {
                        $params = array();
                        $ret = array();
                        $params['ret'] =& $ret;
                        $params['offset'] = $offset;
                        $params['search'] = 1;
                        $params['incl'] = $incl;
                        $params['excl'] = $excl;
                        $pages = $DBInfo->getPageLists($params);
                        // set time_limit
                        $mt = explode(' ', microtime());
                        $timestamp = $mt[0] + $mt[1];
                        $j = 0;
                        $time_limit = isset($DBInfo->process_time_limit) ? $DBInfo->process_time_limit : 3;
                        // default 3-seconds
                        $j = 0;
                        while (list($_, $page_name) = each($pages)) {
                            // check time_limit
                            if ($time_limit and $j % 30 == 0) {
                                $mt = explode(' ', microtime());
                                $now = $mt[0] + $mt[1];
                                if ($now - $timestamp > $time_limit) {
                                    break;
                                }
                            }
                            $j++;
                            $p = new WikiPage($page_name);
                            if (!$p->exists()) {
                                continue;
                            }
                            $body = $p->_get_raw_body();
                            #$count = count(preg_split($pattern, $body))-1;
                            $count = preg_match_all($pattern, $body, $matches);
                            if ($count) {
                                foreach ($excl as $ex) {
                                    if (stristr($body, $ex)) {
                                        continue;
                                    }
                                }
                                foreach ($incl as $in) {
                                    if (!stristr($body, $in)) {
                                        continue;
                                    }
                                }
                                $hits[$page_name] = $count;
                            }
                        }
                        $searched = $j > 0 ? $j : 0;
                        $offset = !empty($offset) ? $offset + $j : $j;
                    }
                }
            }
        }
        #krsort($hits);
        #ksort($hits);
        $name = array_keys($hits);
        array_multisort($hits, SORT_DESC, $name, SORT_ASC);
        if (in_array($arena, array('backlinks', 'keywords'))) {
            $fc->update($sid, $name);
        } else {
            $fc->update($sid, array('hits' => $hits, 'offset' => $offset, 'searched' => $searched));
        }
    }
    $opts['hits'] = $hits;
    $opts['hit'] = count($hits);
    $opts['all'] = $DBInfo->getCounter();
    if ($opts['all'] > $searched) {
        $opts['next'] = $offset;
        $opts['searched'] = $searched;
    }
    if (!empty($opts['call'])) {
        return $hits;
    }
    $out = "<!-- RESULT LIST START -->";
    // for search plugin
    $out .= "<ul class='fullsearchResult'>";
    $idx = 1;
    $checkbox = '';
    while (list($page_name, $count) = each($hits)) {
        $pgname = _html_escape($page_name);
        if (!empty($opts['checkbox'])) {
            $checkbox = "<input type='checkbox' name='pagenames[]' value=\"{$pgname}\" />";
        }
        $out .= '<!-- RESULT ITEM START -->';
        // for search plugin
        $out .= '<li>' . $checkbox . $formatter->link_tag(_rawurlencode($page_name), '?action=highlight&amp;value=' . _urlencode($value), $pgname, 'tabindex="' . $idx . '"');
        if ($count > 0) {
            $out .= ' . . . . ' . sprintf($count == 1 ? _("%d match") : _("%d matches"), $count);
        } else {
            if ($count == -2) {
                $out .= " <span class='redirectIcon'><span>" . _("Redirect page") . "</span></span>\n";
            }
        }
        if (!empty($opts['context']) and $opts['context'] > 0) {
            # search matching contexts
            $p = new WikiPage($page_name);
            if ($p->exists()) {
                $body = $p->_get_raw_body();
                $out .= find_needle($body, $needle, $excl_needle, $opts['context']);
            }
        }
        $out .= "</li>\n";
        $out .= '<!-- RESULT ITEM END -->';
        // for search plugin
        $idx++;
        #if ($idx > 50) break;
    }
    $out .= "</ul>\n";
    $out .= "<!-- RESULT LIST END -->";
    // for search plugin
    return $out;
}
 /**
  * @covers WikiPage::exists
  */
 public function testExists()
 {
     $page = $this->newPage("WikiPageTest_testExists");
     $this->assertFalse($page->exists());
     # -----------------
     $this->createPage($page, "some text", CONTENT_MODEL_WIKITEXT);
     $this->assertTrue($page->exists());
     $page = new WikiPage($page->getTitle());
     $this->assertTrue($page->exists());
     # -----------------
     $page->doDeleteArticle("done testing");
     $this->assertFalse($page->exists());
     $page = new WikiPage($page->getTitle());
     $this->assertFalse($page->exists());
 }
예제 #11
0
function latex_ref($page, $appearance, $hover = '')
{
    global $db;
    if ($hover != '') {
        $hover = ' title="' . $hover . '"';
    }
    $p = new WikiPage($db, $page);
    if ($p->exists()) {
        //    return '<a href="' . viewURL($page) . '"' . $hover . '>' . $page . '</a>';
        return '\\textbf{' . $page . '}';
    } else {
        return '\\textbf{' . $appearance . $hover . "}";
    }
}
예제 #12
0
 /**
  * Attempt submission (no UI)
  *
  * @param array $result Array to add statuses to, currently with the
  *   possible keys:
  *   - spam (string): Spam string from content if any spam is detected by
  *     matchSpamRegex.
  *   - sectionanchor (string): Section anchor for a section save.
  *   - nullEdit (boolean): Set if doEditContent is OK.  True if null edit,
  *     false otherwise.
  *   - redirect (bool): Set if doEditContent is OK. True if resulting
  *     revision is a redirect.
  * @param bool $bot True if edit is being made under the bot right.
  *
  * @return Status Status object, possibly with a message, but always with
  *   one of the AS_* constants in $status->value,
  *
  * @todo FIXME: This interface is TERRIBLE, but hard to get rid of due to
  *   various error display idiosyncrasies. There are also lots of cases
  *   where error metadata is set in the object and retrieved later instead
  *   of being returned, e.g. AS_CONTENT_TOO_BIG and
  *   AS_BLOCKED_PAGE_FOR_USER. All that stuff needs to be cleaned up some
  * time.
  */
 function internalAttemptSave(&$result, $bot = false)
 {
     global $wgUser, $wgRequest, $wgParser, $wgMaxArticleSize;
     global $wgContentHandlerUseDB;
     $status = Status::newGood();
     if (!Hooks::run('EditPage::attemptSave', array($this))) {
         wfDebug("Hook 'EditPage::attemptSave' aborted article saving\n");
         $status->fatal('hookaborted');
         $status->value = self::AS_HOOK_ERROR;
         return $status;
     }
     $spam = $wgRequest->getText('wpAntispam');
     if ($spam !== '') {
         wfDebugLog('SimpleAntiSpam', $wgUser->getName() . ' editing "' . $this->mTitle->getPrefixedText() . '" submitted bogus field "' . $spam . '"');
         $status->fatal('spamprotectionmatch', false);
         $status->value = self::AS_SPAM_ERROR;
         return $status;
     }
     try {
         # Construct Content object
         $textbox_content = $this->toEditContent($this->textbox1);
     } catch (MWContentSerializationException $ex) {
         $status->fatal('content-failed-to-parse', $this->contentModel, $this->contentFormat, $ex->getMessage());
         $status->value = self::AS_PARSE_ERROR;
         return $status;
     }
     # Check image redirect
     if ($this->mTitle->getNamespace() == NS_FILE && $textbox_content->isRedirect() && !$wgUser->isAllowed('upload')) {
         $code = $wgUser->isAnon() ? self::AS_IMAGE_REDIRECT_ANON : self::AS_IMAGE_REDIRECT_LOGGED;
         $status->setResult(false, $code);
         return $status;
     }
     # Check for spam
     $match = self::matchSummarySpamRegex($this->summary);
     if ($match === false && $this->section == 'new') {
         # $wgSpamRegex is enforced on this new heading/summary because, unlike
         # regular summaries, it is added to the actual wikitext.
         if ($this->sectiontitle !== '') {
             # This branch is taken when the API is used with the 'sectiontitle' parameter.
             $match = self::matchSpamRegex($this->sectiontitle);
         } else {
             # This branch is taken when the "Add Topic" user interface is used, or the API
             # is used with the 'summary' parameter.
             $match = self::matchSpamRegex($this->summary);
         }
     }
     if ($match === false) {
         $match = self::matchSpamRegex($this->textbox1);
     }
     if ($match !== false) {
         $result['spam'] = $match;
         $ip = $wgRequest->getIP();
         $pdbk = $this->mTitle->getPrefixedDBkey();
         $match = str_replace("\n", '', $match);
         wfDebugLog('SpamRegex', "{$ip} spam regex hit [[{$pdbk}]]: \"{$match}\"");
         $status->fatal('spamprotectionmatch', $match);
         $status->value = self::AS_SPAM_ERROR;
         return $status;
     }
     if (!Hooks::run('EditFilter', array($this, $this->textbox1, $this->section, &$this->hookError, $this->summary))) {
         # Error messages etc. could be handled within the hook...
         $status->fatal('hookaborted');
         $status->value = self::AS_HOOK_ERROR;
         return $status;
     } elseif ($this->hookError != '') {
         # ...or the hook could be expecting us to produce an error
         $status->fatal('hookaborted');
         $status->value = self::AS_HOOK_ERROR_EXPECTED;
         return $status;
     }
     if ($wgUser->isBlockedFrom($this->mTitle, false)) {
         // Auto-block user's IP if the account was "hard" blocked
         $wgUser->spreadAnyEditBlock();
         # Check block state against master, thus 'false'.
         $status->setResult(false, self::AS_BLOCKED_PAGE_FOR_USER);
         return $status;
     }
     $this->kblength = (int) (strlen($this->textbox1) / 1024);
     if ($this->kblength > $wgMaxArticleSize) {
         // Error will be displayed by showEditForm()
         $this->tooBig = true;
         $status->setResult(false, self::AS_CONTENT_TOO_BIG);
         return $status;
     }
     if (!$wgUser->isAllowed('edit')) {
         if ($wgUser->isAnon()) {
             $status->setResult(false, self::AS_READ_ONLY_PAGE_ANON);
             return $status;
         } else {
             $status->fatal('readonlytext');
             $status->value = self::AS_READ_ONLY_PAGE_LOGGED;
             return $status;
         }
     }
     $changingContentModel = false;
     if ($this->contentModel !== $this->mTitle->getContentModel()) {
         if (!$wgContentHandlerUseDB) {
             $status->fatal('editpage-cannot-use-custom-model');
             $status->value = self::AS_CANNOT_USE_CUSTOM_MODEL;
             return $status;
         } elseif (!$wgUser->isAllowed('editcontentmodel')) {
             $status->setResult(false, self::AS_NO_CHANGE_CONTENT_MODEL);
             return $status;
         }
         $changingContentModel = true;
         $oldContentModel = $this->mTitle->getContentModel();
     }
     if ($this->changeTags) {
         $changeTagsStatus = ChangeTags::canAddTagsAccompanyingChange($this->changeTags, $wgUser);
         if (!$changeTagsStatus->isOK()) {
             $changeTagsStatus->value = self::AS_CHANGE_TAG_ERROR;
             return $changeTagsStatus;
         }
     }
     if (wfReadOnly()) {
         $status->fatal('readonlytext');
         $status->value = self::AS_READ_ONLY_PAGE;
         return $status;
     }
     if ($wgUser->pingLimiter() || $wgUser->pingLimiter('linkpurge', 0)) {
         $status->fatal('actionthrottledtext');
         $status->value = self::AS_RATE_LIMITED;
         return $status;
     }
     # If the article has been deleted while editing, don't save it without
     # confirmation
     if ($this->wasDeletedSinceLastEdit() && !$this->recreate) {
         $status->setResult(false, self::AS_ARTICLE_WAS_DELETED);
         return $status;
     }
     # Load the page data from the master. If anything changes in the meantime,
     # we detect it by using page_latest like a token in a 1 try compare-and-swap.
     $this->page->loadPageData('fromdbmaster');
     $new = !$this->page->exists();
     if ($new) {
         // Late check for create permission, just in case *PARANOIA*
         if (!$this->mTitle->userCan('create', $wgUser)) {
             $status->fatal('nocreatetext');
             $status->value = self::AS_NO_CREATE_PERMISSION;
             wfDebug(__METHOD__ . ": no create permission\n");
             return $status;
         }
         // Don't save a new page if it's blank or if it's a MediaWiki:
         // message with content equivalent to default (allow empty pages
         // in this case to disable messages, see bug 50124)
         $defaultMessageText = $this->mTitle->getDefaultMessageText();
         if ($this->mTitle->getNamespace() === NS_MEDIAWIKI && $defaultMessageText !== false) {
             $defaultText = $defaultMessageText;
         } else {
             $defaultText = '';
         }
         if (!$this->allowBlankArticle && $this->textbox1 === $defaultText) {
             $this->blankArticle = true;
             $status->fatal('blankarticle');
             $status->setResult(false, self::AS_BLANK_ARTICLE);
             return $status;
         }
         if (!$this->runPostMergeFilters($textbox_content, $status, $wgUser)) {
             return $status;
         }
         $content = $textbox_content;
         $result['sectionanchor'] = '';
         if ($this->section == 'new') {
             if ($this->sectiontitle !== '') {
                 // Insert the section title above the content.
                 $content = $content->addSectionHeader($this->sectiontitle);
             } elseif ($this->summary !== '') {
                 // Insert the section title above the content.
                 $content = $content->addSectionHeader($this->summary);
             }
             $this->summary = $this->newSectionSummary($result['sectionanchor']);
         }
         $status->value = self::AS_SUCCESS_NEW_ARTICLE;
     } else {
         # not $new
         # Article exists. Check for edit conflict.
         $this->page->clear();
         # Force reload of dates, etc.
         $timestamp = $this->page->getTimestamp();
         wfDebug("timestamp: {$timestamp}, edittime: {$this->edittime}\n");
         if ($timestamp != $this->edittime) {
             $this->isConflict = true;
             if ($this->section == 'new') {
                 if ($this->page->getUserText() == $wgUser->getName() && $this->page->getComment() == $this->newSectionSummary()) {
                     // Probably a duplicate submission of a new comment.
                     // This can happen when CDN resends a request after
                     // a timeout but the first one actually went through.
                     wfDebug(__METHOD__ . ": duplicate new section submission; trigger edit conflict!\n");
                 } else {
                     // New comment; suppress conflict.
                     $this->isConflict = false;
                     wfDebug(__METHOD__ . ": conflict suppressed; new section\n");
                 }
             } elseif ($this->section == '' && Revision::userWasLastToEdit(DB_MASTER, $this->mTitle->getArticleID(), $wgUser->getId(), $this->edittime)) {
                 # Suppress edit conflict with self, except for section edits where merging is required.
                 wfDebug(__METHOD__ . ": Suppressing edit conflict, same user.\n");
                 $this->isConflict = false;
             }
         }
         // If sectiontitle is set, use it, otherwise use the summary as the section title.
         if ($this->sectiontitle !== '') {
             $sectionTitle = $this->sectiontitle;
         } else {
             $sectionTitle = $this->summary;
         }
         $content = null;
         if ($this->isConflict) {
             wfDebug(__METHOD__ . ": conflict! getting section '{$this->section}' for time '{$this->edittime}'" . " (article time '{$timestamp}')\n");
             $content = $this->page->replaceSectionContent($this->section, $textbox_content, $sectionTitle, $this->edittime);
         } else {
             wfDebug(__METHOD__ . ": getting section '{$this->section}'\n");
             $content = $this->page->replaceSectionContent($this->section, $textbox_content, $sectionTitle);
         }
         if (is_null($content)) {
             wfDebug(__METHOD__ . ": activating conflict; section replace failed.\n");
             $this->isConflict = true;
             $content = $textbox_content;
             // do not try to merge here!
         } elseif ($this->isConflict) {
             # Attempt merge
             if ($this->mergeChangesIntoContent($content)) {
                 // Successful merge! Maybe we should tell the user the good news?
                 $this->isConflict = false;
                 wfDebug(__METHOD__ . ": Suppressing edit conflict, successful merge.\n");
             } else {
                 $this->section = '';
                 $this->textbox1 = ContentHandler::getContentText($content);
                 wfDebug(__METHOD__ . ": Keeping edit conflict, failed merge.\n");
             }
         }
         if ($this->isConflict) {
             $status->setResult(false, self::AS_CONFLICT_DETECTED);
             return $status;
         }
         if (!$this->runPostMergeFilters($content, $status, $wgUser)) {
             return $status;
         }
         if ($this->section == 'new') {
             // Handle the user preference to force summaries here
             if (!$this->allowBlankSummary && trim($this->summary) == '') {
                 $this->missingSummary = true;
                 $status->fatal('missingsummary');
                 // or 'missingcommentheader' if $section == 'new'. Blegh
                 $status->value = self::AS_SUMMARY_NEEDED;
                 return $status;
             }
             // Do not allow the user to post an empty comment
             if ($this->textbox1 == '') {
                 $this->missingComment = true;
                 $status->fatal('missingcommenttext');
                 $status->value = self::AS_TEXTBOX_EMPTY;
                 return $status;
             }
         } elseif (!$this->allowBlankSummary && !$content->equals($this->getOriginalContent($wgUser)) && !$content->isRedirect() && md5($this->summary) == $this->autoSumm) {
             $this->missingSummary = true;
             $status->fatal('missingsummary');
             $status->value = self::AS_SUMMARY_NEEDED;
             return $status;
         }
         # All's well
         $sectionanchor = '';
         if ($this->section == 'new') {
             $this->summary = $this->newSectionSummary($sectionanchor);
         } elseif ($this->section != '') {
             # Try to get a section anchor from the section source, redirect
             # to edited section if header found.
             # XXX: Might be better to integrate this into Article::replaceSection
             # for duplicate heading checking and maybe parsing.
             $hasmatch = preg_match("/^ *([=]{1,6})(.*?)(\\1) *\\n/i", $this->textbox1, $matches);
             # We can't deal with anchors, includes, html etc in the header for now,
             # headline would need to be parsed to improve this.
             if ($hasmatch && strlen($matches[2]) > 0) {
                 $sectionanchor = $wgParser->guessLegacySectionNameFromWikiText($matches[2]);
             }
         }
         $result['sectionanchor'] = $sectionanchor;
         // Save errors may fall down to the edit form, but we've now
         // merged the section into full text. Clear the section field
         // so that later submission of conflict forms won't try to
         // replace that into a duplicated mess.
         $this->textbox1 = $this->toEditText($content);
         $this->section = '';
         $status->value = self::AS_SUCCESS_UPDATE;
     }
     if (!$this->allowSelfRedirect && $content->isRedirect() && $content->getRedirectTarget()->equals($this->getTitle())) {
         // If the page already redirects to itself, don't warn.
         $currentTarget = $this->getCurrentContent()->getRedirectTarget();
         if (!$currentTarget || !$currentTarget->equals($this->getTitle())) {
             $this->selfRedirect = true;
             $status->fatal('selfredirect');
             $status->value = self::AS_SELF_REDIRECT;
             return $status;
         }
     }
     // Check for length errors again now that the section is merged in
     $this->kblength = (int) (strlen($this->toEditText($content)) / 1024);
     if ($this->kblength > $wgMaxArticleSize) {
         $this->tooBig = true;
         $status->setResult(false, self::AS_MAX_ARTICLE_SIZE_EXCEEDED);
         return $status;
     }
     $flags = EDIT_AUTOSUMMARY | ($new ? EDIT_NEW : EDIT_UPDATE) | ($this->minoredit && !$this->isNew ? EDIT_MINOR : 0) | ($bot ? EDIT_FORCE_BOT : 0);
     $doEditStatus = $this->page->doEditContent($content, $this->summary, $flags, false, $wgUser, $content->getDefaultFormat(), $this->changeTags);
     if (!$doEditStatus->isOK()) {
         // Failure from doEdit()
         // Show the edit conflict page for certain recognized errors from doEdit(),
         // but don't show it for errors from extension hooks
         $errors = $doEditStatus->getErrorsArray();
         if (in_array($errors[0][0], array('edit-gone-missing', 'edit-conflict', 'edit-already-exists'))) {
             $this->isConflict = true;
             // Destroys data doEdit() put in $status->value but who cares
             $doEditStatus->value = self::AS_END;
         }
         return $doEditStatus;
     }
     $result['nullEdit'] = $doEditStatus->hasMessage('edit-no-change');
     if ($result['nullEdit']) {
         // We don't know if it was a null edit until now, so increment here
         $wgUser->pingLimiter('linkpurge');
     }
     $result['redirect'] = $content->isRedirect();
     $this->updateWatchlist();
     // If the content model changed, add a log entry
     if ($changingContentModel) {
         $this->addContentModelChangeLogEntry($wgUser, $oldContentModel, $this->contentModel, $this->summary);
     }
     return $status;
 }
예제 #13
0
function html_ref($page, $appearance, $hover = '', $anchor = '', $anchor_appearance = '')
{
    global $db, $SeparateLinkWords;
    if ($hover != '') {
        $hover = ' title="' . $hover . '"';
    }
    $p = new WikiPage($db, $page);
    if ($p->exists()) {
        if ($SeparateLinkWords && $page == $appearance) {
            $appearance = html_split_name($page);
        }
        return '<a href="' . viewURL($page) . $anchor . '"' . $hover . '>' . $appearance . $anchor_appearance . '</a>';
    } else {
        if (validate_page($page) == 1 && $appearance == $page) {
            return $page . '<a href="' . editURL($page) . '"' . $hover . '>?</a>';
        } else {
            return '(' . $appearance . ')<a href="' . editURL($page) . '"' . $hover . '>?</a>';
        }
    }
}
예제 #14
0
 /**
  * This is the default action of the index.php entry point: just view the
  * page of the given title.
  */
 public function view()
 {
     global $wgUser, $wgOut, $wgRequest, $wgParser;
     global $wgUseFileCache, $wgUseETag, $wgDebugToolbar;
     wfProfileIn(__METHOD__);
     # Get variables from query string
     # As side effect this will load the revision and update the title
     # in a revision ID is passed in the request, so this should remain
     # the first call of this method even if $oldid is used way below.
     $oldid = $this->getOldID();
     # Another whitelist check in case getOldID() is altering the title
     $permErrors = $this->getTitle()->getUserPermissionsErrors('read', $wgUser);
     if (count($permErrors)) {
         wfDebug(__METHOD__ . ": denied on secondary read check\n");
         wfProfileOut(__METHOD__);
         throw new PermissionsError('read', $permErrors);
     }
     # getOldID() may as well want us to redirect somewhere else
     if ($this->mRedirectUrl) {
         $wgOut->redirect($this->mRedirectUrl);
         wfDebug(__METHOD__ . ": redirecting due to oldid\n");
         wfProfileOut(__METHOD__);
         return;
     }
     # If we got diff in the query, we want to see a diff page instead of the article.
     if ($wgRequest->getCheck('diff')) {
         wfDebug(__METHOD__ . ": showing diff page\n");
         $this->showDiffPage();
         wfProfileOut(__METHOD__);
         return;
     }
     # Set page title (may be overridden by DISPLAYTITLE)
     $wgOut->setPageTitle($this->getTitle()->getPrefixedText());
     $wgOut->setArticleFlag(true);
     # Allow frames by default
     $wgOut->allowClickjacking();
     $parserCache = ParserCache::singleton();
     $parserOptions = $this->getParserOptions();
     # Render printable version, use printable version cache
     if ($wgOut->isPrintable()) {
         $parserOptions->setIsPrintable(true);
         $parserOptions->setEditSection(false);
     } elseif (!$this->isCurrent() || !$this->getTitle()->quickUserCan('edit')) {
         $parserOptions->setEditSection(false);
     }
     # Try client and file cache
     if (!$wgDebugToolbar && $oldid === 0 && $this->mPage->checkTouched()) {
         if ($wgUseETag) {
             $wgOut->setETag($parserCache->getETag($this, $parserOptions));
         }
         # Is it client cached?
         if ($wgOut->checkLastModified($this->mPage->getTouched())) {
             wfDebug(__METHOD__ . ": done 304\n");
             wfProfileOut(__METHOD__);
             return;
             # Try file cache
         } elseif ($wgUseFileCache && $this->tryFileCache()) {
             wfDebug(__METHOD__ . ": done file cache\n");
             # tell wgOut that output is taken care of
             $wgOut->disable();
             $this->mPage->doViewUpdates($wgUser);
             wfProfileOut(__METHOD__);
             return;
         }
     }
     # Should the parser cache be used?
     $useParserCache = $this->mPage->isParserCacheUsed($parserOptions, $oldid);
     wfDebug('Article::view using parser cache: ' . ($useParserCache ? 'yes' : 'no') . "\n");
     if ($wgUser->getStubThreshold()) {
         wfIncrStats('pcache_miss_stub');
     }
     $this->showRedirectedFromHeader();
     $this->showNamespaceHeader();
     # Iterate through the possible ways of constructing the output text.
     # Keep going until $outputDone is set, or we run out of things to do.
     $pass = 0;
     $outputDone = false;
     $this->mParserOutput = false;
     while (!$outputDone && ++$pass) {
         switch ($pass) {
             case 1:
                 wfRunHooks('ArticleViewHeader', array(&$this, &$outputDone, &$useParserCache));
                 break;
             case 2:
                 # Early abort if the page doesn't exist
                 if (!$this->mPage->exists()) {
                     wfDebug(__METHOD__ . ": showing missing article\n");
                     $this->showMissingArticle();
                     wfProfileOut(__METHOD__);
                     /* Wikia change begin - @author: Marcin, #BugId: 30436 */
                     $text = '';
                     if (wfRunHooks('ArticleNonExistentPage', array(&$this, $wgOut, &$text))) {
                         $this->mParserOutput = $wgParser->parse($text, $this->getTitle(), $parserOptions);
                         $wgOut->addParserOutput($this->mParserOutput);
                     }
                     /* Wikia change end */
                     return;
                 }
                 # Try the parser cache
                 if ($useParserCache) {
                     $this->mParserOutput = $parserCache->get($this, $parserOptions);
                     //Wikia Change
                     Transaction::setAttribute(Transaction::PARAM_PARSER_CACHE_USED, $this->mParserOutput !== false);
                     //Wikia Change End
                     if ($this->mParserOutput !== false) {
                         if ($oldid) {
                             wfDebug(__METHOD__ . ": showing parser cache contents for current rev permalink\n");
                             $this->setOldSubtitle($oldid);
                         } else {
                             wfDebug(__METHOD__ . ": showing parser cache contents\n");
                         }
                         $wgOut->addParserOutput($this->mParserOutput);
                         // Wikia change - begin - @author: wladek
                         wfRunHooks('ArticleViewAddParserOutput', array($this, $this->mParserOutput));
                         // Wikia change - end
                         # Ensure that UI elements requiring revision ID have
                         # the correct version information.
                         $wgOut->setRevisionId($this->mPage->getLatest());
                         # Preload timestamp to avoid a DB hit
                         $cachedTimestamp = $this->mParserOutput->getTimestamp();
                         if ($cachedTimestamp !== null) {
                             $wgOut->setRevisionTimestamp($cachedTimestamp);
                             $this->mPage->setTimestamp($cachedTimestamp);
                         }
                         $outputDone = true;
                     }
                     // Wikia change - begin - @author: wladek
                 } else {
                     Transaction::setAttribute(Transaction::PARAM_PARSER_CACHE_USED, false);
                     // Wikia change - end
                 }
                 break;
             case 3:
                 # This will set $this->mRevision if needed
                 $this->fetchContent();
                 // Wikia change - begin
                 // @author macbre
                 // return status different than HTTP 200 when revision is missing (BAC-630)
                 if (!$this->mRevision instanceof Revision) {
                     global $wgEnableParserCache;
                     wfDebug(__METHOD__ . ": no revision found - disabling parser cache and returning 404\n");
                     $wgOut->getRequest()->response()->header('X-Missing-Revision: 1', true, 404);
                     $useParserCache = false;
                     $wgEnableParserCache = false;
                 }
                 // Wikia change - end
                 # Are we looking at an old revision
                 if ($oldid && $this->mRevision) {
                     $this->setOldSubtitle($oldid);
                     if (!$this->showDeletedRevisionHeader()) {
                         wfDebug(__METHOD__ . ": cannot view deleted revision\n");
                         wfProfileOut(__METHOD__);
                         return;
                     }
                 }
                 # Ensure that UI elements requiring revision ID have
                 # the correct version information.
                 $wgOut->setRevisionId($this->getRevIdFetched());
                 # Preload timestamp to avoid a DB hit
                 $wgOut->setRevisionTimestamp($this->getTimestamp());
                 # Pages containing custom CSS or JavaScript get special treatment
                 if ($this->getTitle()->isCssOrJsPage() || $this->getTitle()->isCssJsSubpage()) {
                     wfDebug(__METHOD__ . ": showing CSS/JS source\n");
                     $this->showCssOrJsPage();
                     $outputDone = true;
                 } elseif (!wfRunHooks('ArticleViewCustom', array($this->mContent, $this->getTitle(), $wgOut))) {
                     # Allow extensions do their own custom view for certain pages
                     $outputDone = true;
                 } else {
                     $text = $this->getContent();
                     $rt = Title::newFromRedirectArray($text);
                     if ($rt) {
                         wfDebug(__METHOD__ . ": showing redirect=no page\n");
                         # Viewing a redirect page (e.g. with parameter redirect=no)
                         $wgOut->addHTML($this->viewRedirect($rt));
                         # Parse just to get categories, displaytitle, etc.
                         $this->mParserOutput = $wgParser->parse($text, $this->getTitle(), $parserOptions);
                         $wgOut->addParserOutputNoText($this->mParserOutput);
                         $outputDone = true;
                     }
                 }
                 break;
             case 4:
                 # Run the parse, protected by a pool counter
                 wfDebug(__METHOD__ . ": doing uncached parse\n");
                 $poolArticleView = new PoolWorkArticleView($this, $parserOptions, $this->getRevIdFetched(), $useParserCache, $this->getContent());
                 if (!$poolArticleView->execute()) {
                     $error = $poolArticleView->getError();
                     if ($error) {
                         $wgOut->clearHTML();
                         // for release() errors
                         $wgOut->enableClientCache(false);
                         $wgOut->setRobotPolicy('noindex,nofollow');
                         $errortext = $error->getWikiText(false, 'view-pool-error');
                         $wgOut->addWikiText('<div class="errorbox">' . $errortext . '</div>');
                     }
                     # Connection or timeout error
                     wfProfileOut(__METHOD__);
                     return;
                 }
                 $this->mParserOutput = $poolArticleView->getParserOutput();
                 $wgOut->addParserOutput($this->mParserOutput);
                 // Wikia change - begin - @author: wladek
                 Transaction::setAttribute(Transaction::PARAM_PARSER_CACHE_USED, $poolArticleView->getIsDirty());
                 wfRunHooks('ArticleViewAddParserOutput', array($this, $this->mParserOutput));
                 // Wikia change - end
                 # Don't cache a dirty ParserOutput object
                 if ($poolArticleView->getIsDirty()) {
                     $wgOut->setSquidMaxage(0);
                     $wgOut->addHTML("<!-- parser cache is expired, sending anyway due to pool overload-->\n");
                 }
                 # <Wikia>
                 if (!$poolArticleView->getIsDirty()) {
                     wfRunHooks('ArticleViewAfterParser', array($this, $this->mParserOutput));
                 }
                 # </Wikia>
                 $outputDone = true;
                 break;
                 # Should be unreachable, but just in case...
             # Should be unreachable, but just in case...
             default:
                 break 2;
         }
     }
     # Get the ParserOutput actually *displayed* here.
     # Note that $this->mParserOutput is the *current* version output.
     $pOutput = $outputDone instanceof ParserOutput ? $outputDone : $this->mParserOutput;
     # Adjust title for main page & pages with displaytitle
     if ($pOutput) {
         $this->adjustDisplayTitle($pOutput);
         if ($pOutput->getText() == '') {
             \Wikia\Logger\WikiaLogger::instance()->error('PLATFORM-1212 - empty parser output');
         }
     }
     # For the main page, overwrite the <title> element with the con-
     # tents of 'pagetitle-view-mainpage' instead of the default (if
     # that's not empty).
     # This message always exists because it is in the i18n files
     if ($this->getTitle()->isMainPage()) {
         $msg = wfMessage('pagetitle-view-mainpage')->inContentLanguage();
         if (!$msg->isDisabled()) {
             $wgOut->setHTMLTitle($msg->title($this->getTitle())->text());
         }
     }
     # Check for any __NOINDEX__ tags on the page using $pOutput
     $policy = $this->getRobotPolicy('view', $pOutput);
     $wgOut->setIndexPolicy($policy['index']);
     $wgOut->setFollowPolicy($policy['follow']);
     $this->showViewFooter();
     $this->mPage->doViewUpdates($wgUser);
     wfProfileOut(__METHOD__);
 }
예제 #15
0
 /**
  * Create or edit a group
  */
 public function html_group(&$q)
 {
     global $wgOut, $wgUser, $wgScript, $haclgHaloScriptPath, $wgContLang, $haclgContLang;
     $grpTitle = $grpArticle = $grpName = $grpPrefix = NULL;
     if (!empty($q['group'])) {
         $pe = IACLDefinition::nameOfPE($q['group']);
         $t = Title::newFromText($q['group'], HACL_NS_ACL);
         if ($t && $pe[0] == IACL::PE_GROUP) {
             $a = new WikiPage($t);
             if ($a->exists()) {
                 $grpTitle = $t;
                 $grpArticle = $a;
                 $grpPrefix = $haclgContLang->getPetPrefix(IACL::PE_GROUP);
                 $grpName = $pe[1];
             }
         }
     }
     /* Run template */
     ob_start();
     require dirname(__FILE__) . '/../templates/HACL_GroupEditor.tpl.php';
     $html = ob_get_contents();
     ob_end_clean();
     $wgOut->addModules('ext.intraacl.groupeditor');
     $wgOut->setPageTitle($grpTitle ? wfMsg('hacl_grp_editing', $grpTitle->getText()) : wfMsg('hacl_grp_creating'));
     $wgOut->addHTML($html);
 }
 function approveEditById($id)
 {
     $dbw = wfGetDB(DB_MASTER);
     $row = $dbw->selectRow('moderation', array('mod_id AS id', 'mod_timestamp AS timestamp', 'mod_user AS user', 'mod_user_text AS user_text', 'mod_cur_id AS cur_id', 'mod_namespace AS namespace', 'mod_title AS title', 'mod_comment AS comment', 'mod_minor AS minor', 'mod_bot AS bot', 'mod_last_oldid AS last_oldid', 'mod_ip AS ip', 'mod_header_xff AS header_xff', 'mod_header_ua AS header_ua', 'mod_text AS text', 'mod_merged_revid AS merged_revid', 'mod_rejected AS rejected', 'mod_stash_key AS stash_key'), array('mod_id' => $id), __METHOD__);
     if (!$row) {
         throw new ModerationError('moderation-edit-not-found');
     }
     if ($row->merged_revid) {
         throw new ModerationError('moderation-already-merged');
     }
     if ($row->rejected && $row->timestamp < $this->mSpecial->earliestReapprovableTimestamp) {
         throw new ModerationError('moderation-rejected-long-ago');
     }
     # Prepare everything
     $title = Title::makeTitle($row->namespace, $row->title);
     $model = $title->getContentModel();
     $user = $row->user ? User::newFromId($row->user) : User::newFromName($row->user_text, false);
     $flags = EDIT_DEFER_UPDATES | EDIT_AUTOSUMMARY;
     if ($row->bot && $user->isAllowed('bot')) {
         $flags |= EDIT_FORCE_BOT;
     }
     if ($row->minor) {
         # doEditContent() checks the right
         $flags |= EDIT_MINOR;
     }
     # For CheckUser extension to work properly, IP, XFF and UA
     # should be set to the correct values for the original user
     # (not from the moderator)
     $cuHook = new ModerationCheckUserHook();
     $cuHook->install($row->ip, $row->header_xff, $row->header_ua);
     $approveHook = new ModerationApproveHook();
     $approveHook->install(array('rev_timestamp' => $dbw->timestamp($row->timestamp), 'rev_user' => $user->getId(), 'rev_user_text' => $user->getName()));
     $status = Status::newGood();
     if ($row->stash_key) {
         # This is the upload from stash.
         $stash = RepoGroup::singleton()->getLocalRepo()->getUploadStash($user);
         try {
             $file = $stash->getFile($row->stash_key);
         } catch (MWException $e) {
             throw new ModerationError('moderation-missing-stashed-image');
         }
         $upload = new UploadFromStash($user, $stash);
         $upload->initialize($row->stash_key, $title->getText());
         $status = $upload->performUpload($row->comment, $row->text, 0, $user);
     } else {
         # This is normal edit (not an upload).
         $new_content = ContentHandler::makeContent($row->text, null, $model);
         $page = new WikiPage($title);
         if (!$page->exists()) {
             # New page
             $status = $page->doEditContent($new_content, $row->comment, $flags, false, $user);
         } else {
             # Existing page
             $latest = $page->getLatest();
             if ($latest == $row->last_oldid) {
                 # Page hasn't changed since this edit was queued for moderation.
                 $status = $page->doEditContent($new_content, $row->comment, $flags, $row->last_oldid, $user);
             } else {
                 # Page has changed!
                 # Let's attempt merging, as MediaWiki does in private EditPage::mergeChangesIntoContent().
                 $base_content = $row->last_oldid ? Revision::newFromId($row->last_oldid)->getContent(Revision::RAW) : ContentHandler::makeContent('', null, $model);
                 $latest_content = Revision::newFromId($latest)->getContent(Revision::RAW);
                 $handler = ContentHandler::getForModelID($base_content->getModel());
                 $merged_content = $handler->merge3($base_content, $new_content, $latest_content);
                 if ($merged_content) {
                     $status = $page->doEditContent($merged_content, $row->comment, $flags, $latest, $user);
                 } else {
                     $dbw = wfGetDB(DB_MASTER);
                     $dbw->update('moderation', array('mod_conflict' => 1), array('mod_id' => $id), __METHOD__);
                     $dbw->commit(__METHOD__);
                     throw new ModerationError('moderation-edit-conflict');
                 }
             }
         }
     }
     $approveHook->deinstall();
     $cuHook->deinstall();
     if (!$status->isGood()) {
         throw new ModerationError($status->getMessage());
     }
     $logEntry = new ManualLogEntry('moderation', 'approve');
     $logEntry->setPerformer($this->moderator);
     $logEntry->setTarget($title);
     $logEntry->setParameters(array('revid' => $approveHook->lastRevId));
     $logid = $logEntry->insert();
     $logEntry->publish($logid);
     # Approved edits are removed from "moderation" table,
     # because they already exist in page history, recentchanges etc.
     $dbw = wfGetDB(DB_MASTER);
     $dbw->delete('moderation', array('mod_id' => $id), __METHOD__);
 }
예제 #17
0
function do_post_fixbacklinks($formatter, $options = array())
{
    global $DBInfo;
    if ($_SERVER['REQUEST_METHOD'] == 'POST' && !$DBInfo->security->writable($options)) {
        $options['title'] = _("Page is not writable");
        return do_invalid($formatter, $options);
    }
    $options['name'] = trim($options['name']);
    $new = $options['name'];
    if (!empty($DBInfo->use_namespace) and $new[0] == '~' and ($p = strpos($new, '/')) !== false) {
        // Namespace renaming ~foo/bar -> foo~bar
        $dummy = substr($new, 1, $p - 1);
        $dummy2 = substr($new, $p + 1);
        $options['name'] = $dummy . '~' . $dummy2;
    }
    if (isset($options['name'][0]) and $options['name']) {
        if ($DBInfo->hasPage($options['name'])) {
            $formatter->send_header('', $options);
            $new_encodedname = _rawurlencode($options['name']);
            $fixed = 0;
            $msg = '';
            $title = sprintf(_("backlinks of \"%s\" page are fixed !"), $options['page']);
            $comment = sprintf(_("Fixed \"%s\" to \"%s\""), $options['page'], $options['name']);
            if ($options['pagenames'] and is_array($options['pagenames'])) {
                $regex = preg_quote($options['page']);
                //$options['minor'] = 1; # disable log
                foreach ($options['pagenames'] as $page) {
                    $p = new WikiPage($page);
                    if (!$p->exists()) {
                        continue;
                    }
                    $f = new Formatter($p);
                    $body = $p->_get_raw_body();
                    $nbody = preg_replace("/{$regex}/m", $options['name'], $body);
                    // FIXME
                    if ($nbody !== false && $body != $nbody) {
                        $f->page->write($nbody);
                        if (!$options['show_only']) {
                            $DBInfo->savePage($f->page, $comment, $options);
                        }
                        $msg .= sprintf(_("'%s' is changed"), $f->link_tag(_rawurlencode($page), "?action=highlight&amp;value=" . $new_encodedname, _html_escape($page))) . "<br />";
                        $fixed++;
                    }
                }
            }
            if ($fixed == 0) {
                $title = _("No pages are fixed!");
            }
            $formatter->send_title($title, '', $options);
            if ($fixed > 0) {
                print $msg;
                print sprintf(_("'%s' links are successfully fixed as '%s'."), _html_escape($options['page']), $formatter->link_tag($new_encodedname, "?action=highlight&amp;value=" . $new_encodedname, _html_escape($options['name'])));
            }
            $formatter->send_footer('', $options);
            return;
        } else {
            $title = sprintf(_("Fail to fix backlinks of \"%s\" !"), $options['page']);
            $options['msg'] = sprintf(_("New pagename \"%s\" is not exists!"), $options['name']);
            $formatter->send_header('', $options);
            $formatter->send_title($title, '', $options);
            $formatter->send_footer('', $options);
            return;
        }
    }
    $title = sprintf(_("Fix backlinks of \"%s\" ?"), $options['page']);
    $formatter->send_header('', $options);
    $formatter->send_title($title, '', $options);
    $obtn = _("Old name:");
    $nbtn = _("New name:");
    $pgname = _html_escape($options['page']);
    print "<form method='post'>\n        <table border='0'>\n        <tr><td align='right'>{$obtn} </td><td><b>{$pgname}</b></td></tr>\n        <tr><td align='right'>{$nbtn} </td><td><input name='name' /></td></tr>\n";
    if (!empty($options['value']) and $options['value'] == 'check_backlinks') {
        $button = _("Fix backlinks");
        print "<tr><td colspan='2'>\n";
        print check_backlinks($formatter, $options);
        print "</td></tr>\n";
    } else {
        $button = _("Check backlinks");
    }
    if ($DBInfo->security->is_protected("fixbacklinks", $options)) {
        print "<tr><td align='right'>" . _("Password") . ": </td><td><input type='password' name='passwd' /> " . _("Only WikiMaster can fix backlinks of this page") . "</td></tr>\n";
    }
    if (!empty($options['value']) and $options['value'] == 'check_backlinks') {
        print "<tr><td colspan='2'><input type='checkbox' name='show_only' checked='checked' />" . _("show only") . "</td></tr>\n";
    }
    print "<tr><td></td><td><input type='submit' name='button_fixbacklinks' value='{$button}' />";
    print "<input type='hidden' name='value' value='check_backlinks' />";
    print "</td></tr>\n";
    print "\n        </table>\n        <input type='hidden' name='action' value='fixbacklinks' />\n        </form>";
    $formatter->send_footer('', $options);
}
예제 #18
0
파일: Cite.php 프로젝트: ahastudio/moniwiki
function macro_Cite($formatter = "", $value = "")
{
    $CITE_MAP = "CiteMap";
    $DEFAULT = <<<EOS
JCP,J.Chem.Phys. http://jcp.aip.org/jcp/top.jsp?vol=\$VOL&amp;pg=\$PAGE
JACS,J.Am.Chem.Soc. http://pubs.acs.org/journals/query/subscriberResults.jsp?Research=true&amp;yearrange1=ASAP&amp;yearrange3=current&amp;cit_qjrn=jacsat&styear=YYYY&endyear=YYYY&vol=\$VOL&spn=\$PAGE
JPC,J.Phys.Chem. http://pubs.acs.org/journals/query/subscriberResults.jsp?Research=true&amp;yearrange1=ASAP&amp;yearrange3=current&amp;cit_qjrn=jpchax&styear=YYYY&endyear=YYYY&vol=\$VOL&spn=\$PAGE
JPCA,J.Phys.Chem.A http://pubs.acs.org/journals/query/subscriberResults.jsp?Research=true&amp;yearrange1=ASAP&amp;yearrange3=current&amp;cit_qjrn=jpcafh&styear=YYYY&endyear=YYYY&vol=\$VOL&spn=\$PAGE
ChemRev,Chem.Rev. http://pubs.acs.org/journals/query/subscriberResults.jsp?Research=true&amp;yearrange1=ASAP&amp;yearrange3=current&amp;cit_qjrn=chreay&styear=YYYY&endyear=YYYY&vol=\$VOL&spn=\$PAGE
RMP,Rev.Mod.Phys. http://link.aps.org/volpage?journal=RMP&volume=\$VOL&id=\$PAGE
PR,Phys.Rev. http://link.aps.org/volpage?journal=PR&volume=\$VOL&id=\$PAGE
PRL,Phys.Rev.Lett. http://link.aps.org/doi/10.1103/PhysRevLett.\$VOL.\$PAGE
CPL,Chem.Phys.Lett. http://www.sciencedirect.com/science/journal/00092614

EOS;
    $CITE_list = array('JCP' => array('http://jcp.aip.org/jcp/top.jsp?vol=$VOL&amp;pg=$PAGE', '', 'J.Chem.Phys.'));
    $DEFAULT_CITE = "JCP";
    $re_cite = "/([A-Z][A-Za-z]*)?\\s*([0-9\\-]+\\s*,\\s*[0-9]+)/x";
    $test = preg_match($re_cite, $value, $match);
    if ($test === false) {
        return "<p><strong class=\"error\">Invalid CITE \"%value\"</strong></p>";
    }
    list($vol, $page) = explode(',', preg_replace('/ /', '', $match[2]));
    if (!empty($match[1])) {
        if (strtolower($match[1][0]) == "k") {
            $cite = "JKCS";
        } else {
            $cite = $match[1];
        }
    } else {
        $cite = $DEFAULT_CITE;
    }
    $attr = '';
    if (!empty($match[3])) {
        $args = explode(",", $match[3]);
        foreach ($args as $arg) {
            if ($arg == "noimg") {
                $noimg = 1;
            } else {
                $name = strtok($arg, '=');
                $val = strtok(' ');
                $attr .= $name . '="' . $val . '" ';
                if ($name == 'align') {
                    $attr .= 'class="img' . ucfirst($val) . '" ';
                }
            }
        }
    }
    $list = $DEFAULT;
    $map = new WikiPage($CITE_MAP);
    if ($map->exists()) {
        $list .= $map->get_raw_body();
    }
    $lists = explode("\n", $list);
    foreach ($lists as $line) {
        if (empty($line) or !preg_match("/^[A-Z]/", $line[0])) {
            continue;
        }
        $dum = explode(" ", rtrim($line));
        if (sizeof($dum) == 2) {
            $dum[] = $CITE_list[$DEFAULT_CITE][1];
        } else {
            if (sizeof($dum) != 3) {
                continue;
            }
        }
        list($dum[0], $name) = explode(',', $dum[0]);
        $CITE_list[$dum[0]] = array($dum[1], $dum[2], $name);
    }
    if (!empty($CITE_list[$cite])) {
        $citelink = $CITE_list[$cite][0];
        $imglink = $CITE_list[$cite][1];
        $citename = $CITE_list[$cite][2];
        if ($citename) {
            $cite = str_replace('.', '. ', $citename);
        }
    } else {
        $citelink = $CITE_list[$DEFAULT_CITE][0];
        $imglink = $CITE_list[$DEFAULT_CITE][1];
    }
    $citelink = str_replace('$VOL', $vol, $citelink);
    $citelink = str_replace('$PAGE', $page, $citelink);
    return $formatter->icon['www'] . '<a href=' . "'{$citelink}'>" . $cite . ' <strong>' . $vol . '</strong>, ' . $page . '</a> ';
}
예제 #19
0
function macro_FastSearch($formatter, $value = "", &$opts)
{
    global $DBInfo;
    $default_limit = isset($DBInfo->fastsearch_limit) ? $DBInfo->fastsearch_limit : 30;
    if ($value === true) {
        $needle = $value = $formatter->page->name;
    } else {
        # for MoinMoin compatibility with [[FullSearch("blah blah")]]
        $needle = $value = preg_replace("/^('|\")([^\\1]*)\\1/", "\\2", $value);
    }
    $needle = _preg_search_escape($needle);
    $pattern = '/' . $needle . '/i';
    $fneedle = str_replace('"', "&#34;", $needle);
    # XXX
    $url = $formatter->link_url($formatter->page->urlname);
    $arena = 'fullsearch';
    $check1 = 'checked="checked"';
    $check2 = $check3 = '';
    if (in_array($opts['arena'], array('titlesearch', 'fullsearch', 'pagelinks'))) {
        $check1 = '';
        $arena = $opts['arena'];
        if ($arena == 'fullsearch') {
            $check1 = 'checked="checked"';
        } else {
            if ($arena == 'titlesearch') {
                $check2 = 'checked="checked"';
            } else {
                $check3 = 'checked="checked"';
            }
        }
    }
    if (!empty($opts['backlinks'])) {
        $arena = 'pagelinks';
        $check1 = '';
        $check3 = 'checked="checked"';
    }
    $msg = _("Fast search");
    $msg2 = _("Display context of search results");
    $msg3 = _("Full text search");
    $msg4 = _("Title search");
    $msg5 = _("Link search");
    $form = <<<EOF
<form method='get' action='{$url}'>
   <input type='hidden' name='action' value='fastsearch' />
   <input name='value' size='30' value='{$fneedle}' />
   <span class='button'><input type='submit' class='button' value='{$msg}' /></span><br />
   <input type='checkbox' name='context' value='20' />{$msg2}<br />
   <input type='radio' name='arena' value='fullsearch' {$check1} />{$msg3}
   <input type='radio' name='arena' value='titlesearch' {$check2} />{$msg4}
   <input type='radio' name='arena' value='pagelinks' {$check3} />{$msg5}<br />
   </form>
EOF;
    if (!isset($needle[0]) or !empty($opts['form'])) {
        # or blah blah
        $opts['msg'] = _("No search text");
        return $form;
    } else {
        if (validate_needle($needle) === false) {
            $opts['msg'] = sprintf(_("Invalid search expression \"%s\""), $needle);
            return $form;
        }
    }
    $DB = new Indexer_dba($arena, "r", $DBInfo->dba_type);
    if ($DB->db == null) {
        $opts['msg'] = _("Couldn't open search database, sorry.");
        $opts['hits'] = array();
        $opts['hit'] = 0;
        $opts['all'] = 0;
        return '';
    }
    $opts['form'] = $form;
    $sc = new Cache_text("searchkey");
    if ($arena == "pagelinks") {
        $words = array($value);
    } else {
        $words = getTokens($value);
    }
    // $words=explode(' ', strtolower($value));
    $idx = array();
    $new_words = array();
    foreach ($words as $word) {
        if ($sc->exists($word)) {
            $searchkeys = $sc->fetch($word);
        } else {
            $searchkeys = $DB->_search($word);
            $sc->update($word, $searchkeys);
        }
        $new_words = array_merge($new_words, $searchkeys);
        $new_words = array_merge($idx, $DB->_search($word));
    }
    $words = array_merge($words, $new_words);
    //
    $word = array_shift($words);
    $idx = $DB->_fetchValues($word);
    foreach ($words as $word) {
        $ids = $DB->_fetchValues($word);
        // FIXME
        foreach ($ids as $id) {
            $idx[] = $id;
        }
    }
    $init_hits = array_count_values($idx);
    // initial hits
    $idx = array_keys($init_hits);
    //arsort($idx);
    $all_count = $DBInfo->getCounter();
    $pages = array();
    $hits = array();
    foreach ($idx as $id) {
        $key = $DB->_fetch($id);
        $pages[$id] = $key;
        $hits['_' . $key] = $init_hits[$id];
        // HACK. prefix '_' to numerical named pages
    }
    $DB->close();
    if (!empty($_GET['q']) and isset($_GET['q'][0])) {
        return $pages;
    }
    $context = !empty($opts['context']) ? $opts['context'] : 0;
    $limit = isset($opts['limit'][0]) ? $opts['limit'] : $default_limit;
    $contexts = array();
    if ($arena == 'fullsearch' || $arena == 'pagelinks') {
        $idx = 1;
        foreach ($pages as $page_name) {
            if (!empty($limit) and $idx > $limit) {
                break;
            }
            $p = new WikiPage($page_name);
            if (!$p->exists()) {
                continue;
            }
            $body = $p->_get_raw_body();
            $count = preg_match_all($pattern, $body, $matches);
            // more precisely count matches
            if ($context) {
                # search matching contexts
                $contexts[$page_name] = find_needle($body, $needle, '', $context);
            }
            $hits['_' . $page_name] = $count;
            // XXX hack for numerical named pages
            $idx++;
        }
    }
    //uasort($hits, 'strcasecmp');
    //$order = 0;
    //uasort($hits, create_function('$a, $b', 'return ' . ($order ? '' : '-') . '(strcasecmp($a, $b));'));
    $name = array_keys($hits);
    array_multisort($hits, SORT_DESC, $name, SORT_ASC);
    $opts['hits'] = $hits;
    $opts['hit'] = count($hits);
    $opts['all'] = $all_count;
    if (!empty($opts['call'])) {
        return $hits;
    }
    $out = "<!-- RESULT LIST START -->";
    // for search plugin
    $out .= "<ul>";
    $idx = 1;
    while (list($page_name, $count) = each($hits)) {
        $page_name = substr($page_name, 1);
        $out .= '<!-- RESULT ITEM START -->';
        // for search plugin
        $out .= '<li>' . $formatter->link_tag(_rawurlencode($page_name), "?action=highlight&amp;value=" . _urlencode($needle), $page_name, "tabindex='{$idx}'");
        if ($count > 1) {
            $out .= ' . . . . ' . sprintf($count == 1 ? _("%d match") : _("%d matches"), $count);
            if (!empty($contexts[$page_name])) {
                $out .= $contexts[$page_name];
            }
        }
        $out .= "</li>\n";
        $out .= '<!-- RESULT ITEM END -->';
        // for search plugin
        $idx++;
        if (!empty($limit) and $idx > $limit) {
            break;
        }
    }
    $out .= "</ul>\n";
    $out .= "<!-- RESULT LIST END -->";
    // for search plugin
    return $out;
}
예제 #20
0
function odt_ref($refPage, $appearance, $hover = '', $anchor = '', $anchor_appearance = '')
{
    global $db, $SeparateLinkWords, $page, $pagestore, $ScriptBase;
    if ($page == 'RecentChanges') {
        $p_exists = $pagestore->page_exists($refPage);
    } else {
        $p = new WikiPage($db, $refPage);
        $p_exists = $p->exists();
        // automatically handle plurals
        if (!$p_exists) {
            foreach (array('s', 'es') as $plural) {
                if (substr($refPage, -strlen($plural)) == $plural) {
                    $temp_refPage = substr($refPage, 0, strlen($refPage) - strlen($plural));
                    $p = new WikiPage($db, $temp_refPage);
                    if ($p_exists = $p->exists()) {
                        $refPage = $temp_refPage;
                        break;
                    }
                }
            }
        }
    }
    if ($p_exists) {
        if ($SeparateLinkWords && $refPage == $appearance) {
            $appearance = html_split_name($refPage);
        }
        $url = $ScriptBase . '?page=' . urlencode($refPage) . $anchor;
        $result = odt_url($url, $appearance . $anchor_appearance);
    } else {
        $result = "";
        if (validate_page($refPage) == 1 && $appearance == $refPage) {
            $result = $refPage;
        } else {
            // Free link.
            // Puts the appearance between parenthesis if there's a space in it.
            if (strpos($appearance, ' ') === false) {
                $tempAppearance = $appearance;
            } else {
                $tempAppearance = "({$appearance})";
            }
            $result = $tempAppearance;
        }
    }
    return $result;
}
예제 #21
0
 /**
  * wfMaintenance -- wiki factory maintenance
  *
  * @static
  */
 public static function wfMaintenance()
 {
     $results = [];
     // VOLDEV-96: Do not credit edits to localhost
     $wikiaUser = User::newFromName('Wikia');
     /**
      * create Blog:Recent posts page if not exists
      */
     $recentPosts = wfMessage('create-blog-post-recent-listing')->text();
     if ($recentPosts) {
         $recentPostsKey = "Creating {$recentPosts}";
         $oTitle = Title::newFromText($recentPosts, NS_BLOG_LISTING);
         if ($oTitle) {
             $page = new WikiPage($oTitle);
             if (!$page->exists()) {
                 $page->doEdit('<bloglist summary="true" count=50><title>' . wfMessage('create-blog-post-recent-listing-title ')->text() . '</title><type>plain</type><order>date</order></bloglist>', wfMessage('create-blog-post-recent-listing-log')->text(), EDIT_NEW | EDIT_MINOR | EDIT_FORCE_BOT, false, $wikiaUser);
                 $results[$recentPostsKey] = 'done';
             } else {
                 $results[$recentPostsKey] = 'already exists';
             }
         }
     }
     /**
      * create Category:Blog page if not exists
      */
     $catName = wfMessage('create-blog-post-category')->text();
     if ($catName && $catName !== "-") {
         $catNameKey = "Creating {$catName}";
         $oTitle = Title::newFromText($catName, NS_CATEGORY);
         if ($oTitle) {
             $page = new WikiPage($oTitle);
             if (!$page->exists()) {
                 $page->doEdit(wfMessage('create-blog-post-category-body')->text(), wfMessage('create-blog-post-category-log')->text(), EDIT_NEW | EDIT_MINOR | EDIT_FORCE_BOT, false, $wikiaUser);
                 $results[$catNameKey] = 'done';
             } else {
                 $results[$catNameKey] = 'already exists';
             }
         }
     }
     return $results;
 }
예제 #22
0
 /**
  * UI entry point for page deletion
  */
 public function delete()
 {
     # This code desperately needs to be totally rewritten
     $title = $this->getTitle();
     $user = $this->getContext()->getUser();
     # Check permissions
     $permission_errors = $title->getUserPermissionsErrors('delete', $user);
     if (count($permission_errors)) {
         throw new PermissionsError('delete', $permission_errors);
     }
     # Read-only check...
     if (wfReadOnly()) {
         throw new ReadOnlyError();
     }
     # Better double-check that it hasn't been deleted yet!
     $this->mPage->loadPageData('fromdbmaster');
     if (!$this->mPage->exists()) {
         $deleteLogPage = new LogPage('delete');
         $outputPage = $this->getContext()->getOutput();
         $outputPage->setPageTitle(wfMessage('cannotdelete-title', $title->getPrefixedText()));
         $outputPage->wrapWikiMsg("<div class=\"error mw-error-cannotdelete\">\n\$1\n</div>", array('cannotdelete', wfEscapeWikiText($title->getPrefixedText())));
         $outputPage->addHTML(Xml::element('h2', null, $deleteLogPage->getName()->text()));
         LogEventsList::showLogExtract($outputPage, 'delete', $title);
         return;
     }
     $request = $this->getContext()->getRequest();
     $deleteReasonList = $request->getText('wpDeleteReasonList', 'other');
     $deleteReason = $request->getText('wpReason');
     if ($deleteReasonList == 'other') {
         $reason = $deleteReason;
     } elseif ($deleteReason != '') {
         // Entry from drop down menu + additional comment
         $colonseparator = wfMessage('colon-separator')->inContentLanguage()->text();
         $reason = $deleteReasonList . $colonseparator . $deleteReason;
     } else {
         $reason = $deleteReasonList;
     }
     if ($request->wasPosted() && $user->matchEditToken($request->getVal('wpEditToken'), array('delete', $this->getTitle()->getPrefixedText()))) {
         # Flag to hide all contents of the archived revisions
         $suppress = $request->getVal('wpSuppress') && $user->isAllowed('suppressrevision');
         $this->doDelete($reason, $suppress);
         if ($user->isLoggedIn() && $request->getCheck('wpWatch') != $user->isWatched($title)) {
             if ($request->getCheck('wpWatch')) {
                 WatchAction::doWatch($title, $user);
             } else {
                 WatchAction::doUnwatch($title, $user);
             }
         }
         return;
     }
     // Generate deletion reason
     $hasHistory = false;
     if (!$reason) {
         try {
             $reason = $this->generateReason($hasHistory);
         } catch (MWException $e) {
             # if a page is horribly broken, we still want to be able to delete it. so be lenient about errors here.
             wfDebug("Error while building auto delete summary: {$e}");
             $reason = '';
         }
     }
     // If the page has a history, insert a warning
     if ($hasHistory) {
         $revisions = $this->mTitle->estimateRevisionCount();
         // @todo FIXME: i18n issue/patchwork message
         $this->getContext()->getOutput()->addHTML('<strong class="mw-delete-warning-revisions">' . wfMessage('historywarning')->numParams($revisions)->parse() . wfMessage('word-separator')->plain() . Linker::linkKnown($title, wfMessage('history')->escaped(), array('rel' => 'archives'), array('action' => 'history')) . '</strong>');
         if ($this->mTitle->isBigDeletion()) {
             global $wgDeleteRevisionsLimit;
             $this->getContext()->getOutput()->wrapWikiMsg("<div class='error'>\n\$1\n</div>\n", array('delete-warning-toobig', $this->getContext()->getLanguage()->formatNum($wgDeleteRevisionsLimit)));
         }
     }
     $this->confirmDelete($reason);
 }
예제 #23
0
function do_post_rename($formatter, $options)
{
    global $DBInfo;
    $new = $options['name'];
    if ($new[0] == '~' and ($p = strpos($new, '/')) !== false) {
        // Namespace renaming
        $dummy = substr($new, 1, $p - 1);
        $dummy2 = substr($new, $p + 1);
        $options['name'] = $dummy . '~' . $dummy2;
    }
    if (isset($options['name']) and trim($options['name'])) {
        if ($DBInfo->hasPage($options['page']) && !$DBInfo->hasPage($options['name'])) {
            $title = sprintf(_("\"%s\" is renamed !"), $options['page']);
            $formatter->send_header("", $options);
            $formatter->send_title($title, "", $options);
            $new_encodedname = _rawurlencode($options['name']);
            if ($options['pagenames'] and is_array($options['pagenames'])) {
                $regex = preg_quote($options['page']);
                $options['minor'] = 1;
                foreach ($options['pagenames'] as $page) {
                    $p = new WikiPage($page);
                    if (!$p->exists()) {
                        continue;
                    }
                    $f = new Formatter($p);
                    $body = $p->_get_raw_body();
                    $body = preg_replace("/{$regex}/m", $options['name'], $body);
                    $f->page->write($body);
                    if (!$options['show_only']) {
                        $DBInfo->savePage($f->page, '', $options);
                    }
                    $msg .= sprintf(_("'%s' is changed"), $f->link_tag(_rawurlencode($page), "?action=highlight&amp;value=" . $new_encodedname)) . "<br />";
                }
            }
            print $msg;
            if (!$options['show_only']) {
                $DBInfo->renamePage($options['page'], $options['name'], $options);
            }
            print sprintf(_("'%s' is renamed as '%s' successfully."), $options['page'], $formatter->link_tag($options['name'], "?action=highlight&amp;value=" . $new_encodedname));
            $formatter->send_footer("", $options);
            return;
        } else {
            $title = sprintf(_("Fail to rename \"%s\" !"), $options['page']);
            $formatter->send_header("", $options);
            $formatter->send_title($title, "", $options);
            $formatter->send_footer("", $options);
            return;
        }
    }
    $title = sprintf(_("Rename \"%s\" ?"), $options['page']);
    $formatter->send_header("", $options);
    $formatter->send_title($title, "", $options);
    #<tr><td align='right'><input type='checkbox' name='show' checked='checked' />show only </td><td><input type='password' name='passwd'>
    $obtn = _("Old name:");
    $nbtn = _("New name:");
    print "<form method='post'>\n<table border='0'>\n<tr><td align='right'>{$obtn} </td><td><b>{$options['page']}</b></td></tr>\n<tr><td align='right'>{$nbtn} </td><td><input name='name' /></td></tr>\n";
    $rename_button = _("Rename");
    if ($options['value'] == 'check_backlinks') {
        print "<tr><td colspan='2'>\n";
        print check_backlinks($formatter, $options);
        print "</td></tr>\n";
        $rename_button = _("Rename and fix Backlinks");
    }
    if ($DBInfo->security->is_protected("rename", $options)) {
        print "<tr><td align='right'>" . _("Password") . ": </td><td><input type='password' name='passwd' /> " . _("Only WikiMaster can rename this page") . "</td></tr>\n";
    }
    print "<tr><td colspan='2'><input type='checkbox' name='history' />" . _("with revision history") . "</td></tr>\n";
    print "<tr><td colspan='2'><input type='checkbox' name='show_only' checked='checked' />" . _("show only") . "</td></tr>\n";
    print "<tr><td></td><td><input type='submit' name='button_rename' value='{$rename_button}' />";
    print " <a href='?action=rename&value=check_backlinks'>" . _("Check backlinks") . "</a>";
    print "</td></tr>\n";
    print "\n</table>\n    <input type=hidden name='action' value='rename' />\n    </form>";
    #  $formatter->send_page();
    $formatter->send_footer("", $options);
}
예제 #24
0
/**
 * get updated info
 *
 */
function ajax_RecentChanges($formatter, $options = array())
{
    global $DBInfo;
    // list style
    if (!empty($options['type']) and $options['type'] == 'list') {
        $options['call'] = 1;
        $options['ajax'] = 1;
        $opt = '';
        if (isset($options['datefmt'])) {
            $opt .= $options['datefmt'] . ',';
        }
        $opt .= 'list';
        if (!empty($options['item'])) {
            $opt .= ',item=' . $options['item'];
        }
        $out = macro_RecentChanges($formatter, $opt, $options);
        echo $out;
        return;
    }
    if (empty($options['value'])) {
        echo '[]';
        return;
    }
    $checknew = 0;
    $checkchange = 0;
    if (!empty($options['new'])) {
        $checknew = 1;
    }
    if (!empty($options['change'])) {
        $checkchange = 1;
    }
    require_once 'lib/JSON.php';
    $json = new Services_JSON();
    $rclist = $json->decode($options['value']);
    if (!is_array($rclist)) {
        echo '[]';
        return;
    }
    // get bookmark parameter and call bookmark macro
    if (!empty($options['time'])) {
        if (is_numeric($options['time']) and $options['time'] > 0) {
            $formatter->macro_repl('Bookmark', '', $options);
            //$bookmark = $options['time'];
        }
    }
    $u = $DBInfo->user;
    # retrive user info
    if ($u->id != 'Anonymous') {
        $bookmark = !empty($u->info['bookmark']) ? $u->info['bookmark'] : '';
    } else {
        $bookmark = $u->bookmark;
    }
    if (!$bookmark) {
        $bookmark = time();
    }
    $tz_offset = $formatter->tz_offset;
    $info = array();
    foreach ($rclist as $page_name) {
        $p = new WikiPage($page_name);
        if (!$p->exists()) {
            $info[$page_name]['state'] = 'deleted';
            continue;
            // XXX
        }
        $ed_time = $p->mtime();
        if ($ed_time <= $bookmark) {
            break;
        }
        $info[$page_name]['state'] = 'updated';
        $add = 0;
        $del = 0;
        if ($checknew or $checkchange) {
            $v = $p->get_rev($bookmark);
            if (empty($v)) {
                $info[$page_name]['state'] = 'new';
                $add += $p->lines();
            }
        }
        if ($checkchange) {
            if (empty($v)) {
                // new
                $infos = array();
            } else {
                $infos = $p->get_info('>' . $bookmark);
            }
            foreach ($infos as $inf) {
                $tmp = explode(' ', trim($inf[1]));
                if (isset($tmp[1])) {
                    $add += $tmp[0];
                    $del += $tmp[1];
                }
            }
            $info[$page_name]['add'] = $add;
            $info[$page_name]['del'] = $del;
        }
    }
    $info['__-_-bookmark-_-__'] = $bookmark;
    echo $json->encode($info);
    return;
}
예제 #25
0
function html_ref($refPage, $appearance, $hover = '', $anchor = '', $anchor_appearance = '')
{
    global $db, $SeparateLinkWords, $page, $pagestore;
    if ($hover != '') {
        $hover = ' alt="' . $hover . '" title="' . $hover . '"';
    }
    $redirect_from = '';
    if ($page == 'RecentChanges') {
        $p_exists = $pagestore->page_exists($refPage);
    } else {
        $p = new WikiPage($db, $refPage);
        $p_exists = $p->exists();
        // automatically handle plurals
        if (!$p_exists) {
            foreach (array('s', 'es') as $plural) {
                if (substr($refPage, -strlen($plural)) == $plural) {
                    $temp_refPage = substr($refPage, 0, strlen($refPage) - strlen($plural));
                    $p = new WikiPage($db, $temp_refPage);
                    if ($p_exists = $p->exists()) {
                        $redirect_from = $refPage;
                        $refPage = $temp_refPage;
                        break;
                    }
                }
            }
        }
    }
    $twintext = "";
    $onlytwin = "";
    $twin = $pagestore->twinpages($refPage, $page);
    if (!$p_exists && count($twin) == 1) {
        $onlytwin = html_twin_x($twin[0][0], $twin[0][1], $twin[0][1]);
    } else {
        if (count($twin)) {
            // point at the sisterwiki's version
            $n = 1;
            foreach ($twin as $site) {
                $twintext = $twintext . html_twin_x($site[0], $n, $site[1]);
                $n++;
            }
            $twintext = '<sup>' . $twintext . '</sup>';
        }
    }
    if ($p_exists) {
        if ($SeparateLinkWords && $refPage == $appearance) {
            $appearance = html_split_name($refPage);
        }
        $result = '<a href="' . viewURL($refPage) . ($redirect_from ? '&redirect_from=' . $redirect_from : '') . $anchor . '"' . $hover . '>' . $appearance . $anchor_appearance . '</a>' . $onlytwin;
    } else {
        $result = "";
        if (validate_page($refPage) == 1 && $appearance == $refPage) {
            if ($onlytwin) {
                $result = $onlytwin;
            } else {
                $result = $refPage;
            }
        } else {
            // Puts the appearance between parenthesis if there's a space in it.
            if (strpos($appearance, ' ') === false) {
                $tempAppearance = $appearance;
            } else {
                $tempAppearance = "({$appearance})";
            }
            if ($onlytwin) {
                $result = $onlytwin;
            } else {
                $result = $tempAppearance;
            }
        }
        $result = $result . '<a href="' . editURL($refPage, '', $page) . '"' . ' title="Create this Wiki page" ' . $hover . '>?</a>' . $twintext;
    }
    return $result;
}
예제 #26
0
 /**
  * This method is called after an article has been saved.
  * This is the server side of IntraACL protection toolbar,
  * allowing to modify page SD together with article save.
  *
  * No modifications are made if either:
  * - Page namespace is ACL
  * - User is anonymous
  * - Users don't have the right to modify page SD
  * - 'haloacl_protect_with' request value is invalid
  *   (valid are 'unprotected', or ID/name of predefined right or THIS page SD)
  *
  * @param WikiPage $article The article which was saved
  * @param User $user        The user who saved the article
  * @param string $text      The content of the article
  *
  * @return true
  */
 public static function articleSaveComplete_SaveSD($article, User $user, $text)
 {
     global $wgUser, $wgRequest, $haclgContLang;
     if ($user->isAnon()) {
         // Don't handle protection toolbar for anonymous users
         return true;
     }
     if ($article->getTitle()->getNamespace() == HACL_NS_ACL) {
         // Don't use protection toolbar for articles in the namespace ACL.
         // Note that embedded content protection toolbar is handled nevertheless.
         return true;
     }
     // Obtain user selection
     // hacl_protected_with == '<peType>:<peID>' or 'unprotected'
     $selectedSD = $wgRequest->getVal('hacl_protected_with');
     if ($selectedSD && $selectedSD != 'unprotected') {
         // Some SD is selected by the user
         // Ignore selection of invalid SDs
         $selectedSD = array_map('intval', explode('-', $selectedSD, 2));
         if (count($selectedSD) != 2) {
             $selectedSD = NULL;
         }
     }
     if (!$selectedSD) {
         return true;
     }
     if ($selectedSD == 'unprotected') {
         $selectedSD = NULL;
     }
     // Check if current SD must be modified
     if ($article->exists()) {
         $pageSD = IACLDefinition::getSDForPE(IACL::PE_PAGE, $article->getId());
         if ($pageSD && $selectedSD) {
             // Check if page's SD ID passed as selected
             if ($pageSD['pe_type'] == $selectedSD[0] && $pageSD['pe_id'] == $selectedSD[1]) {
                 return true;
             }
             // Check if page's SD is single inclusion and it is passed as selected
             if ($pageSD['single_child'] == $selectedSD) {
                 return true;
             }
         }
     }
     // Check if no protection selected and no protection exists
     if (!$selectedSD && !$pageSD) {
         return true;
     }
     // Check if other SD is a predefined right
     // FIXME Allow selecting non-PE_RIGHTs in quick acl toolbar?
     if ($selectedSD && $selectedSD[0] != IACL::PE_RIGHT) {
         return true;
     }
     // Check SD modification rights
     $pageSDName = IACLDefinition::nameOfSD(IACL::PE_PAGE, $article->getTitle());
     $etc = haclfDisableTitlePatch();
     $pageSDTitle = Title::newFromText($pageSDName);
     haclfRestoreTitlePatch($etc);
     if (!$pageSDTitle->userCan('edit')) {
         return true;
     }
     $newSDArticle = new WikiPage($pageSDTitle);
     if ($selectedSD) {
         // Create/modify page SD
         $selectedSDTitle = IACLDefinition::getSDTitle($selectedSD);
         $content = '{{#predefined right: ' . $selectedSDTitle->getText() . "}}\n" . '{{#manage rights: assigned to = User:'******'hacl_comment_protect_with', $selectedSDTitle->getFullText()));
     } else {
         // Remove page SD
         $newSDArticle->doDeleteArticle(wfMsg('hacl_comment_unprotect'));
     }
     // Continue hook processing
     return true;
 }
예제 #27
0
파일: ISBN.php 프로젝트: ahastudio/moniwiki
function macro_ISBN($formatter, $value = "")
{
    global $DBInfo;
    // http://www.isbn-international.org/en/identifiers/allidentifiers.html
    $default_map = array('89' => 'Aladdin');
    $ISBN_MAP = "IsbnMap";
    $DEFAULT = <<<EOS
Amazon http://www.amazon.com/exec/obidos/ISBN= http://images.amazon.com/images/P/\$ISBN.01.MZZZZZZZ.gif
Aladdin http://www.aladdin.co.kr/shop/wproduct.aspx?ISBN= http://image.aladdin.co.kr/cover/cover/\$ISBN_1.gif @(http://image\\..*/cover/(?:[^\\s_/]*\$ISBN_\\d\\.(?:jpe?g|gif)))@
Gang http://kangcom.com/common/qsearch/search.asp?s_flag=T&s_text= http://kangcom.com/l_pic/\$ISBN.jpg @bookinfo\\.asp\\?sku=(\\d+)"@

EOS;
    $DEFAULT_ISBN = "Amazon";
    $re_isbn = "/^([0-9\\-]+[xX]?)(?:,\\s*)?(([A-Z][A-Za-z]*)?(?:,)?(.*))?/x";
    if ($value != '') {
        $test = preg_match($re_isbn, $value, $match);
        if ($test === false) {
            return "<p><strong class=\"error\">Invalid ISBN \"%value\"</strong></p>";
        }
    }
    $list = $DEFAULT;
    $map = new WikiPage($ISBN_MAP);
    if ($map->exists()) {
        $list .= $map->get_raw_body();
    }
    $lists = explode("\n", $list);
    $ISBN_list = array();
    foreach ($lists as $line) {
        if (!$line or !preg_match("/^[A-Z]/", $line[0])) {
            continue;
        }
        $dum = explode(" ", rtrim($line));
        $re = '';
        $sz = sizeof($dum);
        if (!preg_match('/^(http|ftp)/', $dum[1])) {
            continue;
        }
        if ($sz == 2) {
            $dum[] = $ISBN_list[$DEFAULT_ISBN][1];
        } else {
            if ($sz != 3) {
                if ($sz == 4) {
                    if (($p = strpos(substr($dum[3], 1), $dum[3][0])) !== false) {
                        $retest = substr($dum[3], 0, $p + 2);
                    } else {
                        $retest = $dum[3];
                    }
                    if (preg_match($retest, '') !== false) {
                        $re = $dum[3];
                    }
                } else {
                    continue;
                }
            }
        }
        $ISBN_list[$dum[0]] = array($dum[1], $dum[2], $re);
    }
    if ($value == '') {
        $out = "<ul>";
        foreach ($ISBN_list as $interwiki => $v) {
            $href = $ISBN_list[$interwiki][0];
            if (strpos($href, '$ISBN') === false) {
                $url = $href . '0738206679';
            } else {
                $url = str_replace('$ISBN', '0738206679', $href);
            }
            $icon = $DBInfo->imgs_url_interwiki . strtolower($interwiki) . '-16.png';
            $sx = 16;
            $sy = 16;
            if ($DBInfo->intericon[$interwiki]) {
                $icon = $DBInfo->intericon[$interwiki][2];
                $sx = $DBInfo->intericon[$interwiki][0];
                $sy = $DBInfo->intericon[$interwiki][1];
            }
            $out .= "<li><img src='{$icon}' width='{$sx}' height='{$sy}' " . "align='middle' alt='{$interwiki}:' /><a href='{$url}'>{$interwiki}</a>: " . "<tt class='link'>{$href}</tt></li>";
        }
        $out .= "</ul>\n";
        return $out;
    }
    $isbn2 = $match[1];
    $isbn = str_replace('-', '', $isbn2);
    #print_r($match);
    if ($match[3]) {
        if (strtolower($match[2][0]) == 'k') {
            $lang = 'Aladdin';
        } else {
            $lang = $match[3];
        }
    } else {
        $cl = strlen($isbn);
        if ($cl == 13) {
            $lang_code = substr($isbn, 3, 2);
        } else {
            $lang_code = substr($isbn, 0, 2);
        }
        // 89
        if (!empty($default_map[$lang_code])) {
            $lang = $default_map[$lang_code];
        } else {
            $lang = $DEFAULT_ISBN;
        }
    }
    $attr = '';
    $ext = '';
    if ($match[2]) {
        $args = explode(',', $match[2]);
        foreach ($args as $arg) {
            $arg = trim($arg);
            if ($arg == 'noimg') {
                $noimg = 1;
            } else {
                if (strtolower($arg) == 'k') {
                    $lang = 'Aladdin';
                } else {
                    $name = strtok($arg, '=');
                    $val = strtok(' ');
                    if ($val) {
                        $attr .= $name . '="' . $val . '" ';
                    }
                    #XXX
                    if ($name == 'align') {
                        $attr .= 'class="img' . ucfirst($val) . '" ';
                    }
                    if ($name == 'img') {
                        $ext = $val;
                    }
                }
            }
        }
    }
    if ($ISBN_list[$lang]) {
        $booklink = $ISBN_list[$lang][0];
        $imglink = $ISBN_list[$lang][1];
        $imgre = $ISBN_list[$lang][2];
    } else {
        $booklink = $ISBN_list[$DEFAULT_ISBN][0];
        $imglink = $ISBN_list[$DEFAULT_ISBN][1];
    }
    if (strpos($booklink, '$ISBN') === false) {
        $booklink .= $isbn;
    } else {
        if (strpos($booklink, '$ISBN2') === false) {
            $booklink = str_replace('$ISBN', $isbn, $booklink);
        } else {
            $booklink = str_replace('$ISBN2', $isbn2, $booklink);
        }
    }
    if (empty($noimg) and $imgre and get_cfg_var('allow_url_fopen')) {
        if (($p = strpos(substr($imgre, 1), $imgre[0])) !== false) {
            $imgrepl = substr($imgre, $p + 2);
            $imgre = substr($imgre, 0, $p + 2);
            if ($imgrepl == '@') {
                $imgrepl = '';
            }
            $imgre = str_replace('$ISBN', $isbn, $imgre);
        }
        $md5sum = md5($booklink);
        // check cache
        $bcache = new Cache_text('isbn');
        if (empty($formatter->refresh) and $bcache->exists($md5sum)) {
            $imgname = trim($bcache->fetch($md5sum));
            $fetch_ok = 1;
        } else {
            // fetch the bookinfo page and grep the imagname of the book.
            $fd = fopen($booklink, 'r');
            if (is_resource($fd)) {
                while (!feof($fd)) {
                    $line = fgets($fd, 1024);
                    preg_match($imgre, $line, $match);
                    if (!empty($match[1])) {
                        $bcache->update($md5sum, $match[1]);
                        $imgname = $match[1];
                        $fetch_ok = 1;
                        break;
                    }
                }
                fclose($fd);
            }
        }
        if ($fetch_ok) {
            if ($imgrepl) {
                $imglink = preg_replace('@' . $imgrepl . '@', $imgname, $imglink);
            } else {
                if (!preg_match('/^https?:/', $imgname)) {
                    $imglink = str_replace('$ISBN', $imgname, $imglink);
                } else {
                    $imglink = $imgname;
                }
            }
        }
        if (!empty($fetch_ok) and !empty($DBInfo->isbn_img_download)) {
            # some sites such as the IMDB check the referer and
            # do not permit to show any of its images
            # the $isbn_img_download option is needed to show such images
            preg_match('/^(.*)\\.(jpeg|jpg|gif|png)$/i', $imglink, $m);
            if (!empty($m[1]) and isset($m[2])) {
                $myimglink = md5($m[1]) . '.' . $m[2];
            }
            if (isset($m[2])) {
                # skip XXX
            } else {
                if (file_exists($DBInfo->upload_dir . '/isbn/' . $myimglink)) {
                    $mlink = $formatter->macro_repl('attachment', 'isbn:' . $myimglink, 1);
                    $imglink = qualifiedUrl($DBInfo->url_prefix . '/' . $mlink);
                } else {
                    $fd = fopen($imglink, 'r');
                    if (is_resource($fd)) {
                        $myimg = '';
                        while (!feof($fd)) {
                            $myimg .= fread($fd, 1024);
                        }
                        fclose($fd);
                        if (!is_dir($DBInfo->upload_dir . '/isbn/')) {
                            umask(00);
                            mkdir($DBInfo->upload_dir . '/isbn/', 0777);
                            umask($DBInfo->umask);
                        }
                        $fd = fopen($DBInfo->upload_dir . '/isbn/' . $myimglink, 'w');
                        if (is_resource($fd)) {
                            fwrite($fd, $myimg);
                            fclose($fd);
                        }
                    }
                }
            }
        }
    }
    if (empty($fetch_ok)) {
        if (strpos($imglink, '$ISBN') === false) {
            $imglink .= $isbn;
        } else {
            if (strpos($imglink, '$ISBN2') === false) {
                $imglink = str_replace('$ISBN', $isbn, $imglink);
            } else {
                $imglink = str_replace('$ISBN2', $isbn2, $imglink);
            }
            if ($ext) {
                $imglink = preg_replace('/\\.(gif|jpeg|jpg|png|bmp)$/i', $ext, $imglink);
            }
        }
    }
    if (!empty($noimg)) {
        $icon = $DBInfo->imgs_url_interwiki . strtolower($lang) . '-16.png';
        $sx = 16;
        $sy = 16;
        if (!empty($DBInfo->intericon[$lang])) {
            $icon = $DBInfo->intericon[$lang][2];
            $sx = $DBInfo->intericon[$lang][0];
            $sy = $DBInfo->intericon[$lang][1];
        }
        return "<img src='{$icon}' alt='{$lang}:' align='middle' width='{$sx}' height='{$sy}' title='{$lang}' />" . "[<a href='{$booklink}'>ISBN-{$isbn2}</a>]";
    } else {
        return "<a href='{$booklink}'><img src='{$imglink}' border='1' title='{$lang}" . ":ISBN-{$isbn}' alt='[ISBN-{$isbn2}]' class='isbn' {$attr} /></a>";
    }
}