示例#1
0
/**
 * constructor
 */
function wfSpecialLog($par = '')
{
    global $wgRequest, $wgOut, $wgUser, $wgLogTypes;
    # Get parameters
    $parms = explode('/', $par = $par !== null ? $par : '');
    $symsForAll = array('*', 'all');
    if ($parms[0] != '' && (in_array($par, $wgLogTypes) || in_array($par, $symsForAll))) {
        $type = $par;
        $user = $wgRequest->getText('user');
    } else {
        if (count($parms) == 2) {
            $type = $parms[0];
            $user = $parms[1];
        } else {
            $type = $wgRequest->getVal('type');
            $user = $par != '' ? $par : $wgRequest->getText('user');
        }
    }
    $title = $wgRequest->getText('page');
    $pattern = $wgRequest->getBool('pattern');
    $y = $wgRequest->getIntOrNull('year');
    $m = $wgRequest->getIntOrNull('month');
    $tagFilter = $wgRequest->getVal('tagfilter');
    # Don't let the user get stuck with a certain date
    $skip = $wgRequest->getText('offset') || $wgRequest->getText('dir') == 'prev';
    if ($skip) {
        $y = '';
        $m = '';
    }
    # Handle type-specific inputs
    $qc = array();
    if ($type == 'suppress') {
        $offender = User::newFromName($wgRequest->getVal('offender'), false);
        if ($offender && $offender->getId() > 0) {
            $qc = array('ls_field' => 'target_author_id', 'ls_value' => $offender->getId());
        } else {
            if ($offender && IP::isIPAddress($offender->getName())) {
                $qc = array('ls_field' => 'target_author_ip', 'ls_value' => $offender->getName());
            }
        }
    }
    # Create a LogPager item to get the results and a LogEventsList item to format them...
    $loglist = new LogEventsList($wgUser->getSkin(), $wgOut, 0);
    $pager = new LogPager($loglist, $type, $user, $title, $pattern, $qc, $y, $m, $tagFilter);
    # Set title and add header
    $loglist->showHeader($pager->getType());
    # Show form options
    $loglist->showOptions($pager->getType(), $pager->getUser(), $pager->getPage(), $pager->getPattern(), $pager->getYear(), $pager->getMonth(), $pager->getFilterParams(), $tagFilter);
    # Insert list
    $logBody = $pager->getBody();
    if ($logBody) {
        $wgOut->addHTML($pager->getNavigationBar() . $loglist->beginLogEventsList() . $logBody . $loglist->endLogEventsList() . $pager->getNavigationBar());
    } else {
        $wgOut->addWikiMsg('logempty');
    }
}
 /**
  * @param $user User
  * @param $output OutputPage
  */
 protected function showLogFragment($user, $output)
 {
     $pageTitle = Title::makeTitleSafe(NS_USER, $user->getName());
     $logPage = new LogPage('gblrights');
     $output->addHTML(Xml::element('h2', null, $logPage->getName()->text() . "\n"));
     LogEventsList::showLogExtract($output, 'gblrights', $pageTitle->getPrefixedText());
 }
示例#3
0
 /**
  * @return string A HTML <li> element representing this revision, showing
  * change tags and everything
  */
 public function getHTML()
 {
     $date = htmlspecialchars($this->list->getLanguage()->userTimeAndDate($this->row->log_timestamp, $this->list->getUser()));
     $title = Title::makeTitle($this->row->log_namespace, $this->row->log_title);
     $formatter = LogFormatter::newFromRow($this->row);
     $formatter->setContext($this->list->getContext());
     $formatter->setAudience(LogFormatter::FOR_THIS_USER);
     // Log link for this page
     $loglink = Linker::link(SpecialPage::getTitleFor('Log'), $this->list->msg('log')->escaped(), array(), array('page' => $title->getPrefixedText()));
     $loglink = $this->list->msg('parentheses')->rawParams($loglink)->escaped();
     // User links and action text
     $action = $formatter->getActionText();
     // Comment
     $comment = $this->list->getLanguage()->getDirMark() . $formatter->getComment();
     if (LogEventsList::isDeleted($this->row, LogPage::DELETED_COMMENT)) {
         $comment = '<span class="history-deleted">' . $comment . '</span>';
     }
     $content = "{$loglink} {$date} {$action} {$comment}";
     $attribs = array();
     $tags = $this->getTags();
     if ($tags) {
         list($tagSummary, $classes) = ChangeTags::formatSummaryRow($tags, 'edittags', $this->list->getContext());
         $content .= " {$tagSummary}";
         $attribs['class'] = implode(' ', $classes);
     }
     return Xml::tags('li', $attribs, $content);
 }
 public function execute($par)
 {
     global $wgFlaggedRevsOversightAge;
     $out = $this->getOutput();
     $request = $this->getRequest();
     $this->setHeaders();
     $this->namespace = $request->getInt('namespace');
     $this->level = $request->getIntOrNull('level');
     $this->status = $request->getIntOrNull('status');
     $this->automatic = $request->getIntOrNull('automatic');
     $this->user = $request->getVal('user');
     # Check if the user exists
     $usertitle = Title::makeTitleSafe(NS_USER, $this->user);
     $u = $usertitle ? User::idFromName($this->user) : false;
     # Are the dropdown params given even valid?
     $actions = $this->getActions();
     if (empty($actions)) {
         $out->addWikiMsg('qualityoversight-list', 0);
         $out->addWikiMsg('logempty');
         return;
     }
     # Get extra query conds
     $conds = array('log_namespace' => $this->namespace, 'log_action' => $actions);
     # Get cutoff time (mainly for performance)
     if (!$u) {
         $dbr = wfGetDB(DB_SLAVE);
         $cutoff_unixtime = time() - $wgFlaggedRevsOversightAge;
         $cutoff = $dbr->addQuotes($dbr->timestamp($cutoff_unixtime));
         $conds[] = "log_timestamp >= {$cutoff}";
     }
     # Create a LogPager item to get the results and a LogEventsList item to format them...
     $loglist = new LogEventsList($this->getContext()->getSkin(), $out, 0);
     $pager = new LogPager($loglist, 'review', $this->user, '', '', $conds);
     # Explanatory text
     $out->addWikiMsg('qualityoversight-list', $this->getLanguage()->formatNum($pager->getNumRows()));
     # Show form options
     $this->showForm();
     # Insert list
     $logBody = $pager->getBody();
     if ($logBody) {
         $out->addHTML($pager->getNavigationBar() . $loglist->beginLogEventsList() . $logBody . $loglist->endLogEventsList() . $pager->getNavigationBar());
     } else {
         $out->addWikiMsg('logempty');
     }
 }
 /**
  * Show a log if the user has been renamed and point to the new username.
  * Don't show the log if the $oldUserName exists as a user.
  *
  * @param $article Article
  * @return bool
  */
 public static function onShowMissingArticle($article)
 {
     $title = $article->getTitle();
     $oldUser = User::newFromName($title->getBaseText());
     if (($title->getNamespace() === NS_USER || $title->getNamespace() === NS_USER_TALK) && ($oldUser && $oldUser->isAnon())) {
         // Get the title for the base userpage
         $page = Title::makeTitle(NS_USER, str_replace(' ', '_', $title->getBaseText()))->getPrefixedDBkey();
         $out = $article->getContext()->getOutput();
         LogEventsList::showLogExtract($out, 'renameuser', $page, '', array('lim' => 10, 'showIfEmpty' => false, 'msgKey' => array('renameuser-renamed-notice', $title->getBaseText())));
     }
     return true;
 }
示例#6
0
 /**
  * Check if a log item can be displayed
  * @param int $field LogPage::DELETED_* constant
  * @return bool
  */
 protected function canView($field)
 {
     if ($this->audience == self::FOR_THIS_USER) {
         return LogEventsList::userCanBitfield($this->entry->getDeleted(), $field, $this->context->getUser());
     } else {
         return !$this->entry->isDeleted($field);
     }
 }
 /**
  * Show protection long extracts for this page
  *
  * @param $out OutputPage
  * @access private
  */
 function showLogExtract(&$out)
 {
     # Show relevant lines from the protection log:
     $protectLogPage = new LogPage('protect');
     $out->addHTML(Xml::element('h2', null, $protectLogPage->getName()->text()));
     LogEventsList::showLogExtract($out, 'protect', $this->mTitle);
     # Let extensions add other relevant log extracts
     wfRunHooks('ProtectionForm::showLogExtract', array($this->mArticle, $out));
 }
 /**
  * Extracts from a single sql row the data needed to describe one recent change.
  *
  * @param stdClass $row The row from which to extract the data.
  * @return array An array mapping strings (descriptors) to their respective string values.
  * @access public
  */
 public function extractRowInfo($row)
 {
     /* Determine the title of the page that has been changed. */
     $title = Title::makeTitle($row->rc_namespace, $row->rc_title);
     $user = $this->getUser();
     /* Our output data. */
     $vals = array();
     $type = intval($row->rc_type);
     $vals['type'] = RecentChange::parseFromRCType($type);
     $anyHidden = false;
     /* Create a new entry in the result for the title. */
     if ($this->fld_title || $this->fld_ids) {
         if ($type === RC_LOG && $row->rc_deleted & LogPage::DELETED_ACTION) {
             $vals['actionhidden'] = true;
             $anyHidden = true;
         }
         if ($type !== RC_LOG || LogEventsList::userCanBitfield($row->rc_deleted, LogPage::DELETED_ACTION, $user)) {
             if ($this->fld_title) {
                 ApiQueryBase::addTitleInfo($vals, $title);
             }
             if ($this->fld_ids) {
                 $vals['pageid'] = intval($row->rc_cur_id);
                 $vals['revid'] = intval($row->rc_this_oldid);
                 $vals['old_revid'] = intval($row->rc_last_oldid);
             }
         }
     }
     if ($this->fld_ids) {
         $vals['rcid'] = intval($row->rc_id);
     }
     /* Add user data and 'anon' flag, if user is anonymous. */
     if ($this->fld_user || $this->fld_userid) {
         if ($row->rc_deleted & Revision::DELETED_USER) {
             $vals['userhidden'] = true;
             $anyHidden = true;
         }
         if (Revision::userCanBitfield($row->rc_deleted, Revision::DELETED_USER, $user)) {
             if ($this->fld_user) {
                 $vals['user'] = $row->rc_user_text;
             }
             if ($this->fld_userid) {
                 $vals['userid'] = $row->rc_user;
             }
             if (!$row->rc_user) {
                 $vals['anon'] = true;
             }
         }
     }
     /* Add flags, such as new, minor, bot. */
     if ($this->fld_flags) {
         $vals['bot'] = (bool) $row->rc_bot;
         $vals['new'] = $row->rc_type == RC_NEW;
         $vals['minor'] = (bool) $row->rc_minor;
     }
     /* Add sizes of each revision. (Only available on 1.10+) */
     if ($this->fld_sizes) {
         $vals['oldlen'] = intval($row->rc_old_len);
         $vals['newlen'] = intval($row->rc_new_len);
     }
     /* Add the timestamp. */
     if ($this->fld_timestamp) {
         $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->rc_timestamp);
     }
     /* Add edit summary / log summary. */
     if ($this->fld_comment || $this->fld_parsedcomment) {
         if ($row->rc_deleted & Revision::DELETED_COMMENT) {
             $vals['commenthidden'] = true;
             $anyHidden = true;
         }
         if (Revision::userCanBitfield($row->rc_deleted, Revision::DELETED_COMMENT, $user)) {
             if ($this->fld_comment && isset($row->rc_comment)) {
                 $vals['comment'] = $row->rc_comment;
             }
             if ($this->fld_parsedcomment && isset($row->rc_comment)) {
                 $vals['parsedcomment'] = Linker::formatComment($row->rc_comment, $title);
             }
         }
     }
     if ($this->fld_redirect) {
         $vals['redirect'] = (bool) $row->page_is_redirect;
     }
     /* Add the patrolled flag */
     if ($this->fld_patrolled) {
         $vals['patrolled'] = $row->rc_patrolled == 1;
         $vals['unpatrolled'] = ChangesList::isUnpatrolled($row, $user);
     }
     if ($this->fld_loginfo && $row->rc_type == RC_LOG) {
         if ($row->rc_deleted & LogPage::DELETED_ACTION) {
             $vals['actionhidden'] = true;
             $anyHidden = true;
         }
         if (LogEventsList::userCanBitfield($row->rc_deleted, LogPage::DELETED_ACTION, $user)) {
             $vals['logid'] = intval($row->rc_logid);
             $vals['logtype'] = $row->rc_log_type;
             $vals['logaction'] = $row->rc_log_action;
             $vals['logparams'] = LogFormatter::newFromRow($row)->formatParametersForApi();
         }
     }
     if ($this->fld_tags) {
         if ($row->ts_tags) {
             $tags = explode(',', $row->ts_tags);
             ApiResult::setIndexedTagName($tags, 'tag');
             $vals['tags'] = $tags;
         } else {
             $vals['tags'] = array();
         }
     }
     if ($this->fld_sha1 && $row->rev_sha1 !== null) {
         if ($row->rev_deleted & Revision::DELETED_TEXT) {
             $vals['sha1hidden'] = true;
             $anyHidden = true;
         }
         if (Revision::userCanBitfield($row->rev_deleted, Revision::DELETED_TEXT, $user)) {
             if ($row->rev_sha1 !== '') {
                 $vals['sha1'] = wfBaseConvert($row->rev_sha1, 36, 16, 40);
             } else {
                 $vals['sha1'] = '';
             }
         }
     }
     if (!is_null($this->token)) {
         $tokenFunctions = $this->getTokenFunctions();
         foreach ($this->token as $t) {
             $val = call_user_func($tokenFunctions[$t], $row->rc_cur_id, $title, RecentChange::newFromRow($row));
             if ($val === false) {
                 $this->setWarning("Action '{$t}' is not allowed for the current user");
             } else {
                 $vals[$t . 'token'] = $val;
             }
         }
     }
     if ($anyHidden && $row->rc_deleted & Revision::DELETED_RESTRICTED) {
         $vals['suppressed'] = true;
     }
     return $vals;
 }
 /**
  * @param string $field
  * @param string $value
  * @return string HTML
  * @throws MWException
  */
 function formatValue($field, $value)
 {
     /** @var $row object */
     $row = $this->mCurrentRow;
     $formatted = '';
     switch ($field) {
         case 'log_timestamp':
             // when timestamp is null, this is a old protection row
             if ($value === null) {
                 $formatted = Html::rawElement('span', array('class' => 'mw-protectedpages-unknown'), $this->msg('protectedpages-unknown-timestamp')->escaped());
             } else {
                 $formatted = htmlspecialchars($this->getLanguage()->userTimeAndDate($value, $this->getUser()));
             }
             break;
         case 'pr_page':
             $title = Title::makeTitleSafe($row->page_namespace, $row->page_title);
             if (!$title) {
                 $formatted = Html::element('span', array('class' => 'mw-invalidtitle'), Linker::getInvalidTitleDescription($this->getContext(), $row->page_namespace, $row->page_title));
             } else {
                 $formatted = Linker::link($title);
             }
             if (!is_null($row->page_len)) {
                 $formatted .= $this->getLanguage()->getDirMark() . ' ' . Html::rawElement('span', array('class' => 'mw-protectedpages-length'), Linker::formatRevisionSize($row->page_len));
             }
             break;
         case 'pr_expiry':
             $formatted = htmlspecialchars($this->getLanguage()->formatExpiry($value, true));
             $title = Title::makeTitleSafe($row->page_namespace, $row->page_title);
             if ($this->getUser()->isAllowed('protect') && $title) {
                 $changeProtection = Linker::linkKnown($title, $this->msg('protect_change')->escaped(), array(), array('action' => 'unprotect'));
                 $formatted .= ' ' . Html::rawElement('span', array('class' => 'mw-protectedpages-actions'), $this->msg('parentheses')->rawParams($changeProtection)->escaped());
             }
             break;
         case 'log_user':
             // when timestamp is null, this is a old protection row
             if ($row->log_timestamp === null) {
                 $formatted = Html::rawElement('span', array('class' => 'mw-protectedpages-unknown'), $this->msg('protectedpages-unknown-performer')->escaped());
             } else {
                 $username = UserCache::singleton()->getProp($value, 'name');
                 if (LogEventsList::userCanBitfield($row->log_deleted, LogPage::DELETED_USER, $this->getUser())) {
                     if ($username === false) {
                         $formatted = htmlspecialchars($value);
                     } else {
                         $formatted = Linker::userLink($value, $username) . Linker::userToolLinks($value, $username);
                     }
                 } else {
                     $formatted = $this->msg('rev-deleted-user')->escaped();
                 }
                 if (LogEventsList::isDeleted($row, LogPage::DELETED_USER)) {
                     $formatted = '<span class="history-deleted">' . $formatted . '</span>';
                 }
             }
             break;
         case 'pr_params':
             $params = array();
             // Messages: restriction-level-sysop, restriction-level-autoconfirmed
             $params[] = $this->msg('restriction-level-' . $row->pr_level)->escaped();
             if ($row->pr_cascade) {
                 $params[] = $this->msg('protect-summary-cascade')->escaped();
             }
             $formatted = $this->getLanguage()->commaList($params);
             break;
         case 'log_comment':
             // when timestamp is null, this is an old protection row
             if ($row->log_timestamp === null) {
                 $formatted = Html::rawElement('span', array('class' => 'mw-protectedpages-unknown'), $this->msg('protectedpages-unknown-reason')->escaped());
             } else {
                 if (LogEventsList::userCanBitfield($row->log_deleted, LogPage::DELETED_COMMENT, $this->getUser())) {
                     $formatted = Linker::formatComment($value !== null ? $value : '');
                 } else {
                     $formatted = $this->msg('rev-deleted-comment')->escaped();
                 }
                 if (LogEventsList::isDeleted($row, LogPage::DELETED_COMMENT)) {
                     $formatted = '<span class="history-deleted">' . $formatted . '</span>';
                 }
             }
             break;
         default:
             throw new MWException("Unknown field '{$field}'");
     }
     return $formatted;
 }
 /**
  * @param $group
  * @param $output OutputPage
  */
 protected function showLogFragment($group, $output)
 {
     $title = SpecialPage::getTitleFor('GlobalUsers', $group);
     $logPage = new LogPage('gblrights');
     $output->addHTML(Xml::element('h2', null, $logPage->getName()->text() . "\n"));
     LogEventsList::showLogExtract($output, 'gblrights', $title->getPrefixedText());
 }
 function showLogFragment($title)
 {
     $moveLogPage = new LogPage('pagelang');
     $out1 = Xml::element('h2', null, $moveLogPage->getName()->text());
     $out2 = '';
     LogEventsList::showLogExtract($out2, 'pagelang', $title);
     return $out1 . $out2;
 }
示例#12
0
 /**
  * @param string $cond
  * @throws MWException
  * @throws Exception
  */
 protected function dumpFrom($cond = '')
 {
     wfProfileIn(__METHOD__);
     # For logging dumps...
     if ($this->history & self::LOGS) {
         $where = array('user_id = log_user');
         # Hide private logs
         $hideLogs = LogEventsList::getExcludeClause($this->db);
         if ($hideLogs) {
             $where[] = $hideLogs;
         }
         # Add on any caller specified conditions
         if ($cond) {
             $where[] = $cond;
         }
         # Get logging table name for logging.* clause
         $logging = $this->db->tableName('logging');
         if ($this->buffer == WikiExporter::STREAM) {
             $prev = $this->db->bufferResults(false);
         }
         $wrapper = null;
         // Assuring $wrapper is not undefined, if exception occurs early
         try {
             $result = $this->db->select(array('logging', 'user'), array("{$logging}.*", 'user_name'), $where, __METHOD__, array('ORDER BY' => 'log_id', 'USE INDEX' => array('logging' => 'PRIMARY')));
             $wrapper = $this->db->resultObject($result);
             $this->outputLogStream($wrapper);
             if ($this->buffer == WikiExporter::STREAM) {
                 $this->db->bufferResults($prev);
             }
         } catch (Exception $e) {
             // Throwing the exception does not reliably free the resultset, and
             // would also leave the connection in unbuffered mode.
             // Freeing result
             try {
                 if ($wrapper) {
                     $wrapper->free();
                 }
             } catch (Exception $e2) {
                 // Already in panic mode -> ignoring $e2 as $e has
                 // higher priority
             }
             // Putting database back in previous buffer mode
             try {
                 if ($this->buffer == WikiExporter::STREAM) {
                     $this->db->bufferResults($prev);
                 }
             } catch (Exception $e2) {
                 // Already in panic mode -> ignoring $e2 as $e has
                 // higher priority
             }
             // Inform caller about problem
             wfProfileOut(__METHOD__);
             throw $e;
         }
         # For page dumps...
     } else {
         $tables = array('page', 'revision');
         $opts = array('ORDER BY' => 'page_id ASC');
         $opts['USE INDEX'] = array();
         $join = array();
         if (is_array($this->history)) {
             # Time offset/limit for all pages/history...
             $revJoin = 'page_id=rev_page';
             # Set time order
             if ($this->history['dir'] == 'asc') {
                 $op = '>';
                 $opts['ORDER BY'] = 'rev_timestamp ASC';
             } else {
                 $op = '<';
                 $opts['ORDER BY'] = 'rev_timestamp DESC';
             }
             # Set offset
             if (!empty($this->history['offset'])) {
                 $revJoin .= " AND rev_timestamp {$op} " . $this->db->addQuotes($this->db->timestamp($this->history['offset']));
             }
             $join['revision'] = array('INNER JOIN', $revJoin);
             # Set query limit
             if (!empty($this->history['limit'])) {
                 $opts['LIMIT'] = intval($this->history['limit']);
             }
         } elseif ($this->history & WikiExporter::FULL) {
             # Full history dumps...
             $join['revision'] = array('INNER JOIN', 'page_id=rev_page');
         } elseif ($this->history & WikiExporter::CURRENT) {
             # Latest revision dumps...
             if ($this->list_authors && $cond != '') {
                 // List authors, if so desired
                 $this->do_list_authors($cond);
             }
             $join['revision'] = array('INNER JOIN', 'page_id=rev_page AND page_latest=rev_id');
         } elseif ($this->history & WikiExporter::STABLE) {
             # "Stable" revision dumps...
             # Default JOIN, to be overridden...
             $join['revision'] = array('INNER JOIN', 'page_id=rev_page AND page_latest=rev_id');
             # One, and only one hook should set this, and return false
             if (wfRunHooks('WikiExporter::dumpStableQuery', array(&$tables, &$opts, &$join))) {
                 wfProfileOut(__METHOD__);
                 throw new MWException(__METHOD__ . " given invalid history dump type.");
             }
         } elseif ($this->history & WikiExporter::RANGE) {
             # Dump of revisions within a specified range
             $join['revision'] = array('INNER JOIN', 'page_id=rev_page');
             $opts['ORDER BY'] = array('rev_page ASC', 'rev_id ASC');
         } else {
             # Unknown history specification parameter?
             wfProfileOut(__METHOD__);
             throw new MWException(__METHOD__ . " given invalid history dump type.");
         }
         # Query optimization hacks
         if ($cond == '') {
             $opts[] = 'STRAIGHT_JOIN';
             $opts['USE INDEX']['page'] = 'PRIMARY';
         }
         # Build text join options
         if ($this->text != WikiExporter::STUB) {
             // 1-pass
             $tables[] = 'text';
             $join['text'] = array('INNER JOIN', 'rev_text_id=old_id');
         }
         if ($this->buffer == WikiExporter::STREAM) {
             $prev = $this->db->bufferResults(false);
         }
         $wrapper = null;
         // Assuring $wrapper is not undefined, if exception occurs early
         try {
             wfRunHooks('ModifyExportQuery', array($this->db, &$tables, &$cond, &$opts, &$join));
             # Do the query!
             $result = $this->db->select($tables, '*', $cond, __METHOD__, $opts, $join);
             $wrapper = $this->db->resultObject($result);
             # Output dump results
             $this->outputPageStream($wrapper);
             if ($this->buffer == WikiExporter::STREAM) {
                 $this->db->bufferResults($prev);
             }
         } catch (Exception $e) {
             // Throwing the exception does not reliably free the resultset, and
             // would also leave the connection in unbuffered mode.
             // Freeing result
             try {
                 if ($wrapper) {
                     $wrapper->free();
                 }
             } catch (Exception $e2) {
                 // Already in panic mode -> ignoring $e2 as $e has
                 // higher priority
             }
             // Putting database back in previous buffer mode
             try {
                 if ($this->buffer == WikiExporter::STREAM) {
                     $this->db->bufferResults($prev);
                 }
             } catch (Exception $e2) {
                 // Already in panic mode -> ignoring $e2 as $e has
                 // higher priority
             }
             // Inform caller about problem
             throw $e;
         }
     }
     wfProfileOut(__METHOD__);
 }
示例#13
0
 private function extractRowInfo($row)
 {
     $vals = array();
     if ($this->fld_ids) {
         $vals['logid'] = intval($row->log_id);
         $vals['pageid'] = intval($row->page_id);
     }
     if ($this->fld_title || $this->fld_parsedcomment) {
         $title = Title::makeTitle($row->log_namespace, $row->log_title);
     }
     if ($this->fld_title) {
         if (LogEventsList::isDeleted($row, LogPage::DELETED_ACTION)) {
             $vals['actionhidden'] = '';
         } else {
             ApiQueryBase::addTitleInfo($vals, $title);
         }
     }
     if ($this->fld_type || $this->fld_action) {
         $vals['type'] = $row->log_type;
         $vals['action'] = $row->log_action;
     }
     if ($this->fld_details && $row->log_params !== '') {
         if (LogEventsList::isDeleted($row, LogPage::DELETED_ACTION)) {
             $vals['actionhidden'] = '';
         } else {
             self::addLogParams($this->getResult(), $vals, $row->log_params, $row->log_type, $row->log_action, $row->log_timestamp);
         }
     }
     if ($this->fld_user || $this->fld_userid) {
         if (LogEventsList::isDeleted($row, LogPage::DELETED_USER)) {
             $vals['userhidden'] = '';
         } else {
             if ($this->fld_user) {
                 $vals['user'] = $row->user_name;
             }
             if ($this->fld_userid) {
                 $vals['userid'] = $row->user_id;
             }
             if (!$row->log_user) {
                 $vals['anon'] = '';
             }
         }
     }
     if ($this->fld_timestamp) {
         $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->log_timestamp);
     }
     if (($this->fld_comment || $this->fld_parsedcomment) && isset($row->log_comment)) {
         if (LogEventsList::isDeleted($row, LogPage::DELETED_COMMENT)) {
             $vals['commenthidden'] = '';
         } else {
             if ($this->fld_comment) {
                 $vals['comment'] = $row->log_comment;
             }
             if ($this->fld_parsedcomment) {
                 global $wgUser;
                 $vals['parsedcomment'] = $wgUser->getSkin()->formatComment($row->log_comment, $title);
             }
         }
     }
     if ($this->fld_tags) {
         if ($row->ts_tags) {
             $tags = explode(',', $row->ts_tags);
             $this->getResult()->setIndexedTagName($tags, 'tag');
             $vals['tags'] = $tags;
         } else {
             $vals['tags'] = array();
         }
     }
     return $vals;
 }
    /**
     * Replace entire showEditForm, need to add our own textbox and stuff
     */
    function showEditForm($formCallback = null)
    {
        global $wgOut, $wgUser, $wgLang, $wgContLang, $wgMaxArticleSize, $wgTitle, $wgRequest;
        # If $wgTitle is null, that means we're in API mode.
        # Some hook probably called this function  without checking
        # for is_null($wgTitle) first. Bail out right here so we don't
        # do lots of work just to discard it right after.
        if (is_null($wgTitle)) {
            return;
        }
        $fname = 'EditPage::showEditForm';
        wfProfileIn($fname);
        $sk = $wgUser->getSkin();
        wfRunHooks('EditPage::showEditForm:initial', array(&$this));
        #need to parse the preview early so that we know which templates are used,
        #otherwise users with "show preview after edit box" will get a blank list
        #we parse this near the beginning so that setHeaders can do the title
        #setting work instead of leaving it in getPreviewText
        $previewOutput = '';
        if ($this->formtype == 'preview') {
            $previewOutput = $this->getPreviewText();
        }
        $this->setHeaders();
        # Enabled article-related sidebar, toplinks, etc.
        $wgOut->setArticleRelated(true);
        if ($this->isConflict) {
            $wgOut->wrapWikiMsg("<div class='mw-explainconflict'>\n\$1</div>", 'explainconflict');
            $this->textbox2 = $this->textbox1;
            $this->textbox1 = $this->getContent();
            $this->edittime = $this->mArticle->getTimestamp();
            # MeanEditor: too complicated for visual editing
            $this->noVisualEditor = false;
        } else {
            if ($this->section != '' && $this->section != 'new') {
                $matches = array();
                if (!$this->summary && !$this->preview && !$this->diff) {
                    preg_match("/^(=+)(.+)\\1/mi", $this->textbox1, $matches);
                    if (!empty($matches[2])) {
                        global $wgParser;
                        $this->summary = "/* " . $wgParser->stripSectionName(trim($matches[2])) . " */ ";
                    }
                }
            }
            if ($this->missingComment) {
                $wgOut->wrapWikiMsg('<div id="mw-missingcommenttext">$1</div>', 'missingcommenttext');
            }
            if ($this->missingSummary && $this->section != 'new') {
                $wgOut->wrapWikiMsg('<div id="mw-missingsummary">$1</div>', 'missingsummary');
            }
            if ($this->missingSummary && $this->section == 'new') {
                $wgOut->wrapWikiMsg('<div id="mw-missingcommentheader">$1</div>', 'missingcommentheader');
            }
            if ($this->hookError !== '') {
                $wgOut->addWikiText($this->hookError);
            }
            if (!$this->checkUnicodeCompliantBrowser()) {
                $wgOut->addWikiMsg('nonunicodebrowser');
            }
            if (isset($this->mArticle) && isset($this->mArticle->mRevision)) {
                // Let sysop know that this will make private content public if saved
                if (!$this->mArticle->mRevision->userCan(Revision::DELETED_TEXT)) {
                    $wgOut->wrapWikiMsg("<div class='mw-warning plainlinks'>\n\$1</div>\n", 'rev-deleted-text-permission');
                } else {
                    if ($this->mArticle->mRevision->isDeleted(Revision::DELETED_TEXT)) {
                        $wgOut->wrapWikiMsg("<div class='mw-warning plainlinks'>\n\$1</div>\n", 'rev-deleted-text-view');
                    }
                }
                if (!$this->mArticle->mRevision->isCurrent()) {
                    $this->mArticle->setOldSubtitle($this->mArticle->mRevision->getId());
                    $wgOut->addWikiMsg('editingold');
                }
            }
        }
        if (wfReadOnly()) {
            $wgOut->wrapWikiMsg("<div id=\"mw-read-only-warning\">\n\$1\n</div>", array('readonlywarning', wfReadOnlyReason()));
            # MeanEditor: visual editing makes no sense here
            $this->noVisualEditor = true;
        } elseif ($wgUser->isAnon() && $this->formtype != 'preview') {
            $wgOut->wrapWikiMsg('<div id="mw-anon-edit-warning">$1</div>', 'anoneditwarning');
        } else {
            if ($this->isCssJsSubpage) {
                # Check the skin exists
                if ($this->isValidCssJsSubpage) {
                    if ($this->formtype !== 'preview') {
                        $wgOut->addWikiMsg('usercssjsyoucanpreview');
                    }
                } else {
                    $wgOut->addWikiMsg('userinvalidcssjstitle', $wgTitle->getSkinFromCssJsSubpage());
                }
            }
        }
        $classes = array();
        // Textarea CSS
        if ($this->mTitle->getNamespace() == NS_MEDIAWIKI) {
        } elseif ($this->mTitle->isProtected('edit')) {
            # Is the title semi-protected?
            if ($this->mTitle->isSemiProtected()) {
                $noticeMsg = 'semiprotectedpagewarning';
                $classes[] = 'mw-textarea-sprotected';
            } else {
                # Then it must be protected based on static groups (regular)
                $noticeMsg = 'protectedpagewarning';
                $classes[] = 'mw-textarea-protected';
            }
            $wgOut->addHTML("<div class='mw-warning-with-logexcerpt'>\n");
            $wgOut->addWikiMsg($noticeMsg);
            LogEventsList::showLogExtract($wgOut, 'protect', $this->mTitle->getPrefixedText(), '', 1);
            $wgOut->addHTML("</div>\n");
        }
        if ($this->mTitle->isCascadeProtected()) {
            # Is this page under cascading protection from some source pages?
            list($cascadeSources, ) = $this->mTitle->getCascadeProtectionSources();
            $notice = "<div class='mw-cascadeprotectedwarning'>\$1\n";
            $cascadeSourcesCount = count($cascadeSources);
            if ($cascadeSourcesCount > 0) {
                # Explain, and list the titles responsible
                foreach ($cascadeSources as $page) {
                    $notice .= '* [[:' . $page->getPrefixedText() . "]]\n";
                }
            }
            $notice .= '</div>';
            $wgOut->wrapWikiMsg($notice, array('cascadeprotectedwarning', $cascadeSourcesCount));
        }
        if (!$this->mTitle->exists() && $this->mTitle->getRestrictions('create')) {
            $wgOut->wrapWikiMsg('<div class="mw-titleprotectedwarning">$1</div>', 'titleprotectedwarning');
        }
        if ($this->kblength === false) {
            # MeanEditor: the length will probably be different in HTML
            $this->kblength = (int) (strlen($this->textbox1) / 1024);
        }
        if ($this->tooBig || $this->kblength > $wgMaxArticleSize) {
            $wgOut->addHTML("<div class='error' id='mw-edit-longpageerror'>\n");
            $wgOut->addWikiMsg('longpageerror', $wgLang->formatNum($this->kblength), $wgLang->formatNum($wgMaxArticleSize));
            $wgOut->addHTML("</div>\n");
        } elseif ($this->kblength > 29) {
            $wgOut->addHTML("<div id='mw-edit-longpagewarning'>\n");
            $wgOut->addWikiMsg('longpagewarning', $wgLang->formatNum($this->kblength));
            $wgOut->addHTML("</div>\n");
        }
        $q = 'action=' . $this->action;
        #if ( "no" == $redirect ) { $q .= "&redirect=no"; }
        $action = $wgTitle->escapeLocalURL($q);
        $summary = wfMsg('summary');
        $subject = wfMsg('subject');
        $cancel = $sk->makeKnownLink($wgTitle->getPrefixedText(), wfMsgExt('cancel', array('parseinline')));
        $separator = wfMsgExt('pipe-separator', 'escapenoentities');
        $edithelpurl = Skin::makeInternalOrExternalUrl(wfMsgForContent('edithelppage'));
        $edithelp = '<a target="helpwindow" href="' . $edithelpurl . '">' . htmlspecialchars(wfMsg('edithelp')) . '</a> ' . htmlspecialchars(wfMsg('newwindow'));
        global $wgRightsText;
        if ($wgRightsText) {
            $copywarnMsg = array('copyrightwarning', '[[' . wfMsgForContent('copyrightpage') . ']]', $wgRightsText);
        } else {
            $copywarnMsg = array('copyrightwarning2', '[[' . wfMsgForContent('copyrightpage') . ']]');
        }
        /* MeanEditor: always disable the toolbar */
        if ($wgUser->getOption('showtoolbar') and !$this->isCssJsSubpage) {
            # prepare toolbar for edit buttons
            $toolbar = '';
        } else {
            $toolbar = '';
        }
        // activate checkboxes if user wants them to be always active
        if (!$this->preview && !$this->diff) {
            # Sort out the "watch" checkbox
            if ($wgUser->getOption('watchdefault')) {
                # Watch all edits
                $this->watchthis = true;
            } elseif ($wgUser->getOption('watchcreations') && !$this->mTitle->exists()) {
                # Watch creations
                $this->watchthis = true;
            } elseif ($this->mTitle->userIsWatching()) {
                # Already watched
                $this->watchthis = true;
            }
            # May be overriden by request parameters
            if ($wgRequest->getBool('watchthis')) {
                $this->watchthis = true;
            }
            if ($wgUser->getOption('minordefault')) {
                $this->minoredit = true;
            }
            # MeanEditor: User preference
            if ($wgUser->getOption('prefer_traditional_editor')) {
                $this->userWantsTraditionalEditor = true;
            }
        }
        $wgOut->addHTML($this->editFormPageTop);
        if ($wgUser->getOption('previewontop')) {
            $this->displayPreviewArea($previewOutput, true);
        }
        $wgOut->addHTML($this->editFormTextTop);
        # if this is a comment, show a subject line at the top, which is also the edit summary.
        # Otherwise, show a summary field at the bottom
        $summarytext = $wgContLang->recodeForEdit($this->summary);
        # If a blank edit summary was previously provided, and the appropriate
        # user preference is active, pass a hidden tag as wpIgnoreBlankSummary. This will stop the
        # user being bounced back more than once in the event that a summary
        # is not required.
        #####
        # For a bit more sophisticated detection of blank summaries, hash the
        # automatic one and pass that in the hidden field wpAutoSummary.
        $summaryhiddens = '';
        if ($this->missingSummary) {
            $summaryhiddens .= Xml::hidden('wpIgnoreBlankSummary', true);
        }
        $autosumm = $this->autoSumm ? $this->autoSumm : md5($this->summary);
        $summaryhiddens .= Xml::hidden('wpAutoSummary', $autosumm);
        if ($this->section == 'new') {
            $commentsubject = '';
            if (!$wgRequest->getBool('nosummary')) {
                # Add a class if 'missingsummary' is triggered to allow styling of the summary line
                $summaryClass = $this->missingSummary ? 'mw-summarymissed' : 'mw-summary';
                $commentsubject = Xml::tags('label', array('for' => 'wpSummary'), $subject);
                $commentsubject = Xml::tags('span', array('class' => $summaryClass, 'id' => "wpSummaryLabel"), $commentsubject);
                $commentsubject .= '&nbsp;';
                $commentsubject .= Xml::input('wpSummary', 60, $summarytext, array('id' => 'wpSummary', 'maxlength' => '200', 'tabindex' => '1'));
            }
            $editsummary = "<div class='editOptions'>\n";
            global $wgParser;
            $formattedSummary = wfMsgForContent('newsectionsummary', $wgParser->stripSectionName($this->summary));
            $subjectpreview = $summarytext && $this->preview ? "<div class=\"mw-summary-preview\">" . wfMsg('subject-preview') . $sk->commentBlock($formattedSummary, $this->mTitle, true) . "</div>\n" : '';
            $summarypreview = '';
        } else {
            $commentsubject = '';
            # Add a class if 'missingsummary' is triggered to allow styling of the summary line
            $summaryClass = $this->missingSummary ? 'mw-summarymissed' : 'mw-summary';
            $editsummary = Xml::tags('label', array('for' => 'wpSummary'), $summary);
            $editsummary = Xml::tags('span', array('class' => $summaryClass, 'id' => "wpSummaryLabel"), $editsummary) . ' ';
            $editsummary .= Xml::input('wpSummary', 60, $summarytext, array('id' => 'wpSummary', 'maxlength' => '200', 'tabindex' => '1'));
            // No idea where this is closed.
            $editsummary = Xml::openElement('div', array('class' => 'editOptions')) . $editsummary . '<br/>';
            $summarypreview = '';
            if ($summarytext && $this->preview) {
                $summarypreview = Xml::tags('div', array('class' => 'mw-summary-preview'), wfMsg('summary-preview') . $sk->commentBlock($this->summary, $this->mTitle));
            }
            $subjectpreview = '';
        }
        $commentsubject .= $summaryhiddens;
        # Set focus to the edit box on load, except on preview or diff, where it would interfere with the display
        if (!$this->preview && !$this->diff) {
            $wgOut->setOnloadHandler('document.editform.wpTextbox1.focus()');
        }
        $templates = $this->getTemplates();
        $formattedtemplates = $sk->formatTemplates($templates, $this->preview, $this->section != '');
        $hiddencats = $this->mArticle->getHiddenCategories();
        $formattedhiddencats = $sk->formatHiddenCategories($hiddencats);
        global $wgUseMetadataEdit;
        if ($wgUseMetadataEdit) {
            $metadata = $this->mMetaData;
            $metadata = htmlspecialchars($wgContLang->recodeForEdit($metadata));
            $top = wfMsgWikiHtml('metadata_help');
            /* ToDo: Replace with clean code */
            $ew = $wgUser->getOption('editwidth');
            if ($ew) {
                $ew = " style=\"width:100%\"";
            } else {
                $ew = '';
            }
            $cols = $wgUser->getIntOption('cols');
            /* /ToDo */
            $metadata = $top . "<textarea name='metadata' rows='3' cols='{$cols}'{$ew}>{$metadata}</textarea>";
        } else {
            $metadata = "";
        }
        $recreate = '';
        if ($this->wasDeletedSinceLastEdit()) {
            if ('save' != $this->formtype) {
                $wgOut->wrapWikiMsg("<div class='error mw-deleted-while-editing'>\n\$1</div>", 'deletedwhileediting');
            } else {
                // Hide the toolbar and edit area, user can click preview to get it back
                // Add an confirmation checkbox and explanation.
                $toolbar = '';
                $recreate = '<div class="mw-confirm-recreate">' . $wgOut->parse(wfMsg('confirmrecreate', $this->lastDelete->user_name, $this->lastDelete->log_comment)) . Xml::checkLabel(wfMsg('recreate'), 'wpRecreate', 'wpRecreate', false, array('title' => $sk->titleAttrib('recreate'), 'tabindex' => 1, 'id' => 'wpRecreate')) . '</div>';
            }
        }
        $tabindex = 2;
        $checkboxes = $this->getCheckboxes($tabindex, $sk, array('minor' => $this->minoredit, 'watch' => $this->watchthis, 'want_traditional_editor' => $this->userWantsTraditionalEditor));
        $checkboxhtml = implode($checkboxes, "\n");
        $buttons = $this->getEditButtons($tabindex);
        $buttonshtml = implode($buttons, "\n");
        $safemodehtml = $this->checkUnicodeCompliantBrowser() ? '' : Xml::hidden('safemode', '1');
        $wgOut->addHTML(<<<END
{$toolbar}
<form id="editform" name="editform" method="post" action="{$action}" enctype="multipart/form-data">
END
);
        if (is_callable($formCallback)) {
            call_user_func_array($formCallback, array(&$wgOut));
        }
        wfRunHooks('EditPage::showEditForm:fields', array(&$this, &$wgOut));
        // Put these up at the top to ensure they aren't lost on early form submission
        $this->showFormBeforeText();
        $wgOut->addHTML(<<<END
{$recreate}
{$commentsubject}
{$subjectpreview}
{$this->editFormTextBeforeContent}
END
);
        if ($this->isConflict || $this->diff) {
            # MeanEditor: should be redundant, but let's be sure
            $this->noVisualEditor = true;
        }
        # MeanEditor: also apply htmlspecialchars? See $encodedtext
        $html_text = $this->safeUnicodeOutput($this->textbox1);
        if (!($this->noVisualEditor || $this->userWantsTraditionalEditor)) {
            $this->noVisualEditor = wfRunHooks('EditPage::wiki2html', array($this->mArticle, $wgUser, &$this, &$html_text));
        }
        if (!$this->noVisualEditor && !$this->userWantsTraditionalEditor) {
            $this->noVisualEditor = wfRunHooks('EditPage::showBox', array(&$this, $html_text, $rows, $cols, $ew));
        }
        if (!$this->noVisualEditor && !$this->userWantsTraditionalEditor) {
            $wgOut->addHTML("<input type='hidden' value=\"0\" name=\"wpNoVisualEditor\" />\n");
        } else {
            $wgOut->addHTML("<input type='hidden' value=\"1\" name=\"wpNoVisualEditor\" />\n");
            $this->showTextbox1($classes);
        }
        $wgOut->wrapWikiMsg("<div id=\"editpage-copywarn\">\n\$1\n</div>", $copywarnMsg);
        $wgOut->addHTML(<<<END
{$this->editFormTextAfterWarn}
{$metadata}
{$editsummary}
{$summarypreview}
{$checkboxhtml}
{$safemodehtml}
END
);
        $wgOut->addHTML("<div class='editButtons'>\n{$buttonshtml}\n\t<span class='editHelp'>{$cancel}{$separator}{$edithelp}</span>\n</div><!-- editButtons -->\n</div><!-- editOptions -->");
        /**
         * To make it harder for someone to slip a user a page
         * which submits an edit form to the wiki without their
         * knowledge, a random token is associated with the login
         * session. If it's not passed back with the submission,
         * we won't save the page, or render user JavaScript and
         * CSS previews.
         *
         * For anon editors, who may not have a session, we just
         * include the constant suffix to prevent editing from
         * broken text-mangling proxies.
         */
        $token = htmlspecialchars($wgUser->editToken());
        $wgOut->addHTML("\n<input type='hidden' value=\"{$token}\" name=\"wpEditToken\" />\n");
        $this->showEditTools();
        $wgOut->addHTML(<<<END
{$this->editFormTextAfterTools}
<div class='templatesUsed'>
{$formattedtemplates}
</div>
<div class='hiddencats'>
{$formattedhiddencats}
</div>
END
);
        if ($this->isConflict && wfRunHooks('EditPageBeforeConflictDiff', array(&$this, &$wgOut))) {
            $wgOut->wrapWikiMsg('==$1==', "yourdiff");
            $de = new DifferenceEngine($this->mTitle);
            $de->setText($this->textbox2, $this->textbox1);
            $de->showDiff(wfMsg("yourtext"), wfMsg("storedversion"));
            $wgOut->wrapWikiMsg('==$1==', "yourtext");
            $this->showTextbox2();
        }
        $wgOut->addHTML($this->editFormTextBottom);
        $wgOut->addHTML("</form>\n");
        if (!$wgUser->getOption('previewontop')) {
            $this->displayPreviewArea($previewOutput, false);
        }
        wfProfileOut($fname);
    }
示例#15
0
    protected function openShowImage()
    {
        global $wgImageLimits, $wgEnableUploads, $wgSend404Code;
        $this->loadFile();
        $out = $this->getContext()->getOutput();
        $user = $this->getContext()->getUser();
        $lang = $this->getContext()->getLanguage();
        $dirmark = $lang->getDirMarkEntity();
        $request = $this->getContext()->getRequest();
        $max = $this->getImageLimitsFromOption($user, 'imagesize');
        $maxWidth = $max[0];
        $maxHeight = $max[1];
        if ($this->displayImg->exists()) {
            # image
            $page = $request->getIntOrNull('page');
            if (is_null($page)) {
                $params = array();
                $page = 1;
            } else {
                $params = array('page' => $page);
            }
            $renderLang = $request->getVal('lang');
            if (!is_null($renderLang)) {
                $handler = $this->displayImg->getHandler();
                if ($handler && $handler->validateParam('lang', $renderLang)) {
                    $params['lang'] = $renderLang;
                } else {
                    $renderLang = null;
                }
            }
            $width_orig = $this->displayImg->getWidth($page);
            $width = $width_orig;
            $height_orig = $this->displayImg->getHeight($page);
            $height = $height_orig;
            $filename = wfEscapeWikiText($this->displayImg->getName());
            $linktext = $filename;
            wfRunHooks('ImageOpenShowImageInlineBefore', array(&$this, &$out));
            if ($this->displayImg->allowInlineDisplay()) {
                # image
                # "Download high res version" link below the image
                # $msgsize = wfMessage( 'file-info-size', $width_orig, $height_orig, Linker::formatSize( $this->displayImg->getSize() ), $mime )->escaped();
                # We'll show a thumbnail of this image
                if ($width > $maxWidth || $height > $maxHeight) {
                    # Calculate the thumbnail size.
                    # First case, the limiting factor is the width, not the height.
                    if ($width / $height >= $maxWidth / $maxHeight) {
                        // FIXME: Possible division by 0. bug 36911
                        $height = round($height * $maxWidth / $width);
                        // FIXME: Possible division by 0. bug 36911
                        $width = $maxWidth;
                        # Note that $height <= $maxHeight now.
                    } else {
                        $newwidth = floor($width * $maxHeight / $height);
                        // FIXME: Possible division by 0. bug 36911
                        $height = round($height * $newwidth / $width);
                        // FIXME: Possible division by 0. bug 36911
                        $width = $newwidth;
                        # Note that $height <= $maxHeight now, but might not be identical
                        # because of rounding.
                    }
                    $linktext = wfMessage('show-big-image')->escaped();
                    if ($this->displayImg->getRepo()->canTransformVia404()) {
                        $thumbSizes = $wgImageLimits;
                        // Also include the full sized resolution in the list, so
                        // that users know they can get it. This will link to the
                        // original file asset if mustRender() === false. In the case
                        // that we mustRender, some users have indicated that they would
                        // find it useful to have the full size image in the rendered
                        // image format.
                        $thumbSizes[] = array($width_orig, $height_orig);
                    } else {
                        # Creating thumb links triggers thumbnail generation.
                        # Just generate the thumb for the current users prefs.
                        $thumbSizes = array($this->getImageLimitsFromOption($user, 'thumbsize'));
                        if (!$this->displayImg->mustRender()) {
                            // We can safely include a link to the "full-size" preview,
                            // without actually rendering.
                            $thumbSizes[] = array($width_orig, $height_orig);
                        }
                    }
                    # Generate thumbnails or thumbnail links as needed...
                    $otherSizes = array();
                    foreach ($thumbSizes as $size) {
                        // We include a thumbnail size in the list, if it is
                        // less than or equal to the original size of the image
                        // asset ($width_orig/$height_orig). We also exclude
                        // the current thumbnail's size ($width/$height)
                        // since that is added to the message separately, so
                        // it can be denoted as the current size being shown.
                        if ($size[0] <= $width_orig && $size[1] <= $height_orig && $size[0] != $width && $size[1] != $height) {
                            $sizeLink = $this->makeSizeLink($params, $size[0], $size[1]);
                            if ($sizeLink) {
                                $otherSizes[] = $sizeLink;
                            }
                        }
                    }
                    $otherSizes = array_unique($otherSizes);
                    $msgsmall = '';
                    $sizeLinkBigImagePreview = $this->makeSizeLink($params, $width, $height);
                    if ($sizeLinkBigImagePreview) {
                        $msgsmall .= wfMessage('show-big-image-preview')->rawParams($sizeLinkBigImagePreview)->parse();
                    }
                    if (count($otherSizes)) {
                        $msgsmall .= ' ' . Html::rawElement('span', array('class' => 'mw-filepage-other-resolutions'), wfMessage('show-big-image-other')->rawParams($lang->pipeList($otherSizes))->params(count($otherSizes))->parse());
                    }
                } elseif ($width == 0 && $height == 0) {
                    # Some sort of audio file that doesn't have dimensions
                    # Don't output a no hi res message for such a file
                    $msgsmall = '';
                } elseif ($this->displayImg->isVectorized()) {
                    # For vectorized images, full size is just the frame size
                    $msgsmall = '';
                } else {
                    # Image is small enough to show full size on image page
                    $msgsmall = wfMessage('file-nohires')->parse();
                }
                $params['width'] = $width;
                $params['height'] = $height;
                $thumbnail = $this->displayImg->transform($params);
                Linker::processResponsiveImages($this->displayImg, $thumbnail, $params);
                $anchorclose = Html::rawElement('div', array('class' => 'mw-filepage-resolutioninfo'), $msgsmall);
                $isMulti = $this->displayImg->isMultipage() && $this->displayImg->pageCount() > 1;
                if ($isMulti) {
                    $out->addModules('mediawiki.page.image.pagination');
                    $out->addHTML('<table class="multipageimage"><tr><td>');
                }
                if ($thumbnail) {
                    $options = array('alt' => $this->displayImg->getTitle()->getPrefixedText(), 'file-link' => true);
                    $out->addHTML('<div class="fullImageLink" id="file">' . $thumbnail->toHtml($options) . $anchorclose . "</div>\n");
                }
                if ($isMulti) {
                    $count = $this->displayImg->pageCount();
                    if ($page > 1) {
                        $label = $out->parse(wfMessage('imgmultipageprev')->text(), false);
                        // on the client side, this link is generated in ajaxifyPageNavigation()
                        // in the mediawiki.page.image.pagination module
                        $link = Linker::linkKnown($this->getTitle(), $label, array(), array('page' => $page - 1));
                        $thumb1 = Linker::makeThumbLinkObj($this->getTitle(), $this->displayImg, $link, $label, 'none', array('page' => $page - 1));
                    } else {
                        $thumb1 = '';
                    }
                    if ($page < $count) {
                        $label = wfMessage('imgmultipagenext')->text();
                        $link = Linker::linkKnown($this->getTitle(), $label, array(), array('page' => $page + 1));
                        $thumb2 = Linker::makeThumbLinkObj($this->getTitle(), $this->displayImg, $link, $label, 'none', array('page' => $page + 1));
                    } else {
                        $thumb2 = '';
                    }
                    global $wgScript;
                    $formParams = array('name' => 'pageselector', 'action' => $wgScript);
                    $options = array();
                    for ($i = 1; $i <= $count; $i++) {
                        $options[] = Xml::option($lang->formatNum($i), $i, $i == $page);
                    }
                    $select = Xml::tags('select', array('id' => 'pageselector', 'name' => 'page'), implode("\n", $options));
                    $out->addHTML('</td><td><div class="multipageimagenavbox">' . Xml::openElement('form', $formParams) . Html::hidden('title', $this->getTitle()->getPrefixedDBkey()) . wfMessage('imgmultigoto')->rawParams($select)->parse() . Xml::submitButton(wfMessage('imgmultigo')->text()) . Xml::closeElement('form') . "<hr />{$thumb1}\n{$thumb2}<br style=\"clear: both\" /></div></td></tr></table>");
                }
            } elseif ($this->displayImg->isSafeFile()) {
                # if direct link is allowed but it's not a renderable image, show an icon.
                $icon = $this->displayImg->iconThumb();
                $out->addHTML('<div class="fullImageLink" id="file">' . $icon->toHtml(array('file-link' => true)) . "</div>\n");
            }
            $longDesc = wfMessage('parentheses', $this->displayImg->getLongDesc())->text();
            $medialink = "[[Media:{$filename}|{$linktext}]]";
            if (!$this->displayImg->isSafeFile()) {
                $warning = wfMessage('mediawarning')->plain();
                // dirmark is needed here to separate the file name, which
                // most likely ends in Latin characters, from the description,
                // which may begin with the file type. In RTL environment
                // this will get messy.
                // The dirmark, however, must not be immediately adjacent
                // to the filename, because it can get copied with it.
                // See bug 25277.
                $out->addWikiText(<<<EOT
<div class="fullMedia"><span class="dangerousLink">{$medialink}</span> {$dirmark}<span class="fileInfo">{$longDesc}</span></div>
<div class="mediaWarning">{$warning}</div>
EOT
);
            } else {
                $out->addWikiText(<<<EOT
<div class="fullMedia">{$medialink} {$dirmark}<span class="fileInfo">{$longDesc}</span>
</div>
EOT
);
            }
            $renderLangOptions = $this->displayImg->getAvailableLanguages();
            if (count($renderLangOptions) >= 1) {
                $currentLanguage = $renderLang;
                $defaultLang = $this->displayImg->getDefaultRenderLanguage();
                if (is_null($currentLanguage)) {
                    $currentLanguage = $defaultLang;
                }
                $out->addHtml($this->doRenderLangOpt($renderLangOptions, $currentLanguage, $defaultLang));
            }
            // Add cannot animate thumbnail warning
            if (!$this->displayImg->canAnimateThumbIfAppropriate()) {
                // Include the extension so wiki admins can
                // customize it on a per file-type basis
                // (aka say things like use format X instead).
                // additionally have a specific message for
                // file-no-thumb-animation-gif
                $ext = $this->displayImg->getExtension();
                $noAnimMesg = wfMessageFallback('file-no-thumb-animation-' . $ext, 'file-no-thumb-animation')->plain();
                $out->addWikiText(<<<EOT
<div class="mw-noanimatethumb">{$noAnimMesg}</div>
EOT
);
            }
            if (!$this->displayImg->isLocal()) {
                $this->printSharedImageText();
            }
        } else {
            # Image does not exist
            if (!$this->getID()) {
                # No article exists either
                # Show deletion log to be consistent with normal articles
                LogEventsList::showLogExtract($out, array('delete', 'move'), $this->getTitle()->getPrefixedText(), '', array('lim' => 10, 'conds' => array("log_action != 'revision'"), 'showIfEmpty' => false, 'msgKey' => array('moveddeleted-notice')));
            }
            if ($wgEnableUploads && $user->isAllowed('upload')) {
                // Only show an upload link if the user can upload
                $uploadTitle = SpecialPage::getTitleFor('Upload');
                $nofile = array('filepage-nofile-link', $uploadTitle->getFullURL(array('wpDestFile' => $this->mPage->getFile()->getName())));
            } else {
                $nofile = 'filepage-nofile';
            }
            // Note, if there is an image description page, but
            // no image, then this setRobotPolicy is overridden
            // by Article::View().
            $out->setRobotPolicy('noindex,nofollow');
            $out->wrapWikiMsg("<div id='mw-imagepage-nofile' class='plainlinks'>\n\$1\n</div>", $nofile);
            if (!$this->getID() && $wgSend404Code) {
                // If there is no image, no shared image, and no description page,
                // output a 404, to be consistent with articles.
                $request->response()->header('HTTP/1.1 404 Not Found');
            }
        }
        $out->setFileVersion($this->displayImg);
    }
示例#16
0
 public static function onContributionsToolLinks($id, $nt, &$tools)
 {
     global $wgOut, $wgCityId, $wgUser, $wgCityId;
     wfProfileIn(__METHOD__);
     $user = User::newFromId($id);
     if (!empty($user)) {
         $tools[] = Linker::link(SpecialPage::getSafeTitleFor('Log', 'chatban'), wfMessage('chat-chatban-log')->escaped(), array('class' => 'chat-ban-log'), array('page' => $user->getUserPage()->getPrefixedText()));
         # Add chat ban log link (@author: Sactage)
         if (Chat::getBanInformation($wgCityId, $user) !== false) {
             $dir = "change";
             LogEventsList::showLogExtract($wgOut, 'chatban', $nt->getPrefixedText(), '', array('lim' => 1, 'showIfEmpty' => false, 'msgKey' => array('chat-contributions-ban-notice', $nt->getText()), 'offset' => ''));
         } else {
             if ($wgUser->isAllowed('chatmoderator') && !$user->isAllowed('chatmoderator')) {
                 $tools[] = "<a class='chat-change-ban' data-user-id='{$id}' href='#'>" . wfMsg('chat-ban-contributions-heading') . "</a>";
             }
         }
     }
     wfProfileOut(__METHOD__);
     return true;
 }
示例#17
0
 private function showHistory()
 {
     global $wgLang, $wgContLang, $wgUser, $wgOut;
     $this->sk = $wgUser->getSkin();
     $wgOut->setPagetitle(wfMsg("mergehistory"));
     $this->showMergeForm();
     # List all stored revisions
     $revisions = new MergeHistoryPager($this, array(), $this->mTargetObj, $this->mDestObj);
     $haveRevisions = $revisions && $revisions->getNumRows() > 0;
     $titleObj = SpecialPage::getTitleFor("Mergehistory");
     $action = $titleObj->getLocalURL("action=submit");
     # Start the form here
     $top = Xml::openElement('form', array('method' => 'post', 'action' => $action, 'id' => 'merge'));
     $wgOut->addHTML($top);
     if ($haveRevisions) {
         # Format the user-visible controls (comment field, submission button)
         # in a nice little table
         $align = $wgContLang->isRtl() ? 'left' : 'right';
         $table = Xml::openElement('fieldset') . Xml::openElement('table') . "<tr>\n\t\t\t\t\t\t<td colspan='2'>" . wfMsgExt('mergehistory-merge', array('parseinline'), $this->mTargetObj->getPrefixedText(), $this->mDestObj->getPrefixedText()) . "</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td align='{$align}'>" . Xml::label(wfMsg('undeletecomment'), 'wpComment') . "</td>\n\t\t\t\t\t\t<td>" . Xml::input('wpComment', 50, $this->mComment) . "</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>&nbsp;</td>\n\t\t\t\t\t\t<td>" . Xml::submitButton(wfMsg('mergehistory-submit'), array('name' => 'merge', 'id' => 'mw-merge-submit')) . "</td>\n\t\t\t\t\t</tr>" . Xml::closeElement('table') . Xml::closeElement('fieldset');
         $wgOut->addHTML($table);
     }
     $wgOut->addHTML("<h2 id=\"mw-mergehistory\">" . wfMsgHtml("mergehistory-list") . "</h2>\n");
     if ($haveRevisions) {
         $wgOut->addHTML($revisions->getNavigationBar());
         $wgOut->addHTML("<ul>");
         $wgOut->addHTML($revisions->getBody());
         $wgOut->addHTML("</ul>");
         $wgOut->addHTML($revisions->getNavigationBar());
     } else {
         $wgOut->addWikiMsg("mergehistory-empty");
     }
     # Show relevant lines from the deletion log:
     $wgOut->addHTML("<h2>" . htmlspecialchars(LogPage::logName('merge')) . "</h2>\n");
     LogEventsList::showLogExtract($wgOut, 'merge', $this->mTargetObj->getPrefixedText());
     # When we submit, go by page ID to avoid some nasty but unlikely collisions.
     # Such would happen if a page was renamed after the form loaded, but before submit
     $misc = Xml::hidden('targetID', $this->mTargetObj->getArticleID());
     $misc .= Xml::hidden('destID', $this->mDestObj->getArticleID());
     $misc .= Xml::hidden('target', $this->mTarget);
     $misc .= Xml::hidden('dest', $this->mDest);
     $misc .= Xml::hidden('wpEditToken', $wgUser->editToken());
     $misc .= Xml::closeElement('form');
     $wgOut->addHTML($misc);
     return true;
 }
 public function execute($par)
 {
     $this->useTransactionalTimeLimit();
     $this->checkPermissions();
     $this->checkReadOnly();
     $output = $this->getOutput();
     $user = $this->getUser();
     $this->setHeaders();
     $this->outputHeader();
     $request = $this->getRequest();
     $this->submitClicked = $request->wasPosted() && $request->getBool('wpSubmit');
     # Handle our many different possible input types.
     $ids = $request->getVal('ids');
     if (!is_null($ids)) {
         # Allow CSV, for backwards compatibility, or a single ID for show/hide links
         $this->ids = explode(',', $ids);
     } else {
         # Array input
         $this->ids = array_keys($request->getArray('ids', array()));
     }
     // $this->ids = array_map( 'intval', $this->ids );
     $this->ids = array_unique(array_filter($this->ids));
     $this->typeName = $request->getVal('type');
     $this->targetObj = Title::newFromText($request->getText('target'));
     # For reviewing deleted files...
     $this->archiveName = $request->getVal('file');
     $this->token = $request->getVal('token');
     if ($this->archiveName && $this->targetObj) {
         $this->tryShowFile($this->archiveName);
         return;
     }
     $this->typeName = RevisionDeleter::getCanonicalTypeName($this->typeName);
     # No targets?
     if (!$this->typeName || count($this->ids) == 0) {
         throw new ErrorPageError('revdelete-nooldid-title', 'revdelete-nooldid-text');
     }
     # Allow the list type to adjust the passed target
     $this->targetObj = RevisionDeleter::suggestTarget($this->typeName, $this->targetObj, $this->ids);
     # We need a target page!
     if ($this->targetObj === null) {
         $output->addWikiMsg('undelete-header');
         return;
     }
     $this->typeLabels = self::$UILabels[$this->typeName];
     $list = $this->getList();
     $list->reset();
     $bitfield = $list->current()->getBits();
     $this->mIsAllowed = $user->isAllowed(RevisionDeleter::getRestriction($this->typeName));
     $canViewSuppressedOnly = $this->getUser()->isAllowed('viewsuppressed') && !$this->getUser()->isAllowed('suppressrevision');
     $pageIsSuppressed = $bitfield & Revision::DELETED_RESTRICTED;
     $this->mIsAllowed = $this->mIsAllowed && !($canViewSuppressedOnly && $pageIsSuppressed);
     $this->otherReason = $request->getVal('wpReason');
     # Give a link to the logs/hist for this page
     $this->showConvenienceLinks();
     # Initialise checkboxes
     $this->checks = array(array($this->typeLabels['check-label'], 'wpHidePrimary', RevisionDeleter::getRevdelConstant($this->typeName)), array('revdelete-hide-comment', 'wpHideComment', Revision::DELETED_COMMENT), array('revdelete-hide-user', 'wpHideUser', Revision::DELETED_USER));
     if ($user->isAllowed('suppressrevision')) {
         $this->checks[] = array('revdelete-hide-restricted', 'wpHideRestricted', Revision::DELETED_RESTRICTED);
     }
     # Either submit or create our form
     if ($this->mIsAllowed && $this->submitClicked) {
         $this->submit($request);
     } else {
         $this->showForm();
     }
     $qc = $this->getLogQueryCond();
     # Show relevant lines from the deletion log
     $deleteLogPage = new LogPage('delete');
     $output->addHTML("<h2>" . $deleteLogPage->getName()->escaped() . "</h2>\n");
     LogEventsList::showLogExtract($output, 'delete', $this->targetObj, '', array('lim' => 25, 'conds' => $qc, 'useMaster' => $this->wasSaved));
     # Show relevant lines from the suppression log
     if ($user->isAllowed('suppressionlog')) {
         $suppressLogPage = new LogPage('suppress');
         $output->addHTML("<h2>" . $suppressLogPage->getName()->escaped() . "</h2>\n");
         LogEventsList::showLogExtract($output, 'suppress', $this->targetObj, '', array('lim' => 25, 'conds' => $qc, 'useMaster' => $this->wasSaved));
     }
 }
 /**
  * Print the history page for an article.
  */
 function onView()
 {
     $out = $this->getOutput();
     $request = $this->getRequest();
     /**
      * Allow client caching.
      */
     if ($out->checkLastModified($this->page->getTouched())) {
         return;
         // Client cache fresh and headers sent, nothing more to do.
     }
     wfProfileIn(__METHOD__);
     $this->preCacheMessages();
     $config = $this->context->getConfig();
     # Fill in the file cache if not set already
     $useFileCache = $config->get('UseFileCache');
     if ($useFileCache && HTMLFileCache::useFileCache($this->getContext())) {
         $cache = HTMLFileCache::newFromTitle($this->getTitle(), 'history');
         if (!$cache->isCacheGood()) {
             ob_start(array(&$cache, 'saveToFileCache'));
         }
     }
     // Setup page variables.
     $out->setFeedAppendQuery('action=history');
     $out->addModules('mediawiki.action.history');
     if ($config->get('UseMediaWikiUIEverywhere')) {
         $out = $this->getOutput();
         $out->addModuleStyles(array('mediawiki.ui.input', 'mediawiki.ui.checkbox'));
     }
     // Handle atom/RSS feeds.
     $feedType = $request->getVal('feed');
     if ($feedType) {
         $this->feed($feedType);
         wfProfileOut(__METHOD__);
         return;
     }
     // Fail nicely if article doesn't exist.
     if (!$this->page->exists()) {
         $out->addWikiMsg('nohistory');
         # show deletion/move log if there is an entry
         LogEventsList::showLogExtract($out, array('delete', 'move'), $this->getTitle(), '', array('lim' => 10, 'conds' => array("log_action != 'revision'"), 'showIfEmpty' => false, 'msgKey' => array('moveddeleted-notice')));
         wfProfileOut(__METHOD__);
         return;
     }
     /**
      * Add date selector to quickly get to a certain time
      */
     $year = $request->getInt('year');
     $month = $request->getInt('month');
     $tagFilter = $request->getVal('tagfilter');
     $tagSelector = ChangeTags::buildTagFilterSelector($tagFilter);
     /**
      * Option to show only revisions that have been (partially) hidden via RevisionDelete
      */
     if ($request->getBool('deleted')) {
         $conds = array('rev_deleted != 0');
     } else {
         $conds = array();
     }
     if ($this->getUser()->isAllowed('deletedhistory')) {
         $checkDeleted = Xml::checkLabel($this->msg('history-show-deleted')->text(), 'deleted', 'mw-show-deleted-only', $request->getBool('deleted')) . "\n";
     } else {
         $checkDeleted = '';
     }
     // Add the general form
     $action = htmlspecialchars(wfScript());
     $out->addHTML("<form action=\"{$action}\" method=\"get\" id=\"mw-history-searchform\">" . Xml::fieldset($this->msg('history-fieldset-title')->text(), false, array('id' => 'mw-history-search')) . Html::hidden('title', $this->getTitle()->getPrefixedDBkey()) . "\n" . Html::hidden('action', 'history') . "\n" . Xml::dateMenu($year == null ? MWTimestamp::getLocalInstance()->format('Y') : $year, $month) . '&#160;' . ($tagSelector ? implode('&#160;', $tagSelector) . '&#160;' : '') . $checkDeleted . Xml::submitButton($this->msg('allpagessubmit')->text()) . "\n" . '</fieldset></form>');
     wfRunHooks('PageHistoryBeforeList', array(&$this->page, $this->getContext()));
     // Create and output the list.
     $pager = new HistoryPager($this, $year, $month, $tagFilter, $conds);
     $out->addHTML($pager->getNavigationBar() . $pager->getBody() . $pager->getNavigationBar());
     $out->preventClickjacking($pager->getPreventClickjacking());
     wfProfileOut(__METHOD__);
 }
 protected function doDBUpdates()
 {
     $db = $this->getDB(DB_MASTER);
     if (!$db->tableExists('log_search')) {
         $this->error("log_search does not exist");
         return false;
     }
     $start = $db->selectField('logging', 'MIN(log_id)', false, __FUNCTION__);
     if (!$start) {
         $this->output("Nothing to do.\n");
         return true;
     }
     $end = $db->selectField('logging', 'MAX(log_id)', false, __FUNCTION__);
     # Do remaining chunk
     $end += $this->mBatchSize - 1;
     $blockStart = $start;
     $blockEnd = $start + $this->mBatchSize - 1;
     $delTypes = array('delete', 'suppress');
     // revisiondelete types
     while ($blockEnd <= $end) {
         $this->output("...doing log_id from {$blockStart} to {$blockEnd}\n");
         $cond = "log_id BETWEEN {$blockStart} AND {$blockEnd}";
         $res = $db->select('logging', '*', $cond, __FUNCTION__);
         foreach ($res as $row) {
             // RevisionDelete logs - revisions
             if (LogEventsList::typeAction($row, $delTypes, 'revision')) {
                 $params = LogPage::extractParams($row->log_params);
                 // Param format: <urlparam> <item CSV> [<ofield> <nfield>]
                 if (count($params) < 2) {
                     continue;
                     // bad row?
                 }
                 $field = RevisionDeleter::getRelationType($params[0]);
                 // B/C, the params may start with a title key (<title> <urlparam> <CSV>)
                 if ($field == null) {
                     array_shift($params);
                     // remove title param
                     $field = RevisionDeleter::getRelationType($params[0]);
                     if ($field == null) {
                         $this->output("Invalid param type for {$row->log_id}\n");
                         continue;
                         // skip this row
                     } else {
                         // Clean up the row...
                         $db->update('logging', array('log_params' => implode(',', $params)), array('log_id' => $row->log_id));
                     }
                 }
                 $items = explode(',', $params[1]);
                 $log = new LogPage($row->log_type);
                 // Add item relations...
                 $log->addRelations($field, $items, $row->log_id);
                 // Determine what table to query...
                 $prefix = substr($field, 0, strpos($field, '_'));
                 // db prefix
                 if (!isset(self::$tableMap[$prefix])) {
                     continue;
                     // bad row?
                 }
                 $table = self::$tableMap[$prefix];
                 $userField = $prefix . '_user';
                 $userTextField = $prefix . '_user_text';
                 // Add item author relations...
                 $userIds = $userIPs = array();
                 $sres = $db->select($table, array($userField, $userTextField), array($field => $items));
                 foreach ($sres as $srow) {
                     if ($srow->{$userField} > 0) {
                         $userIds[] = intval($srow->{$userField});
                     } elseif ($srow->{$userTextField} != '') {
                         $userIPs[] = $srow->{$userTextField};
                     }
                 }
                 // Add item author relations...
                 $log->addRelations('target_author_id', $userIds, $row->log_id);
                 $log->addRelations('target_author_ip', $userIPs, $row->log_id);
             } elseif (LogEventsList::typeAction($row, $delTypes, 'event')) {
                 // RevisionDelete logs - log events
                 $params = LogPage::extractParams($row->log_params);
                 // Param format: <item CSV> [<ofield> <nfield>]
                 if (count($params) < 1) {
                     continue;
                     // bad row
                 }
                 $items = explode(',', $params[0]);
                 $log = new LogPage($row->log_type);
                 // Add item relations...
                 $log->addRelations('log_id', $items, $row->log_id);
                 // Add item author relations...
                 $userIds = $userIPs = array();
                 $sres = $db->select('logging', array('log_user', 'log_user_text'), array('log_id' => $items));
                 foreach ($sres as $srow) {
                     if ($srow->log_user > 0) {
                         $userIds[] = intval($srow->log_user);
                     } elseif (IP::isIPAddress($srow->log_user_text)) {
                         $userIPs[] = $srow->log_user_text;
                     }
                 }
                 $log->addRelations('target_author_id', $userIds, $row->log_id);
                 $log->addRelations('target_author_ip', $userIPs, $row->log_id);
             }
         }
         $blockStart += $this->mBatchSize;
         $blockEnd += $this->mBatchSize;
         wfWaitForSlaves();
     }
     $this->output("Done populating log_search table.\n");
     return true;
 }
示例#21
0
    private function showHistory()
    {
        $this->showMergeForm();
        # List all stored revisions
        $revisions = new MergeHistoryPager($this, [], $this->mTargetObj, $this->mDestObj);
        $haveRevisions = $revisions && $revisions->getNumRows() > 0;
        $out = $this->getOutput();
        $titleObj = $this->getPageTitle();
        $action = $titleObj->getLocalURL(['action' => 'submit']);
        # Start the form here
        $top = Xml::openElement('form', ['method' => 'post', 'action' => $action, 'id' => 'merge']);
        $out->addHTML($top);
        if ($haveRevisions) {
            # Format the user-visible controls (comment field, submission button)
            # in a nice little table
            $table = Xml::openElement('fieldset') . $this->msg('mergehistory-merge', $this->mTargetObj->getPrefixedText(), $this->mDestObj->getPrefixedText())->parse() . Xml::openElement('table', ['id' => 'mw-mergehistory-table']) . '<tr>
						<td class="mw-label">' . Xml::label($this->msg('mergehistory-reason')->text(), 'wpComment') . '</td>
					<td class="mw-input">' . Xml::input('wpComment', 50, $this->mComment, ['id' => 'wpComment']) . '</td>
					</tr>
					<tr>
						<td>&#160;</td>
						<td class="mw-submit">' . Xml::submitButton($this->msg('mergehistory-submit')->text(), ['name' => 'merge', 'id' => 'mw-merge-submit']) . '</td>
					</tr>' . Xml::closeElement('table') . Xml::closeElement('fieldset');
            $out->addHTML($table);
        }
        $out->addHTML('<h2 id="mw-mergehistory">' . $this->msg('mergehistory-list')->escaped() . "</h2>\n");
        if ($haveRevisions) {
            $out->addHTML($revisions->getNavigationBar());
            $out->addHTML('<ul>');
            $out->addHTML($revisions->getBody());
            $out->addHTML('</ul>');
            $out->addHTML($revisions->getNavigationBar());
        } else {
            $out->addWikiMsg('mergehistory-empty');
        }
        # Show relevant lines from the merge log:
        $mergeLogPage = new LogPage('merge');
        $out->addHTML('<h2>' . $mergeLogPage->getName()->escaped() . "</h2>\n");
        LogEventsList::showLogExtract($out, 'merge', $this->mTargetObj);
        # When we submit, go by page ID to avoid some nasty but unlikely collisions.
        # Such would happen if a page was renamed after the form loaded, but before submit
        $misc = Html::hidden('targetID', $this->mTargetObj->getArticleID());
        $misc .= Html::hidden('destID', $this->mDestObj->getArticleID());
        $misc .= Html::hidden('target', $this->mTarget);
        $misc .= Html::hidden('dest', $this->mDest);
        $misc .= Html::hidden('wpEditToken', $this->getUser()->getEditToken());
        $misc .= Xml::closeElement('form');
        $out->addHTML($misc);
        return true;
    }
示例#22
0
 /**
  * Show a rights log fragment for the specified user
  *
  * @param $user User to show log for
  * @param $output OutputPage to use
  */
 protected function showLogFragment($user, $output)
 {
     $output->addHTML(Xml::element('h2', null, LogPage::logName('rights') . "\n"));
     LogEventsList::showLogExtract($output, 'rights', $user->getUserPage()->getPrefixedText());
 }
示例#23
0
 /**
  * Determine if the current user is allowed to view a particular
  * field of this revision, if it's marked as deleted.
  * @param $rc RCCacheEntry
  * @param $field Integer
  * @param $user User object to check, or null to use $wgUser
  * @return Boolean
  */
 public static function userCan($rc, $field, User $user = null)
 {
     if ($rc->mAttribs['rc_type'] == RC_LOG) {
         return LogEventsList::userCanBitfield($rc->mAttribs['rc_deleted'], $field, $user);
     } else {
         return Revision::userCanBitfield($rc->mAttribs['rc_deleted'], $field, $user);
     }
 }
示例#24
0
 /**
  * Perform a deletion and output success or failure messages
  * @param string $reason
  * @param bool $suppress
  */
 public function doDelete($reason, $suppress = false)
 {
     $error = '';
     $context = $this->getContext();
     $outputPage = $context->getOutput();
     $user = $context->getUser();
     $status = $this->mPage->doDeleteArticleReal($reason, $suppress, 0, true, $error, $user);
     if ($status->isGood()) {
         $deleted = $this->getTitle()->getPrefixedText();
         $outputPage->setPageTitle(wfMessage('actioncomplete'));
         $outputPage->setRobotPolicy('noindex,nofollow');
         $loglink = '[[Special:Log/delete|' . wfMessage('deletionlog')->text() . ']]';
         $outputPage->addWikiMsg('deletedtext', wfEscapeWikiText($deleted), $loglink);
         Hooks::run('ArticleDeleteAfterSuccess', array($this->getTitle(), $outputPage));
         $outputPage->returnToMain(false);
     } else {
         $outputPage->setPageTitle(wfMessage('cannotdelete-title', $this->getTitle()->getPrefixedText()));
         if ($error == '') {
             $outputPage->addWikiText("<div class=\"error mw-error-cannotdelete\">\n" . $status->getWikiText() . "\n</div>");
             $deleteLogPage = new LogPage('delete');
             $outputPage->addHTML(Xml::element('h2', null, $deleteLogPage->getName()->text()));
             LogEventsList::showLogExtract($outputPage, 'delete', $this->getTitle());
         } else {
             $outputPage->addHTML($error);
         }
     }
 }
 public function getHTML()
 {
     $date = htmlspecialchars($this->list->getLanguage()->userTimeAndDate($this->row->log_timestamp, $this->list->getUser()));
     $title = Title::makeTitle($this->row->log_namespace, $this->row->log_title);
     $formatter = LogFormatter::newFromRow($this->row);
     $formatter->setContext($this->list->getContext());
     $formatter->setAudience(LogFormatter::FOR_THIS_USER);
     // Log link for this page
     $loglink = Linker::link(SpecialPage::getTitleFor('Log'), $this->list->msg('log')->escaped(), array(), array('page' => $title->getPrefixedText()));
     $loglink = $this->list->msg('parentheses')->rawParams($loglink)->escaped();
     // User links and action text
     $action = $formatter->getActionText();
     // Comment
     $comment = $this->list->getLanguage()->getDirMark() . Linker::commentBlock($this->row->log_comment);
     if (LogEventsList::isDeleted($this->row, LogPage::DELETED_COMMENT)) {
         $comment = '<span class="history-deleted">' . $comment . '</span>';
     }
     return "<li>{$loglink} {$date} {$action} {$comment}</li>";
 }
示例#26
0
 /**
  * Get an UploadForm instance with title and text properly set.
  *
  * @param string $message HTML string to add to the form
  * @param string $sessionKey Session key in case this is a stashed upload
  * @param bool $hideIgnoreWarning Whether to hide "ignore warning" check box
  * @return UploadForm
  */
 protected function getUploadForm($message = '', $sessionKey = '', $hideIgnoreWarning = false)
 {
     # Initialize form
     $context = new DerivativeContext($this->getContext());
     $context->setTitle($this->getPageTitle());
     // Remove subpage
     $form = new UploadForm(array('watch' => $this->getWatchCheck(), 'forreupload' => $this->mForReUpload, 'sessionkey' => $sessionKey, 'hideignorewarning' => $hideIgnoreWarning, 'destwarningack' => (bool) $this->mDestWarningAck, 'description' => $this->mComment, 'texttop' => $this->uploadFormTextTop, 'textaftersummary' => $this->uploadFormTextAfterSummary, 'destfile' => $this->mDesiredDestName), $context);
     # Check the token, but only if necessary
     if (!$this->mTokenOk && !$this->mCancelUpload && ($this->mUpload && $this->mUploadClicked)) {
         $form->addPreText($this->msg('session_fail_preview')->parse());
     }
     # Give a notice if the user is uploading a file that has been deleted or moved
     # Note that this is independent from the message 'filewasdeleted' that requires JS
     $desiredTitleObj = Title::makeTitleSafe(NS_FILE, $this->mDesiredDestName);
     $delNotice = '';
     // empty by default
     if ($desiredTitleObj instanceof Title && !$desiredTitleObj->exists()) {
         LogEventsList::showLogExtract($delNotice, array('delete', 'move'), $desiredTitleObj, '', array('lim' => 10, 'conds' => array("log_action != 'revision'"), 'showIfEmpty' => false, 'msgKey' => array('upload-recreate-warning')));
     }
     $form->addPreText($delNotice);
     # Add text to form
     $form->addPreText('<div id="uploadtext">' . $this->msg('uploadtext', array($this->mDesiredDestName))->parseAsBlock() . '</div>');
     # Add upload error message
     $form->addPreText($message);
     # Add footer to form
     $uploadFooter = $this->msg('uploadfooter');
     if (!$uploadFooter->isDisabled()) {
         $form->addPostText('<div id="mw-upload-footer-message">' . $uploadFooter->parseAsBlock() . "</div>\n");
     }
     return $form;
 }
示例#27
0
 private function show(FormOptions $opts, array $extraConds)
 {
     global $wgOut;
     # Create a LogPager item to get the results and a LogEventsList item to format them...
     $loglist = new LogEventsList($this->getSkin(), $wgOut, 0);
     $pager = new LogPager($loglist, $opts->getValue('type'), $opts->getValue('user'), $opts->getValue('page'), $opts->getValue('pattern'), $extraConds, $opts->getValue('year'), $opts->getValue('month'), $opts->getValue('tagfilter'));
     # Set title and add header
     $loglist->showHeader($pager->getType());
     # Set relevant user
     if ($pager->getUser()) {
         $this->getSkin()->setRelevantUser(User::newFromName($pager->getUser()));
     }
     # Show form options
     $loglist->showOptions($pager->getType(), $pager->getUser(), $pager->getPage(), $pager->getPattern(), $pager->getYear(), $pager->getMonth(), $pager->getFilterParams(), $opts->getValue('tagfilter'));
     # Insert list
     $logBody = $pager->getBody();
     if ($logBody) {
         $wgOut->addHTML($pager->getNavigationBar() . $loglist->beginLogEventsList() . $logBody . $loglist->endLogEventsList() . $pager->getNavigationBar());
     } else {
         $wgOut->addWikiMsg('logempty');
     }
 }
 /**
  * Display form for approving/denying request or process form submission.
  *
  * @param GlobalRenameRequest $req Pending request
  */
 protected function doShowProcessForm(GlobalRenameRequest $req)
 {
     $this->commonPreamble('globalrenamequeue-request-title', array($req->getName()));
     $form = HTMLForm::factory('vform', array('rid' => array('default' => $req->getId(), 'name' => 'rid', 'type' => 'hidden'), 'comments' => array('default' => $this->getRequest()->getVal('comments'), 'id' => 'mw-renamequeue-comments', 'label-message' => 'globalrenamequeue-request-comments-label', 'name' => 'comments', 'type' => 'textarea', 'rows' => 5), 'reason' => array('id' => 'mw-renamequeue-reason', 'label-message' => 'globalrenamequeue-request-reason-label', 'name' => 'reason', 'type' => 'text'), 'movepages' => array('id' => 'mw-renamequeue-movepages', 'name' => 'movepages', 'label-message' => 'globalrenamequeue-request-movepages', 'type' => 'check', 'default' => 1), 'suppressredirects' => array('id' => 'mw-renamequeue-suppressredirects', 'name' => 'suppressredirects', 'label-message' => 'globalrenamequeue-request-suppressredirects', 'type' => 'check')), $this->getContext(), 'globalrenamequeue');
     $form->suppressDefaultSubmit();
     $form->addButton('approve', $this->msg('globalrenamequeue-request-approve-text')->text(), 'mw-renamequeue-approve', array('class' => 'mw-ui-constructive mw-ui-flush-right'));
     $form->addButton('deny', $this->msg('globalrenamequeue-request-deny-text')->text(), 'mw-renamequeue-deny', array('class' => 'mw-ui-destructive mw-ui-flush-right'));
     $form->addButton('cancel', $this->msg('globalrenamequeue-request-cancel-text')->text(), 'mw-renamequeue-cancel', array('class' => 'mw-ui-quiet mw-ui-flush-left'));
     $form->setId('mw-globalrenamequeue-request');
     if ($req->userIsGlobal()) {
         $globalUser = new CentralAuthUser($req->getName());
         $homeWiki = $globalUser->getHomeWiki();
         $infoMsgKey = 'globalrenamequeue-request-userinfo-global';
     } else {
         $homeWiki = $req->getWiki();
         $infoMsgKey = 'globalrenamequeue-request-userinfo-local';
     }
     $headerMsg = $this->msg('globalrenamequeue-request-header', WikiMap::getForeignURL($homeWiki, "User:{$req->getName()}"), $req->getName(), $req->getNewName());
     $form->addHeaderText('<span class="plainlinks">' . $headerMsg->parseAsBlock() . '</span>');
     $homeWikiWiki = WikiMap::getWiki($homeWiki);
     $infoMsg = $this->msg($infoMsgKey, $req->getName(), $homeWikiWiki ? $homeWikiWiki->getDisplayName() : $homeWiki, $req->getNewName());
     $form->addHeaderText($infoMsg->parseAsBlock());
     if (class_exists('CentralAuthSpoofUser')) {
         $spoofUser = new CentralAuthSpoofUser($req->getNewName());
         // @todo move this code somewhere else
         $specialGblRename = new SpecialGlobalRenameUser();
         $specialGblRename->setContext($this->getContext());
         $conflicts = $specialGblRename->processAntiSpoofConflicts($req->getName(), $spoofUser->getConflicts());
         if ($conflicts) {
             $form->addHeaderText($this->msg('globalrenamequeue-request-antispoof-conflicts', $this->getLanguage()->commaList($conflicts))->numParams(count($conflicts))->parse());
         }
     }
     // Show a log entry of previous renames under the requesting user's username
     $caTitle = Title::makeTitleSafe(NS_SPECIAL, 'CentralAuth/' . $req->getName());
     $extract = '';
     $extractCount = LogEventsList::showLogExtract($extract, 'gblrename', $caTitle, '', array('showIfEmpty' => false));
     if ($extractCount) {
         $form->addHeaderText(Xml::fieldset($this->msg('globalrenamequeue-request-previous-renames')->numParams($extractCount)->text(), $extract));
     }
     $reason = $req->getReason() ?: $this->msg('globalrenamequeue-request-reason-sul')->parseAsBlock();
     $form->addHeaderText($this->msg('globalrenamequeue-request-reason', $reason)->parseAsBlock());
     $form->setSubmitCallback(array($this, 'onProcessSubmit'));
     $out = $this->getOutput();
     $out->addModuleStyles(array('mediawiki.ui', 'mediawiki.ui.button', 'mediawiki.ui.input', 'ext.centralauth.globalrenamequeue.styles'));
     $out->addModules('ext.centralauth.globalrenamequeue');
     $status = $form->show();
     if ($status instanceof Status && $status->isOk()) {
         $this->getOutput()->redirect($this->getPageTitle(self::PAGE_PROCESS_REQUEST . "/{$req->getId()}/{$status->value}")->getFullURL());
     }
 }
示例#29
0
 public function formatRow($row)
 {
     return $this->mLogEventsList->logLine($row);
 }
示例#30
0
 protected function showHistory()
 {
     $this->checkReadOnly();
     $out = $this->getOutput();
     if ($this->mAllowed) {
         $out->addModules('mediawiki.special.undelete');
     }
     $out->wrapWikiMsg("<div class='mw-undelete-pagetitle'>\n\$1\n</div>\n", array('undeletepagetitle', wfEscapeWikiText($this->mTargetObj->getPrefixedText())));
     $archive = new PageArchive($this->mTargetObj, $this->getConfig());
     Hooks::run('UndeleteForm::showHistory', array(&$archive, $this->mTargetObj));
     /*
     $text = $archive->getLastRevisionText();
     if( is_null( $text ) ) {
     	$out->addWikiMsg( 'nohistory' );
     	return;
     }
     */
     $out->addHTML('<div class="mw-undelete-history">');
     if ($this->mAllowed) {
         $out->addWikiMsg('undeletehistory');
         $out->addWikiMsg('undeleterevdel');
     } else {
         $out->addWikiMsg('undeletehistorynoadmin');
     }
     $out->addHTML('</div>');
     # List all stored revisions
     $revisions = $archive->listRevisions();
     $files = $archive->listFiles();
     $haveRevisions = $revisions && $revisions->numRows() > 0;
     $haveFiles = $files && $files->numRows() > 0;
     # Batch existence check on user and talk pages
     if ($haveRevisions) {
         $batch = new LinkBatch();
         foreach ($revisions as $row) {
             $batch->addObj(Title::makeTitleSafe(NS_USER, $row->ar_user_text));
             $batch->addObj(Title::makeTitleSafe(NS_USER_TALK, $row->ar_user_text));
         }
         $batch->execute();
         $revisions->seek(0);
     }
     if ($haveFiles) {
         $batch = new LinkBatch();
         foreach ($files as $row) {
             $batch->addObj(Title::makeTitleSafe(NS_USER, $row->fa_user_text));
             $batch->addObj(Title::makeTitleSafe(NS_USER_TALK, $row->fa_user_text));
         }
         $batch->execute();
         $files->seek(0);
     }
     if ($this->mAllowed) {
         $action = $this->getPageTitle()->getLocalURL(array('action' => 'submit'));
         # Start the form here
         $top = Xml::openElement('form', array('method' => 'post', 'action' => $action, 'id' => 'undelete'));
         $out->addHTML($top);
     }
     # Show relevant lines from the deletion log:
     $deleteLogPage = new LogPage('delete');
     $out->addHTML(Xml::element('h2', null, $deleteLogPage->getName()->text()) . "\n");
     LogEventsList::showLogExtract($out, 'delete', $this->mTargetObj);
     # Show relevant lines from the suppression log:
     $suppressLogPage = new LogPage('suppress');
     if ($this->getUser()->isAllowed('suppressionlog')) {
         $out->addHTML(Xml::element('h2', null, $suppressLogPage->getName()->text()) . "\n");
         LogEventsList::showLogExtract($out, 'suppress', $this->mTargetObj);
     }
     if ($this->mAllowed && ($haveRevisions || $haveFiles)) {
         # Format the user-visible controls (comment field, submission button)
         # in a nice little table
         if ($this->getUser()->isAllowed('suppressrevision')) {
             $unsuppressBox = "<tr>\n\t\t\t\t\t\t<td>&#160;</td>\n\t\t\t\t\t\t<td class='mw-input'>" . Xml::checkLabel($this->msg('revdelete-unsuppress')->text(), 'wpUnsuppress', 'mw-undelete-unsuppress', $this->mUnsuppress) . "</td>\n\t\t\t\t\t</tr>";
         } else {
             $unsuppressBox = '';
         }
         $table = Xml::fieldset($this->msg('undelete-fieldset-title')->text()) . Xml::openElement('table', array('id' => 'mw-undelete-table')) . "<tr>\n\t\t\t\t\t<td colspan='2' class='mw-undelete-extrahelp'>" . $this->msg('undeleteextrahelp')->parseAsBlock() . "</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td class='mw-label'>" . Xml::label($this->msg('undeletecomment')->text(), 'wpComment') . "</td>\n\t\t\t\t<td class='mw-input'>" . Xml::input('wpComment', 50, $this->mComment, array('id' => 'wpComment', 'autofocus' => '')) . "</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td>&#160;</td>\n\t\t\t\t<td class='mw-submit'>" . Xml::submitButton($this->msg('undeletebtn')->text(), array('name' => 'restore', 'id' => 'mw-undelete-submit')) . ' ' . Xml::submitButton($this->msg('undeleteinvert')->text(), array('name' => 'invert', 'id' => 'mw-undelete-invert')) . "</td>\n\t\t\t</tr>" . $unsuppressBox . Xml::closeElement('table') . Xml::closeElement('fieldset');
         $out->addHTML($table);
     }
     $out->addHTML(Xml::element('h2', null, $this->msg('history')->text()) . "\n");
     if ($haveRevisions) {
         # The page's stored (deleted) history:
         $out->addHTML('<ul>');
         $remaining = $revisions->numRows();
         $earliestLiveTime = $this->mTargetObj->getEarliestRevTime();
         foreach ($revisions as $row) {
             $remaining--;
             $out->addHTML($this->formatRevisionRow($row, $earliestLiveTime, $remaining));
         }
         $revisions->free();
         $out->addHTML('</ul>');
     } else {
         $out->addWikiMsg('nohistory');
     }
     if ($haveFiles) {
         $out->addHTML(Xml::element('h2', null, $this->msg('filehist')->text()) . "\n");
         $out->addHTML('<ul>');
         foreach ($files as $row) {
             $out->addHTML($this->formatFileRow($row));
         }
         $files->free();
         $out->addHTML('</ul>');
     }
     if ($this->mAllowed) {
         # Slip in the hidden controls here
         $misc = Html::hidden('target', $this->mTarget);
         $misc .= Html::hidden('wpEditToken', $this->getUser()->getEditToken());
         $misc .= Xml::closeElement('form');
         $out->addHTML($misc);
     }
     return true;
 }