Krinkle has submitted this change and it was merged. Change subject: Clean up in preparation for the "Recent only" feature ......................................................................
Clean up in preparation for the "Recent only" feature * Remove traces of old justLastHour/onlyRecent implementation. * Simplify hasContribs() implementation. * Rename getRecentChanges() to getContribs() to avoid confusion with the recent changes table, since they actually come from the revision table right now. * Document the data structure so that we can add alternate fetch sources in addition to 'revision' (all contributions). * Move revision query to a separate method. * Prefix custom result fields with 'guc_'. Bug: T64914 Change-Id: I2e264ef3b41e991f08abab6dbf6d92671ed839b2 --- M composer.json M index.php M lb/guc.php M lb/wikicontribs.php M resources/frontend.js 5 files changed, 109 insertions(+), 71 deletions(-) Approvals: Krinkle: Verified; Looks good to me, approved diff --git a/composer.json b/composer.json index b4ef744..63d3d99 100644 --- a/composer.json +++ b/composer.json @@ -4,5 +4,8 @@ }, "scripts": { "test": "phpcs . --standard=phpcs.xml --ignore=vendor/* --extensions=php" + }, + "require": { + "Krinkle/toollabs-base": "^0.8.0" } } diff --git a/index.php b/index.php index 09b4c0a..e5818dd 100644 --- a/index.php +++ b/index.php @@ -15,7 +15,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -// Standard-Dateien +require_once __DIR__ . '/vendor/autoload.php'; require_once 'settings.php'; require_once 'app.php'; @@ -31,17 +31,12 @@ } $data = new stdClass(); -$data->Method = @$_SERVER['REQUEST_METHOD']; -$data->Referer = @$_SERVER['HTTP_REFERER']; -$data->Username = @$_REQUEST['user']; +$data->Method = @$_SERVER['REQUEST_METHOD'] ?: 'GET'; +$data->Referer = @$_SERVER['HTTP_REFERER'] ?: null; +$data->Username = @$_REQUEST['user'] ?: null; $data->options = array( 'isPrefixPattern' => @$_REQUEST['isPrefixPattern'] === '1', ); - -$data->Permalink = './?' . http_build_query(array_merge( - array( 'user' => $data->Username ), - array_map('intval', array_filter($data->options)) -)); // Create app $app = $guc = $error = $robotsPolicy = $canonicalUrl = null; @@ -61,6 +56,14 @@ } catch (Exception $e) { $error = $e; } + +$query = $data->options; +if ($data->Username) { + $query['user'] = $data->Username; +} +// Strip defaults +$query = array_diff_assoc( $query, guc::getDefaultOptions() ); +$data->Permalink = './' . ( !$query ? '' : '?' . http_build_query( $query ) ); $headRobots = !$robotsPolicy ? '' : '<meta name="robots" content="' . htmlspecialchars( $robotsPolicy ) . '">'; @@ -108,7 +111,7 @@ print '</div>'; } if ($guc) { - print '<p class="statistics">'.$guc->getWikiCount()." wikis searched. "; + print '<p class="statistics">'.$guc->getWikiCount().' wikis searched. '; print $guc->getGlobalEditcount().' edits found'; if ($guc->getResultWikiCount()) { print ' in '.$guc->getResultWikiCount().' projects'; @@ -149,7 +152,7 @@ // print '</pre>'; ?> <div class="footer"> - by <a href="https://wikitech.wikimedia.org/wiki/User:Luxo">Luxo</a> • <a href="https://wikitech.wikimedia.org/wiki/User:Krinkle">Krinkle</a> + by <a href="https://wikitech.wikimedia.org/wiki/User:Luxo">Luxo</a> • <a href="https://meta.wikimedia.org/wiki/User:Krinkle">Krinkle</a> </div> </div> <script src="resources/frontend.js"></script> diff --git a/lb/guc.php b/lb/guc.php index fb5eed5..3ac0f51 100644 --- a/lb/guc.php +++ b/lb/guc.php @@ -27,6 +27,13 @@ private $data; private $wikis; + public static function getDefaultOptions() { + return array( + 'isPrefixPattern' => false, + 'includeClosedWikis' => false, + ); + } + public function __construct(lb_app $app, $user, $options = array()) { $this->app = $app; @@ -34,11 +41,7 @@ $this->user = str_replace('_', ' ', ucfirst(trim($user))); // Defaults - $this->options = $options += array( - 'isPrefixPattern' => false, - 'includeClosedWikis' => false, - 'onlyRecent' => false, - ); + $this->options = $options += self::getDefaultOptions(); if (!$this->user) { throw new Exception('No username or IP'); @@ -95,7 +98,7 @@ $options ); if ($this->options['isPrefixPattern'] && !$contribs->getRegisteredUsers()) { - foreach ($contribs->getRecentChanges() as $rc) { + foreach ($contribs->getContribs() as $rc) { $this->addIP($rc->rev_user_text); if (count($this->hostnames) > 10) { break; @@ -152,9 +155,7 @@ $sql = 'SELECT * FROM `meta_p`.`wiki` WHERE '.$f_where.' LIMIT 1500;'; $statement = $this->app->getDB()->prepare($sql); $statement->execute(); - $rows = $statement->fetchAll(PDO::FETCH_OBJ); - unset($statement); - return $rows; + return $statement->fetchAll(PDO::FETCH_OBJ); } /** @@ -193,6 +194,7 @@ $statement->bindParam(':user', $this->user); } $statement->execute(); + $rows = $statement->fetchAll(PDO::FETCH_OBJ); foreach ($rows as $row) { $wiki = $wikisByDbname[$row->dbname]; @@ -202,7 +204,6 @@ $wikisWithEditcount[$row->dbname] = $wiki; } } - unset($statement); } } $this->globalEditCount = $globalEditCount; diff --git a/lb/wikicontribs.php b/lb/wikicontribs.php index 345f6f0..a65a7f3 100644 --- a/lb/wikicontribs.php +++ b/lb/wikicontribs.php @@ -27,8 +27,7 @@ private $centralAuth; private $hasManyMatches = false; - private $recentchanges = null; - private $hasContribs = false; + private $contribs = null; private $registeredUsers = array(); /** @@ -48,7 +47,7 @@ */ public function __construct(lb_app $app, $user, $isIP, $wiki, $centralAuth, $options = array()) { if (!$user) { - throw new Exception("No username or IP"); + throw new Exception('No username or IP'); } $this->app = $app; @@ -56,7 +55,6 @@ $this->isIp = $isIP; $this->options = $options += array( 'isPrefixPattern' => false, - 'onlyRecent' => false, ); $this->wiki = $wiki; @@ -98,28 +96,25 @@ // or a user name pattern with many matches. } - $this->_getRecentChanges(); + $this->contribs = $this->fetchContribs(); } - /** - * gibt die letzten 20 änderungen zurück - * @return mixed; + * @param PDO $pdo + * @param array $userIds + * @return PDOStatement */ - private function _getRecentChanges() { - $this->app->aTP('Query recent changes for ' . $this->wiki->domain); - $where = ''; - if ($this->options['onlyRecent']) { - $where = " `rev_timestamp` >= '" . date('YmdHis') . "' AND "; - } - $pdo = $this->app->getDB($this->wiki->dbname, $this->wiki->slice); - + private function prepareRevisionQuery(PDO $pdo) { + // Optimisation: Use rev_user index where possible + $userIdCond = ''; if ($this->registeredUsers) { $userIdCond = (count($this->registeredUsers) === 1) - ? ' = ' . $pdo->quote(key($this->registeredUsers)) - : ' IN (' . join(',', array_map(array($pdo, 'quote'), array_keys($this->registeredUsers))) . ')'; + ? '`rev_user` = ' . $pdo->quote(key($this->registeredUsers)) + : '`rev_user` IN (' . join(',', array_map( + array($pdo, 'quote'), + array_keys($this->registeredUsers)) + ) . ')'; } - $sql = "SELECT `rev_comment`, `rev_timestamp`, @@ -130,17 +125,16 @@ `rev_user_text`, `page_title`, `page_namespace`, - `page_latest` = `rev_id` AS `rev_cur` + `page_latest` = `rev_id` AS `guc_is_cur` FROM `revision_userindex` INNER JOIN `page` ON `rev_page` = `page_id` WHERE - ".$where." `rev_deleted` = 0 AND ".( - ($this->registeredUsers) - ? "`rev_user` $userIdCond" + ($userIdCond) + ? $userIdCond : ( ($this->options['isPrefixPattern']) ? 'rev_user_text LIKE :userlike' @@ -151,27 +145,48 @@ LIMIT 0, " . intval(self::CONTRIB_LIMIT) . ";"; $statement = $pdo->prepare($sql); - if (!$this->registeredUsers) { + if (!$userIdCond) { if ($this->options['isPrefixPattern']) { $statement->bindParam(':userlike', $this->user); } else { $statement->bindParam(':user', $this->user); } } + return $statement; + } + + /** + * Fetch contributions from the database + */ + private function fetchContribs() { + $this->app->aTP('Query contributions on ' . $this->wiki->domain); + $pdo = $this->app->getDB($this->wiki->dbname, $this->wiki->slice); + + $statement = $this->prepareRevisionQuery($pdo); $statement->execute(); - $this->recentchanges = $statement->fetchAll(PDO::FETCH_OBJ); - $this->hasContribs = !!$this->recentchanges; - unset($statement); - foreach ($this->recentchanges as $rc) { + + $contribs = $statement->fetchAll(PDO::FETCH_OBJ); + + foreach ($contribs as $rc) { + // Normalise $rc->rev_user_text = str_replace('_', ' ', $rc->rev_user_text); - // Expand page with prefixed namespace - $rc->page_namespace_name = $this->app->getNamespaceName($rc->page_namespace, $this->wiki->dbname, $this->wiki->canonical_server); - $rc->full_page_title = $rc->page_namespace_name - ? ($rc->page_namespace_name . ':' . $rc->page_title) + // Localised namespace prefix + $rc->guc_namespace_name = $this->app->getNamespaceName( + $rc->page_namespace, + $this->wiki->dbname, + $this->wiki->canonical_server + ); + // Full page name + $rc->guc_pagename = $rc->guc_namespace_name + ? ($rc->guc_namespace_name . ':' . $rc->page_title) + // Main namespace : $rc->page_title; - $rc->full_page_title = str_replace('_', ' ', $rc->full_page_title); + // Normalise + $rc->guc_pagename = str_replace('_', ' ', $rc->guc_pagename); } + + return $contribs; } /** @@ -183,15 +198,35 @@ } /** - * Get the latest contributions - * @return array of objects + * Get the fetched contributions + * @return array of objects with the following properties: + * - page_namespace + * - page_title + * - rev_comment + * - rev_id + * - rev_len + * - rev_minor_edit + * - rev_parent_id + * - rev_timestamp + * - rev_user_text (Normalised) + * - guc_is_cur + * - guc_namespace_name (Localised namespace prefix) + * - guc_pagename (Full page name) */ - public function getRecentChanges() { - return $this->recentchanges; + public function getContribs() { + return $this->contribs; + } + + + /** + * @return boolean + */ + public function hasContribs() { + return !!$this->contribs; } /** - * @return bool|int + * @return array Map of user id to user name */ public function getRegisteredUsers() { return $this->registeredUsers; @@ -243,10 +278,6 @@ return $res; } - public function hasContribs() { - return $this->hasContribs; - } - private function getUrl($pageName) { return $this->wiki->url . '/wiki/' . _wpurlencode($pageName); } @@ -294,13 +325,13 @@ $return .= '<p class="wikiinfo">' . join(' | ', $userinfo) . '</p>'; } $return .= '<ul>'; - foreach ($this->recentchanges as $rc) { + foreach ($this->getContribs() as $rc) { $item = array(); // Diff and history $item[] = - '(<a href="'.htmlspecialchars($this->getLongUrl('title='._wpurlencode($rc->full_page_title).'&diff=prev&oldid='.urlencode($rc->rev_id))).'">diff</a>' + '(<a href="'.htmlspecialchars($this->getLongUrl('title='._wpurlencode($rc->guc_pagename).'&diff=prev&oldid='.urlencode($rc->rev_id))).'">diff</a>' . ' | ' - . '<a href="'.htmlspecialchars($this->getLongUrl('title='._wpurlencode($rc->full_page_title).'&action=history')).'">hist</a>)' + . '<a href="'.htmlspecialchars($this->getLongUrl('title='._wpurlencode($rc->guc_pagename).'&action=history')).'">hist</a>)' ; // Date @@ -321,16 +352,16 @@ } // Link to the page - $item[] = '<a href="'.htmlspecialchars($this->getUrl($rc->full_page_title)).'">' - . htmlspecialchars($rc->full_page_title)."</a>"; + $item[] = '<a href="'.htmlspecialchars($this->getUrl($rc->guc_pagename)).'">' + . htmlspecialchars($rc->guc_pagename)."</a>"; // Edit summary if ($rc->rev_comment) { - $item[] = '<span class="comment">('.$this->app->wikiparser($rc->rev_comment, $rc->full_page_title, $this->wiki->url).')</span>'; + $item[] = '<span class="comment">('.$this->app->wikiparser($rc->rev_comment, $rc->guc_pagename, $this->wiki->url).')</span>'; } // Cur revision - if ($rc->rev_cur) { + if ($rc->guc_is_cur) { $item[] = '<span class="rev_cur">(current)</span>'; } $return .= '<li>' . join(' ', $item) . '</li>'; diff --git a/resources/frontend.js b/resources/frontend.js index eea8776..5a9498e 100644 --- a/resources/frontend.js +++ b/resources/frontend.js @@ -14,7 +14,7 @@ return; } - function getId (id) { + function getId(id) { return document.getElementById(id); } -- To view, visit https://gerrit.wikimedia.org/r/307104 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I2e264ef3b41e991f08abab6dbf6d92671ed839b2 Gerrit-PatchSet: 7 Gerrit-Project: labs/tools/guc Gerrit-Branch: master Gerrit-Owner: Krinkle <krinklem...@gmail.com> Gerrit-Reviewer: Krinkle <krinklem...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits