/** * Purge the cache for pages containing gallery tags */ public function purge() { global $wgUseFileCache, $wgUseSquid; $totalGalleryPageCount = 0; // Keeps track of actual existing titles with gallery $dbGalleryCount = $this->getGalleryPageCount(); // All counts including those with missing titles // Paginate the operation to prevent db/memory overload for ($limitCount = 0; $limitCount < $dbGalleryCount; $limitCount += self::PAGE_COUNT_LIMIT) { $galleryPageIds = $this->getGalleryPageIds($limitCount); $galleryPageTitles = \Title::newFromIDs($galleryPageIds); $galleryPageCount = count($galleryPageTitles); // abort if no pages were found if ($galleryPageCount == 0) { continue; } // Update squid/varnish/parser cache if ($wgUseSquid) { foreach ($galleryPageTitles as $title) { $title->purgeSquid(); } } // Update file cache if used if ($wgUseFileCache) { foreach ($galleryPageTitles as $title) { \HTMLFileCache::clearFileCache($title); } } $totalGalleryPageCount += $galleryPageCount; } $this->info('Gallery page purge request', ['title' => __METHOD__, 'count' => $totalGalleryPageCount]); return $totalGalleryPageCount; }
function getAverageLength($ids) { $titles = Title::newFromIDs($ids); $len = 0; foreach ($titles as $title) { $len += strlen($title->getText()); } return $len / count($titles); }
public function getTargets() { if ($this->mTo) { return $this->mTo; } $dbr = wfGetDB(DB_SLAVE); $ns = $this->mFrom->getNamespace(); $t = $this->mFrom->getDBkey(); $res = $dbr->select('indexes', 'in_from', array('in_namespace' => $ns, 'in_title' => $t), __METHOD__); $ids = array(); foreach ($res as $row) { $ids[] = $row->in_from; } $this->mTo = Title::newFromIDs($ids); return $this->mTo; }
/** * @see SMWStore::refreshData * * @param integer $index * @param integer $count * @param mixed $namespaces Array or false * @param boolean $usejobs * * @return decimal between 0 and 1 to indicate the overall progress of the refreshing */ public function refreshData(&$index, $count, $namespaces = false, $usejobs = true) { $updatejobs = array(); $emptyrange = true; // was nothing done in this run? // Update by MediaWiki page id --> make sure we get all pages. $tids = array(); // Array of ids for ($i = $index; $i < $index + $count; $i++) { $tids[] = $i; } $titles = Title::newFromIDs($tids); foreach ($titles as $title) { if ($namespaces == false || in_array($title->getNamespace(), $namespaces)) { $updatejobs[] = new SMWUpdateJob($title); $emptyrange = false; } } // update by internal SMW id --> make sure we get all objects in SMW $dbr = wfGetDB(DB_SLAVE); $res = $dbr->select('smw_ids', array('smw_id', 'smw_title', 'smw_namespace', 'smw_iw', 'smw_subobject'), array("smw_id >= {$index} ", " smw_id < " . $dbr->addQuotes($index + $count)), __METHOD__); foreach ($res as $row) { $emptyrange = false; // note this even if no jobs were created if ($namespaces && !in_array($row->smw_namespace, $namespaces)) { continue; } if ($row->smw_subobject !== '') { // leave subobjects alone; they ought to be changed with their pages } elseif ($row->smw_iw === '' || $row->smw_iw == SMW_SQL2_SMWREDIIW) { // objects representing pages // TODO: special treament of redirects needed, since the store will // not act on redirects that did not change according to its records $title = Title::makeTitleSafe($row->smw_namespace, $row->smw_title); if ($title !== null && !$title->exists()) { $updatejobs[] = new SMWUpdateJob($title); } } elseif ($row->smw_iw == SMW_SQL2_SMWIW_OUTDATED) { // remove outdated internal object references foreach (self::getPropertyTables() as $proptable) { if ($proptable->idsubject) { $dbr->delete($proptable->name, array('s_id' => $row->smw_id), __METHOD__); } } $dbr->delete('smw_ids', array('smw_id' => $row->smw_id), __METHOD__); } else { // "normal" interwiki pages or outdated internal objects $diWikiPage = new SMWDIWikiPage($row->smw_title, $row->smw_namespace, $row->smw_iw); $this->deleteSemanticData($diWikiPage); } } $dbr->freeResult($res); wfRunHooks('smwRefreshDataJobs', array(&$updatejobs)); if ($usejobs) { Job::batchInsert($updatejobs); } else { foreach ($updatejobs as $job) { $job->run(); } } $nextpos = $index + $count; if ($emptyrange) { // nothing found, check if there will be more pages later on $next1 = $dbr->selectField('page', 'page_id', "page_id >= {$nextpos}", __METHOD__, array('ORDER BY' => "page_id ASC")); $next2 = $dbr->selectField('smw_ids', 'smw_id', "smw_id >= {$nextpos}", __METHOD__, array('ORDER BY' => "smw_id ASC")); $nextpos = $next2 != 0 && $next2 < $next1 ? $next2 : $next1; } $max1 = $dbr->selectField('page', 'MAX(page_id)', '', __METHOD__); $max2 = $dbr->selectField('smw_ids', 'MAX(smw_id)', '', __METHOD__); $index = $nextpos ? $nextpos : -1; return $index > 0 ? $index / max($max1, $max2) : 1; }
/** * Invalidate a set of IDs, right now */ function invalidateIDs(ResultWrapper $res) { global $wgUseFileCache, $wgUseSquid; if ($res->numRows() == 0) { return; } $dbw =& wfGetDB(DB_MASTER); $timestamp = $dbw->timestamp(); $done = false; while (!$done) { # Get all IDs in this query into an array $ids = array(); for ($i = 0; $i < $this->mRowsPerQuery; $i++) { $row = $res->fetchRow(); if ($row) { $ids[] = $row[0]; } else { $done = true; break; } } if (!count($ids)) { break; } # Update page_touched $dbw->update('page', array('page_touched' => $timestamp), array('page_id IN (' . $dbw->makeList($ids) . ')'), __METHOD__); # Update squid if ($wgUseSquid || $wgUseFileCache) { $titles = Title::newFromIDs($ids); if ($wgUseSquid) { $u = SquidUpdate::newFromTitles($titles); $u->doUpdate(); } # Update file cache if ($wgUseFileCache) { foreach ($titles as $title) { $cm = new CacheManager($title); @unlink($cm->fileCacheName()); } } } } }
protected function getArticlesDetails($articleIds, $articleKeys = [], $width = 0, $height = 0, $abstract = 0, $strict = false) { $articles = is_array($articleIds) ? $articleIds : [$articleIds]; $ids = []; $collection = []; $resultingCollectionIds = []; $titles = []; foreach ($articles as $i) { //data is cached on a per-article basis //to avoid one article requiring purging //the whole collection $cache = $this->wg->Memc->get(self::getCacheKey($i, self::DETAILS_CACHE_ID)); if (!is_array($cache)) { $ids[] = $i; } else { $collection[$i] = $cache; $resultingCollectionIds[] = $i; } } if (count($ids) > 0) { $titles = Title::newFromIDs($ids); } if (!empty($articleKeys)) { foreach ($articleKeys as $titleKey) { $titleObj = Title::newFromDbKey($titleKey); if ($titleObj instanceof Title && $titleObj->exists()) { $titles[] = $titleObj; } } } if (!empty($titles)) { foreach ($titles as $t) { $fileData = []; if ($t->getNamespace() == NS_FILE) { $fileData = $this->getFromFile($t->getText()); } elseif ($t->getNamespace() == NS_MAIN) { $fileData = ['type' => static::ARTICLE_TYPE]; } elseif ($t->getNamespace() == NS_CATEGORY) { $fileData = ['type' => static::CATEGORY_TYPE]; } $id = $t->getArticleID(); $revId = $t->getLatestRevID(); $rev = Revision::newFromId($revId); if (!empty($rev)) { $collection[$id] = ['id' => $id, 'title' => $t->getText(), 'ns' => $t->getNamespace(), 'url' => $t->getLocalURL(), 'revision' => ['id' => $revId, 'user' => $rev->getUserText(Revision::FOR_PUBLIC), 'user_id' => $rev->getUser(Revision::FOR_PUBLIC), 'timestamp' => wfTimestamp(TS_UNIX, $rev->getTimestamp())]]; $collection[$id]['comments'] = class_exists('ArticleCommentList') ? ArticleCommentList::newFromTitle($t)->getCountAllNested() : false; //add file data $collection[$id] = array_merge($collection[$id], $fileData); $resultingCollectionIds[] = $id; $this->wg->Memc->set(self::getCacheKey($id, self::DETAILS_CACHE_ID), $collection[$id], 86400); } else { $dataLog = ['titleText' => $t->getText(), 'articleId' => $t->getArticleID(), 'revId' => $revId]; WikiaLogger::instance()->info('No revision found for article', $dataLog); } } $titles = null; } //ImageServing has separate caching //so processing it separately allows to //make the thumbnail's size parametrical without //invalidating the titles details' cache //or the need to duplicate it $thumbnails = $this->getArticlesThumbnails($resultingCollectionIds, $width, $height); $articles = null; //ArticleService has separate caching //so processing it separately allows to //make the length parametrical without //invalidating the titles details' cache //or the need to duplicate it foreach ($collection as $id => &$details) { if ($abstract > 0) { $as = new ArticleService($id); $snippet = $as->getTextSnippet($abstract); } else { $snippet = null; } $details['abstract'] = $snippet; if (isset($thumbnails[$id])) { $details = array_merge($details, $thumbnails[$id]); } } $collection = $this->appendMetadata($collection); $thumbnails = null; //The collection can be in random order (depends if item was found in memcache or not) //lets preserve original order even if we are not using strict mode: //to keep things consistent over time (some other APIs that are using sorted results are using //ArticleApi::getDetails to fetch info about articles) $orderedIdsFromTitles = array_diff(array_keys($collection), $articleIds); //typecasting to convert falsy values into empty array (array_merge require arrays only) $orderedIds = array_merge((array) $articleIds, (array) $orderedIdsFromTitles); $collection = $this->preserveOriginalOrder($orderedIds, $collection); //if strict - return array instead of associative array (dict) if ($strict) { return array_values($collection); } else { return $collection; } }
public function refreshData(&$index, $count, $namespaces = false, $usejobs = true) { $updatejobs = array(); $emptyrange = true; // was nothing found in this run? // update by MediaWiki page id --> make sure we get all pages $tids = array(); for ($i = $index; $i < $index + $count; $i++) { // array of ids $tids[] = $i; } $titles = Title::newFromIDs($tids); foreach ($titles as $title) { if ($namespaces == false || in_array($title->getNamespace(), $namespaces)) { // wikia change start - jobqueue migration $task = new \Wikia\Tasks\Tasks\JobWrapperTask(); $task->call('SMWUpdateJob', $title); $updatejobs[] = $task; // wikia change end $emptyrange = false; } } wfRunHooks('smwRefreshDataJobs', array(&$updatejobs)); if ($usejobs) { // wikia change start - jobqueue migration \Wikia\Tasks\Tasks\BaseTask::batch($updatejobs); // wikia change end } else { foreach ($updatejobs as $job) { // wikia change start - jobqueue migration /** @var \Wikia\Tasks\Tasks\JobWrapperTask $job */ try { $job->init(); } catch (Exception $e) { continue; } $job->wrap('SMWUpdateJob'); // wikia change end } } $db = wfGetDB(DB_SLAVE); $nextpos = $index + $count; if ($emptyrange) { // nothing found, check if there will be more pages later on $nextpos = $db->selectField('page', 'page_id', "page_id >= {$nextpos}", __METHOD__, array('ORDER BY' => "page_id ASC")); } $maxpos = $db->selectField('page', 'MAX(page_id)', '', __METHOD__); $index = $nextpos ? $nextpos : -1; return $index > 0 ? $index / $maxpos : 1; }
/** * @desc Creates instances of Title for given pages ids and returns array of titles' texts * * @param Array $pages * @return array */ public function getArtistTitlesFromIds($pages) { $result = []; $artistsTitles = Title::newFromIDs($pages); foreach ($artistsTitles as $artistTitle) { $result[] = $artistTitle->getText(); } return $result; }
/** * @see SMWStore::refreshData * * @todo This method will be overhauled in SMW 1.9 to become cleaner * and more robust. * * @param integer $index * @param integer $count * @param mixed $namespaces Array or false * @param boolean $usejobs * * @return decimal between 0 and 1 to indicate the overall progress of the refreshing */ public function refreshData(&$index, $count, $namespaces = false, $usejobs = true) { $updatejobs = array(); $emptyrange = true; // was nothing done in this run? // Update by MediaWiki page id --> make sure we get all pages. $tids = array(); // Array of ids for ($i = $index; $i < $index + $count; $i++) { $tids[] = $i; } $titles = Title::newFromIDs($tids); foreach ($titles as $title) { if ($namespaces == false || in_array($title->getNamespace(), $namespaces)) { // wikia change start - jobqueue migration $task = new \Wikia\Tasks\Tasks\JobWrapperTask(); $task->call('SMWUpdateJob', $title); $updatejobs[] = $task; // wikia change end $emptyrange = false; } } // update by internal SMW id --> make sure we get all objects in SMW $dbr = wfGetDB(DB_SLAVE, 'smw'); $res = $dbr->select(SMWSql3SmwIds::tableName, array('smw_id', 'smw_title', 'smw_namespace', 'smw_iw', 'smw_subobject'), array("smw_id >= {$index} ", " smw_id < " . $dbr->addQuotes($index + $count)), __METHOD__); foreach ($res as $row) { $emptyrange = false; // note this even if no jobs were created if ($namespaces && !in_array($row->smw_namespace, $namespaces)) { continue; } // Find page to refresh, even for special properties: if ($row->smw_title != '' && $row->smw_title[0] != '_') { $titleKey = $row->smw_title; } elseif ($row->smw_namespace == SMW_NS_PROPERTY && $row->smw_iw == '' && $row->smw_subobject == '') { $titleKey = str_replace(' ', '_', SMWDIProperty::findPropertyLabel($row->smw_title)); } else { $titleKey = ''; } if ($row->smw_subobject !== '') { // leave subobjects alone; they ought to be changed with their pages } elseif (($row->smw_iw === '' || $row->smw_iw == SMW_SQL3_SMWREDIIW) && $titleKey != '') { // objects representing pages // TODO: special treament of redirects needed, since the store will // not act on redirects that did not change according to its records $title = Title::makeTitleSafe($row->smw_namespace, $titleKey); if ($title !== null && !$title->exists()) { // wikia change start - jobqueue migration $task = new \Wikia\Tasks\Tasks\JobWrapperTask(); $task->call('SMWUpdateJob', $title); $updatejobs[] = $task; // wikia change end } } elseif ($row->smw_iw == SMW_SQL3_SMWIW_OUTDATED) { // remove outdated internal object references $dbw = wfGetDB(DB_MASTER, 'smw'); foreach (SMWSQLStore3::getPropertyTables() as $proptable) { if ($proptable->usesIdSubject()) { $dbw->delete($proptable->getName(), array('s_id' => $row->smw_id), __METHOD__); } } $dbw->delete(SMWSql3SmwIds::tableName, array('smw_id' => $row->smw_id), __METHOD__); } elseif ($titleKey != '') { // "normal" interwiki pages or outdated internal objects -- delete $diWikiPage = new SMWDIWikiPage($titleKey, $row->smw_namespace, $row->smw_iw); $emptySemanticData = new SMWSemanticData($diWikiPage); $this->store->doDataUpdate($emptySemanticData); } } $dbr->freeResult($res); wfRunHooks('smwRefreshDataJobs', array(&$updatejobs)); if ($usejobs) { // wikia change start - jobqueue migration \Wikia\Tasks\Tasks\BaseTask::batch($updatejobs); // wikia change end } else { foreach ($updatejobs as $job) { // wikia change start - jobqueue migration /** @var \Wikia\Tasks\Tasks\JobWrapperTask $job */ try { $job->init(); } catch (Exception $e) { continue; } $job->wrap('SMWUpdateJob'); // wikia change end } } $nextpos = $index + $count; // smw+ wikia change, handler to local database $dbl = wfGetDB(DB_SLAVE); if ($emptyrange) { // nothing found, check if there will be more pages later on $next1 = $dbl->selectField('page', 'page_id', "page_id >= {$nextpos}", __METHOD__, array('ORDER BY' => "page_id ASC")); $next2 = $dbr->selectField(SMWSql3SmwIds::tableName, 'smw_id', "smw_id >= {$nextpos}", __METHOD__, array('ORDER BY' => "smw_id ASC")); $nextpos = $next2 != 0 && $next2 < $next1 ? $next2 : $next1; } $max1 = $dbl->selectField('page', 'MAX(page_id)', '', __METHOD__); $max2 = $dbr->selectField(SMWSql3SmwIds::tableName, 'MAX(smw_id)', '', __METHOD__); $index = $nextpos ? $nextpos : -1; return $index > 0 ? $index / max($max1, $max2) : 1; }
/** * Invalidate a set of IDs, right now */ public function invalidateIDs(ResultWrapper $res) { global $wgUseFileCache, $wgUseSquid; if ($res->numRows() == 0) { return; } // sanity check $dbw = wfGetDB(DB_MASTER); $timestamp = $dbw->timestamp(); $done = false; while (!$done) { # Get all IDs in this query into an array $ids = array(); for ($i = 0; $i < $this->mRowsPerQuery; $i++) { $row = $res->fetchRow(); if ($row) { $ids[] = $row[0]; } else { $done = true; break; } } if (count($ids) == 0) { break; } # Update page_touched $dbw->update('page', array('page_touched' => $timestamp), array('page_id' => $ids), __METHOD__); # Update static caches if ($wgUseSquid || $wgUseFileCache) { $titles = Title::newFromIDs($ids); # Update squid cache if ($wgUseSquid) { $u = SquidUpdate::newFromTitles($titles); $u->doUpdate(); } # Update file cache if ($wgUseFileCache) { foreach ($titles as $title) { HTMLFileCache::clearFileCache($title); } } } } }
protected function getCommentsNumber($item) { $titles = Title::newFromIDs($item['pageid']); if (empty($titles)) { return null; } $title = $titles[0]; if (class_exists('ArticleCommentList')) { $commentsList = ArticleCommentList::newFromTitle($title); return $commentsList->getCountAllNested(); } return null; }
public function latestViewPages($namespace = -1) { global $wgStatsDB, $wgStatsDBEnabled, $wgLang; wfProfileIn(__METHOD__); $result = array(); if (!empty($wgStatsDBEnabled)) { $dbr = wfGetDB(DB_SLAVE, array(), $wgStatsDB); $where = array("pv_city_id" => $this->mCityId, "pv_ts >= '" . date('Y-m-d H-i-s', time() - self::PV_DELTA) . "'"); if ($namespace > 0) { $where['pv_namespace'] = $namespace; } $res = $dbr->select(array('page_views_articles'), array('pv_page_id', 'pv_views'), $where, __METHOD__, array('ORDER BY' => 'pv_ts DESC', 'LIMIT' => self::PV_LIMIT)); $ids = array(); $count = array(); $loop = 0; while ($oRow = $dbr->fetchObject($res)) { if (!isset($ids[$oRow->pv_page_id])) { $ids[$oRow->pv_page_id] = $loop; $loop++; } $count[$oRow->pv_page_id] += $oRow->pv_views; } $dbr->freeResult($res); $titles = Title::newFromIDs(array_keys($ids)); $urls = array(); foreach ($titles as $oTitle) { $page_id = $oTitle->getArticleID(); $urls[$page_id] = Xml::element("a", array("href" => $oTitle->getLocalURL()), $oTitle->getFullText()); } foreach ($ids as $page_id => $position) { if (isset($urls[$page_id])) { $result[] = $wgLang->specialList($urls[$page_id], $count[$page_id] . "x"); } } } wfProfileOut(__METHOD__); #--- return $result; }
public function refreshData( &$index, $count, $namespaces = false, $usejobs = true ) { $updatejobs = array(); $emptyrange = true; // was nothing found in this run? // update by MediaWiki page id --> make sure we get all pages $tids = array(); for ( $i = $index; $i < $index + $count; $i++ ) { // array of ids $tids[] = $i; } $titles = Title::newFromIDs( $tids ); foreach ( $titles as $title ) { if ( ( $namespaces == false ) || ( in_array( $title->getNamespace(), $namespaces ) ) ) { $updatejobs[] = new SMWUpdateJob( $title ); $emptyrange = false; } } wfRunHooks('smwRefreshDataJobs', array(&$updatejobs)); if ( $usejobs ) { Job::batchInsert( $updatejobs ); } else { foreach ( $updatejobs as $job ) { $job->run(); } } $db = wfGetDB( DB_SLAVE ); $nextpos = $index + $count; if ( $emptyrange ) { // nothing found, check if there will be more pages later on $nextpos = $db->selectField( 'page', 'page_id', "page_id >= $nextpos", __METHOD__, array( 'ORDER BY' => "page_id ASC" ) ); } $maxpos = $db->selectField( 'page', 'MAX(page_id)', '', __METHOD__ ); $index = $nextpos ? $nextpos : -1; return ( $index > 0 ) ? ( $index / $maxpos ) : 1; }