示例#1
0
 /**
  * Same as addWatch, only the opposite.
  * @return bool
  */
 public function removeWatch()
 {
     $success = false;
     $dbw = wfGetDB(DB_MASTER);
     $dbw->delete('watchlist', array('wl_user' => $this->id, 'wl_namespace' => MWNamespace::getSubject($this->ns), 'wl_title' => $this->ti), __METHOD__);
     if ($dbw->affectedRows()) {
         $success = true;
     }
     # the following code compensates the new behaviour, introduced by the
     # enotif patch, that every single watched page needs now to be listed
     # in watchlist namespace:page and namespace_talk:page had separate
     # entries: clear them
     $dbw->delete('watchlist', array('wl_user' => $this->id, 'wl_namespace' => MWNamespace::getTalk($this->ns), 'wl_title' => $this->ti), __METHOD__);
     if ($dbw->affectedRows()) {
         $success = true;
     }
     return $success;
 }
示例#2
0
 function register()
 {
     global $wgContLang, $wgNamespaceAliases, $wgNonincludableNamespaces;
     $lib = array('loadSiteStats' => array($this, 'loadSiteStats'), 'getNsIndex' => array($this, 'getNsIndex'), 'pagesInCategory' => array($this, 'pagesInCategory'), 'pagesInNamespace' => array($this, 'pagesInNamespace'), 'usersInGroup' => array($this, 'usersInGroup'));
     $info = array('siteName' => $GLOBALS['wgSitename'], 'server' => $GLOBALS['wgServer'], 'scriptPath' => $GLOBALS['wgScriptPath'], 'stylePath' => $GLOBALS['wgStylePath'], 'currentVersion' => SpecialVersion::getVersion());
     if (!self::$namespacesCache) {
         $namespaces = array();
         $namespacesByName = array();
         foreach ($wgContLang->getFormattedNamespaces() as $ns => $title) {
             $canonical = MWNamespace::getCanonicalName($ns);
             $namespaces[$ns] = array('id' => $ns, 'name' => $title, 'canonicalName' => strtr($canonical, '_', ' '), 'hasSubpages' => MWNamespace::hasSubpages($ns), 'hasGenderDistinction' => MWNamespace::hasGenderDistinction($ns), 'isCapitalized' => MWNamespace::isCapitalized($ns), 'isContent' => MWNamespace::isContent($ns), 'isIncludable' => !($wgNonincludableNamespaces && in_array($ns, $wgNonincludableNamespaces)), 'isMovable' => MWNamespace::isMovable($ns), 'isSubject' => MWNamespace::isSubject($ns), 'isTalk' => MWNamespace::isTalk($ns), 'aliases' => array());
             if ($ns >= NS_MAIN) {
                 $namespaces[$ns]['subject'] = MWNamespace::getSubject($ns);
                 $namespaces[$ns]['talk'] = MWNamespace::getTalk($ns);
                 $namespaces[$ns]['associated'] = MWNamespace::getAssociated($ns);
             } else {
                 $namespaces[$ns]['subject'] = $ns;
             }
             $namespacesByName[strtr($title, ' ', '_')] = $ns;
             if ($canonical) {
                 $namespacesByName[$canonical] = $ns;
             }
         }
         $aliases = array_merge($wgNamespaceAliases, $wgContLang->getNamespaceAliases());
         foreach ($aliases as $title => $ns) {
             if (!isset($namespacesByName[$title])) {
                 $ct = count($namespaces[$ns]['aliases']);
                 $namespaces[$ns]['aliases'][$ct + 1] = $title;
                 $namespacesByName[$title] = $ns;
             }
         }
         $namespaces[NS_MAIN]['displayName'] = wfMessage('blanknamespace')->text();
         self::$namespacesCache = $namespaces;
     }
     $info['namespaces'] = self::$namespacesCache;
     if (self::$siteStatsLoaded) {
         $stats = $this->loadSiteStats();
         $info['stats'] = $stats[0];
     }
     $this->getEngine()->registerInterface('mw.site.lua', $lib, $info);
 }
示例#3
0
 function register()
 {
     global $wgContLang, $wgNamespaceAliases, $wgDisableCounters;
     $lib = array('getNsIndex' => array($this, 'getNsIndex'), 'pagesInCategory' => array($this, 'pagesInCategory'), 'pagesInNamespace' => array($this, 'pagesInNamespace'), 'usersInGroup' => array($this, 'usersInGroup'), 'interwikiMap' => array($this, 'interwikiMap'));
     $info = array('siteName' => $GLOBALS['wgSitename'], 'server' => $GLOBALS['wgServer'], 'scriptPath' => $GLOBALS['wgScriptPath'], 'stylePath' => $GLOBALS['wgStylePath'], 'currentVersion' => SpecialVersion::getVersion());
     if (!self::$namespacesCache || self::$namespacesCacheLang !== $wgContLang->getCode()) {
         $namespaces = array();
         $namespacesByName = array();
         foreach ($wgContLang->getFormattedNamespaces() as $ns => $title) {
             $canonical = MWNamespace::getCanonicalName($ns);
             $namespaces[$ns] = array('id' => $ns, 'name' => $title, 'canonicalName' => strtr($canonical, '_', ' '), 'hasSubpages' => MWNamespace::hasSubpages($ns), 'hasGenderDistinction' => MWNamespace::hasGenderDistinction($ns), 'isCapitalized' => MWNamespace::isCapitalized($ns), 'isContent' => MWNamespace::isContent($ns), 'isIncludable' => !MWNamespace::isNonincludable($ns), 'isMovable' => MWNamespace::isMovable($ns), 'isSubject' => MWNamespace::isSubject($ns), 'isTalk' => MWNamespace::isTalk($ns), 'defaultContentModel' => MWNamespace::getNamespaceContentModel($ns), 'aliases' => array());
             if ($ns >= NS_MAIN) {
                 $namespaces[$ns]['subject'] = MWNamespace::getSubject($ns);
                 $namespaces[$ns]['talk'] = MWNamespace::getTalk($ns);
                 $namespaces[$ns]['associated'] = MWNamespace::getAssociated($ns);
             } else {
                 $namespaces[$ns]['subject'] = $ns;
             }
             $namespacesByName[strtr($title, ' ', '_')] = $ns;
             if ($canonical) {
                 $namespacesByName[$canonical] = $ns;
             }
         }
         $aliases = array_merge($wgNamespaceAliases, $wgContLang->getNamespaceAliases());
         foreach ($aliases as $title => $ns) {
             if (!isset($namespacesByName[$title]) && isset($namespaces[$ns])) {
                 $ct = count($namespaces[$ns]['aliases']);
                 $namespaces[$ns]['aliases'][$ct + 1] = $title;
                 $namespacesByName[$title] = $ns;
             }
         }
         $namespaces[NS_MAIN]['displayName'] = wfMessage('blanknamespace')->inContentLanguage()->text();
         self::$namespacesCache = $namespaces;
         self::$namespacesCacheLang = $wgContLang->getCode();
     }
     $info['namespaces'] = self::$namespacesCache;
     $info['stats'] = array('pages' => (int) SiteStats::pages(), 'articles' => (int) SiteStats::articles(), 'files' => (int) SiteStats::images(), 'edits' => (int) SiteStats::edits(), 'views' => $wgDisableCounters ? null : (int) SiteStats::views(), 'users' => (int) SiteStats::users(), 'activeUsers' => (int) SiteStats::activeUsers(), 'admins' => (int) SiteStats::numberingroup('sysop'));
     return $this->getEngine()->registerInterface('mw.site.lua', $lib, $info);
 }
示例#4
0
 /**
  * Get the preferred destination title for a given target page.
  * @param integer $ns The destination namespace ID
  * @param string $name The conflicting prefix
  * @param integer $sourceNs The source namespace
  * @param integer $sourceDbk The source DB key (i.e. page_title)
  * @param array $options Associative array of validated command-line options
  * @return Title|false
  */
 private function getDestinationTitle($ns, $name, $sourceNs, $sourceDbk, $options)
 {
     $dbk = substr($sourceDbk, strlen("{$name}:"));
     if ($ns == 0) {
         // An interwiki; try an alternate encoding with '-' for ':'
         $dbk = "{$name}-" . $dbk;
     }
     $destNS = $ns;
     if ($sourceNs == NS_TALK && MWNamespace::isSubject($ns)) {
         // This is an associated talk page moved with the --move-talk feature.
         $destNS = MWNamespace::getTalk($destNS);
     }
     $newTitle = Title::makeTitleSafe($destNS, $dbk);
     if (!$newTitle || !$newTitle->canExist()) {
         return false;
     }
     return $newTitle;
 }
 /**
  * move one comment
  *
  * @access public
  * @static
  *
  * @param $oCommentTitle Title
  * @param $oNewTitle title
  */
 private static function moveComment($oCommentTitle, &$oNewTitle, $reason = '')
 {
     global $wgUser;
     wfProfileIn(__METHOD__);
     if (!is_object($oCommentTitle)) {
         wfProfileOut(__METHOD__);
         return array('invalid title');
     }
     $currentUser = $wgUser;
     $wgUser = User::newFromName(self::MOVE_USER);
     $parts = self::explode($oCommentTitle->getDBkey());
     $commentTitleText = implode('/', $parts['partsOriginal']);
     $newCommentTitle = Title::newFromText(sprintf('%s/%s', $oNewTitle->getText(), $commentTitleText), MWNamespace::getTalk($oNewTitle->getNamespace()));
     $error = $oCommentTitle->moveTo($newCommentTitle, false, $reason, false);
     $wgUser = $currentUser;
     wfProfileOut(__METHOD__);
     return $error;
 }
 public function onAfterLanguageGetNamespaces(&$namespaces)
 {
     wfProfileIn(__METHOD__);
     $app = F::App();
     $title = $app->wg->Title;
     if (empty($title) || !$title->isSpecial('Allpages')) {
         wfProfileOut(__METHOD__);
         return true;
     }
     foreach ($app->wg->WallNS as $val) {
         $ns = MWNamespace::getTalk($val);
         if (!empty($namespaces[$ns])) {
             unset($namespaces[$ns]);
         }
     }
     wfProfileOut(__METHOD__);
     return true;
 }
示例#7
0
 /**
  * Get a Title object associated with the talk page of this article
  *
  * @return Title The object for the talk page
  */
 public function getTalkPage()
 {
     return Title::makeTitle(MWNamespace::getTalk($this->getNamespace()), $this->getDBkey());
 }
示例#8
0
 /**
  * Get talk page IDs (if requested) and subject page IDs (if requested)
  * and put them in $talkids and $subjectids 
  */
 private function getTSIDs()
 {
     $getTitles = $this->talkids = $this->subjectids = array();
     $db = $this->getDB();
     foreach ($this->everything as $t) {
         if (MWNamespace::isTalk($t->getNamespace())) {
             if ($this->fld_subjectid) {
                 $getTitles[] = $t->getSubjectPage();
             }
         } else {
             if ($this->fld_talkid) {
                 $getTitles[] = $t->getTalkPage();
             }
         }
     }
     if (!count($getTitles)) {
         return;
     }
     // Construct a custom WHERE clause that matches
     // all titles in $getTitles
     $lb = new LinkBatch($getTitles);
     $this->resetQueryParams();
     $this->addTables('page');
     $this->addFields(array('page_title', 'page_namespace', 'page_id'));
     $this->addWhere($lb->constructSet('page', $db));
     $res = $this->select(__METHOD__);
     while ($row = $db->fetchObject($res)) {
         if (MWNamespace::isTalk($row->page_namespace)) {
             $this->talkids[MWNamespace::getSubject($row->page_namespace)][$row->page_title] = intval($row->page_id);
         } else {
             $this->subjectids[MWNamespace::getTalk($row->page_namespace)][$row->page_title] = intval($row->page_id);
         }
     }
 }
示例#9
0
 /**
  * Same as addWatch, only the opposite.
  * @return bool
  */
 public function removeWatch()
 {
     // Only loggedin user can have a watchlist
     if (wfReadOnly() || $this->mUser->isAnon()) {
         return false;
     }
     $success = false;
     $dbw = wfGetDB(DB_MASTER);
     $dbw->delete('watchlist', array('wl_user' => $this->userID, 'wl_namespace' => MWNamespace::getSubject($this->nameSpace), 'wl_title' => $this->databaseKey), __METHOD__);
     if ($dbw->affectedRows()) {
         $success = true;
     }
     # the following code compensates the new behaviour, introduced by the
     # enotif patch, that every single watched page needs now to be listed
     # in watchlist namespace:page and namespace_talk:page had separate
     # entries: clear them
     $dbw->delete('watchlist', array('wl_user' => $this->userID, 'wl_namespace' => MWNamespace::getTalk($this->nameSpace), 'wl_title' => $this->databaseKey), __METHOD__);
     // No errors, update the global_watchlist table.
     if ($dbw->affectedRows()) {
         wfRunHooks('WatchedItem::updateWatch', array($this, $this->userID));
     }
     return $success;
 }
示例#10
0
 private function loadThreadListFromDB($master = true)
 {
     wfProfileIn(__METHOD__);
     // get list of threads (article IDs) on Message Wall
     $dbr = wfGetDB($master ? DB_MASTER : DB_SLAVE);
     $query = '';
     // page_latest condition is for BugId:22821
     $query = "\n\t\t\tselect page.page_id, page.page_title from page\n\t\t\tleft join page_wikia_props\n\t\t\ton page.page_id = page_wikia_props.page_id\n\t\t\tand (page_wikia_props.propname = " . WPP_WALL_ADMINDELETE . "\n\t\t\t     or page_wikia_props.propname = " . WPP_WALL_REMOVE . "\n\t\t\t     or page_wikia_props.propname = " . WPP_WALL_ARCHIVE . ")\n\t\t\twhere page_wikia_props.page_id is null\n\t\t\tand page.page_title" . $dbr->buildLike(sprintf("%s/%s", $this->mTitle->getDBkey(), ARTICLECOMMENT_PREFIX), $dbr->anyString()) . " \n\t\t\tand page.page_title NOT " . $dbr->buildLike(sprintf("%s/%s%%/%s", $this->mTitle->getDBkey(), ARTICLECOMMENT_PREFIX, ARTICLECOMMENT_PREFIX), $dbr->anyString()) . "\n\t\t\tand page.page_title not like '%@%@%'\n\t\t\tand page.page_namespace = " . MWNamespace::getTalk($this->mTitle->getNamespace()) . "\n\t\t\tand page.page_latest > 0\n\t\t\torder by page.page_id desc";
     $res = $dbr->query($query);
     $this->mThreadMapping = array();
     $this->mThreadMappingRev = array();
     while ($row = $dbr->fetchObject($res)) {
         $this->mThreadMapping[$row->page_title] = $row->page_id;
         $this->mThreadMappingRev[$row->page_id] = $row->page_title;
     }
     wfProfileOut(__METHOD__);
 }
	/**
	 * Returns comment article title.
	 */
	public function getCommentArticleTitle() {
		if ( $this->mCommentTitle ) {
			return $this->mCommentTitle;
		} elseif ( $this->mCommentPage ) {
			return Title::newFromID( $this->mCommentPage, Title::GAID_FOR_UPDATE );
		} else {
			$it = $this->mItem->mTitle;
			return Title::makeTitle(
				MWNamespace::getTalk( $it->getNamespace() ),
				$it->getText() . '/c' . self::padID( $this->mID )
			);
		}
	}
 /**
  * Hook function calls when watch was removed from database
  * @param $oWatchItem WatchedItem: object
  * @param $success Boolean: removed successfully
  * @return bool (always true)
  */
 public static function removeGlobalWatch($oWatchItem, $success)
 {
     global $wgEnableScribeReport, $wgCityId;
     wfProfileIn(__METHOD__);
     if (empty($wgEnableScribeReport)) {
         wfProfileOut(__METHOD__);
         return true;
     }
     if (!$oWatchItem instanceof WatchedItem) {
         wfProfileOut(__METHOD__);
         return true;
     }
     if (!$success) {
         /* some errors when update in local watchlist table */
         wfProfileOut(__METHOD__);
         return true;
     }
     if ($oWatchItem->id == 0) {
         wfProfileOut(__METHOD__);
         return true;
     }
     foreach (array(MWNamespace::getSubject($oWatchItem->ns), MWNamespace::getTalk($oWatchItem->ns)) as $ns) {
         $params = array('wl_user' => $oWatchItem->id, 'wl_namespace' => $ns, 'wl_title' => $oWatchItem->ti, 'wl_wikia' => $wgCityId);
         try {
             $message = array('method' => 'removeWatch', 'params' => $params);
             $data = json_encode($message);
             WScribeClient::singleton('trigger')->send($data);
         } catch (Exception $e) {
             Wikia::log(__METHOD__, 'scribeClient exception', $e->getMessage());
         }
     }
     wfProfileOut(__METHOD__);
     return true;
 }
示例#13
0
	/**
	 * Constructor.
	 * @param $title Title object.
	 */
	function __construct( $title ) {
		$origns = $title->getNamespace();
		$this->mIsTalk = MWNamespace::isTalk( $origns );
		$ns = MWNamespace::getSubject( $origns );
		$tns = MWNamespace::getTalk( $origns );

		if ( strpos( $title->getText(), '/' ) !== false ) {
			# If title contains a '/', treat as a wikilog article title.
			list( $this->mWikilogName, $this->mItemName ) =
				explode( '/', $title->getText(), 2 );

			if ( strpos( $this->mItemName, '/' ) !== false ) {
				list( $this->mItemName, $this->mTrailing ) =
					explode( '/', $this->mItemName, 2 );
			}

			$rawtitle = "{$this->mWikilogName}/{$this->mItemName}";
			$this->mWikilogTitle = Title::makeTitle( $ns, $this->mWikilogName );
			$this->mItemTitle = Title::makeTitle( $ns, $rawtitle );
			$this->mItemTalkTitle = Title::makeTitle( $tns, $rawtitle );
		} else {
			# Title doesn't contain a '/', treat as a wikilog name.
			$this->mWikilogName = $title->getText();
			$this->mWikilogTitle = Title::makeTitle( $ns, $this->mWikilogName );
			$this->mItemName = null;
			$this->mItemTitle = null;
			$this->mItemTalkTitle = null;
		}
	}
 protected function getWatchlist($name, $titleDbkey, $ns = NS_USER_WALL)
 {
     //TODO: add some caching
     $userTitle = Title::newFromText($name, MWNamespace::getSubject($ns));
     $dbw = $this->getLocalDB(true);
     $res = $dbw->select(array('watchlist'), array('wl_user'), array('wl_title' => array($titleDbkey, $userTitle->getDBkey()), 'wl_namespace' => array(MWNamespace::getSubject($ns), MWNamespace::getTalk($ns)), "((wl_wikia_addedtimestamp > '2012-01-31' and wl_namespace = " . MWNamespace::getSubject($ns) . ") or ( wl_namespace = " . MWNamespace::getTalk($ns) . " ))"), __METHOD__);
     $users = array();
     while ($row = $dbw->fetchObject($res)) {
         $userId = intval($row->wl_user);
         $users[$userId] = $userId;
     }
     return $users;
 }
示例#15
0
 function upgradeWatchlist()
 {
     $chunksize = 100;
     list($watchlist, $watchlist_temp) = $this->dbw->tableNamesN('watchlist', 'watchlist_temp');
     $this->log('Migrating watchlist table to watchlist_temp...');
     $this->dbw->query("CREATE TABLE {$watchlist_temp} (\n  -- Key to user_id\n  wl_user int(5) unsigned NOT NULL,\n\n  -- Key to page_namespace/page_title\n  -- Note that users may watch patches which do not exist yet,\n  -- or existed in the past but have been deleted.\n  wl_namespace int NOT NULL default '0',\n  wl_title varchar(255) binary NOT NULL default '',\n\n  -- Timestamp when user was last sent a notification e-mail;\n  -- cleared when the user visits the page.\n  -- FIXME: add proper null support etc\n  wl_notificationtimestamp varchar(14) binary NOT NULL default '0',\n\n  UNIQUE KEY (wl_user, wl_namespace, wl_title),\n  KEY namespace_title (wl_namespace,wl_title)\n\n) TYPE=InnoDB;", __METHOD__);
     // Fix encoding for Latin-1 upgrades, add some fields,
     // and double article to article+talk pairs
     $numwatched = $this->dbw->selectField('watchlist', 'count(*)', '', __METHOD__);
     $this->setChunkScale($chunksize, $numwatched * 2, 'watchlist_temp', __METHOD__);
     $result = $this->dbr->select('watchlist', array('wl_user', 'wl_namespace', 'wl_title'), '', __METHOD__);
     $add = array();
     foreach ($result as $row) {
         $add[] = array('wl_user' => $row->wl_user, 'wl_namespace' => MWNamespace::getSubject($row->wl_namespace), 'wl_title' => $this->conv($row->wl_title), 'wl_notificationtimestamp' => '0');
         $this->addChunk($add);
         $add[] = array('wl_user' => $row->wl_user, 'wl_namespace' => MWNamespace::getTalk($row->wl_namespace), 'wl_title' => $this->conv($row->wl_title), 'wl_notificationtimestamp' => '0');
         $this->addChunk($add);
     }
     $this->lastChunk($add);
     $this->log('Done converting watchlist.');
     $this->cleanupSwaps[] = 'watchlist';
 }
示例#16
0
 /**
  * Exceptions with getTalk()
  * NS_SPECIAL does not have talk pages. MediaWiki raise an exception for them.
  * @expectedException MWException
  */
 public function testGetTalkExceptionsForNsSpecial()
 {
     $this->assertNull(MWNamespace::getTalk(NS_SPECIAL));
 }
示例#17
0
 private function loadReplyIdsFromDB($master = false)
 {
     // this is a direct way to get IDs
     // the other one is in Wall.class done in a grouped way
     // (fetch for many threads at once, set with ->setReplies)
     $title = Title::newFromId($this->mThreadId);
     if (empty($title)) {
         $title = Title::newFromId($this->mThreadId, Title::GAID_FOR_UPDATE);
     }
     if (empty($title)) {
         return;
     }
     $dbr = wfGetDB($master ? DB_MASTER : DB_SLAVE);
     $table = array('page');
     $vars = array('page_id');
     $conds[] = "page_title" . $dbr->buildLike(sprintf("%s/%s", $title->getDBkey(), ARTICLECOMMENT_PREFIX), $dbr->anyString());
     $conds[] = "page_latest > 0";
     // BugId:22821
     $conds['page_namespace'] = MWNamespace::getTalk($title->getNamespace());
     $options = array('ORDER BY' => 'page_id ASC');
     $res = $dbr->select($table, $vars, $conds, __METHOD__, $options);
     $list = array();
     while ($row = $dbr->fetchObject($res)) {
         array_push($list, $row->page_id);
     }
     $this->setReplies($list);
 }
示例#18
0
 /**
  * Same as addWatch, only the opposite.
  * @return bool
  */
 public function removeWatch()
 {
     wfProfileIn(__METHOD__);
     // Only loggedin user can have a watchlist
     if (wfReadOnly() || $this->mUser->isAnon() || !$this->isAllowed('editmywatchlist')) {
         wfProfileOut(__METHOD__);
         return false;
     }
     $success = false;
     $dbw = wfGetDB(DB_MASTER);
     $dbw->delete('watchlist', array('wl_user' => $this->getUserId(), 'wl_namespace' => MWNamespace::getSubject($this->getTitleNs()), 'wl_title' => $this->getTitleDBkey()), __METHOD__);
     if ($dbw->affectedRows()) {
         $success = true;
     }
     # the following code compensates the new behavior, introduced by the
     # enotif patch, that every single watched page needs now to be listed
     # in watchlist namespace:page and namespace_talk:page had separate
     # entries: clear them
     $dbw->delete('watchlist', array('wl_user' => $this->getUserId(), 'wl_namespace' => MWNamespace::getTalk($this->getTitleNs()), 'wl_title' => $this->getTitleDBkey()), __METHOD__);
     if ($dbw->affectedRows()) {
         $success = true;
     }
     $this->watched = false;
     wfProfileOut(__METHOD__);
     return $success;
 }
 private function getRemovedCommentPages($oTitle)
 {
     wfProfileIn(__METHOD__);
     $pages = array();
     if ($oTitle instanceof Title) {
         $dbr = wfGetDB(DB_SLAVE);
         $res = $dbr->select(array('archive'), array('ar_page_id', 'ar_title'), array('ar_namespace' => MWNamespace::getTalk($this->getTitle()->getNamespace()), "ar_title" . $dbr->buildLike(sprintf("%s/%s", $oTitle->getDBkey(), ARTICLECOMMENT_PREFIX), $dbr->anyString())), __METHOD__, array('ORDER BY' => 'ar_page_id ASC'));
         while ($row = $dbr->fetchObject($res)) {
             $pages[$row->ar_page_id] = array('title' => $row->ar_title, 'nspace' => MWNamespace::getTalk($this->getTitle()->getNamespace()));
         }
         $dbr->freeResult($res);
     }
     wfProfileOut(__METHOD__);
     return $pages;
 }
 /**
  * Remove a list of titles from a user's watchlist
  *
  * $titles can be an array of strings or Title objects; the former
  * is preferred, since Titles are very memory-heavy
  *
  * @param array $titles Array of strings, or Title objects
  */
 private function unwatchTitles($titles)
 {
     $dbw = wfGetDB(DB_MASTER);
     foreach ($titles as $title) {
         if (!$title instanceof Title) {
             $title = Title::newFromText($title);
         }
         if ($title instanceof Title) {
             $dbw->delete('watchlist', array('wl_user' => $this->getUser()->getId(), 'wl_namespace' => MWNamespace::getSubject($title->getNamespace()), 'wl_title' => $title->getDBkey()), __METHOD__);
             $dbw->delete('watchlist', array('wl_user' => $this->getUser()->getId(), 'wl_namespace' => MWNamespace::getTalk($title->getNamespace()), 'wl_title' => $title->getDBkey()), __METHOD__);
             $page = WikiPage::factory($title);
             Hooks::run('UnwatchArticleComplete', array($this->getUser(), &$page));
         }
     }
 }
示例#21
0
 /**
  * Add a list of targets to a user's watchlist
  *
  * @param string[]|LinkTarget[] $targets
  */
 private function watchTitles($targets)
 {
     $expandedTargets = [];
     foreach ($targets as $target) {
         if (!$target instanceof LinkTarget) {
             try {
                 $target = $this->titleParser->parseTitle($target, NS_MAIN);
             } catch (MalformedTitleException $e) {
                 continue;
             }
         }
         $ns = $target->getNamespace();
         $dbKey = $target->getDBkey();
         $expandedTargets[] = new TitleValue(MWNamespace::getSubject($ns), $dbKey);
         $expandedTargets[] = new TitleValue(MWNamespace::getTalk($ns), $dbKey);
     }
     MediaWikiServices::getInstance()->getWatchedItemStore()->addWatchBatchForUser($this->getUser(), $expandedTargets);
 }
示例#22
0
 /**
  * Get a Title object associated with the talk page of this article
  *
  * @return Title the object for the talk page
  */
 public function getTalkPage()
 {
     // begin wikia change
     // VOLDEV-66
     $talkPageTitle = Title::makeTitle(MWNamespace::getTalk($this->getNamespace()), $this->getDBkey());
     wfRunHooks('GetTalkPage', [$this, &$talkPageTitle]);
     return $talkPageTitle;
     // end wikia change
 }
示例#23
0
 public function execute()
 {
     global $wgUser;
     $params = $this->extractRequestParams();
     $fld_protection = $fld_talkid = $fld_subjectid = $fld_url = $fld_readable = false;
     if (!is_null($params['prop'])) {
         $prop = array_flip($params['prop']);
         $fld_protection = isset($prop['protection']);
         $fld_talkid = isset($prop['talkid']);
         $fld_subjectid = isset($prop['subjectid']);
         $fld_url = isset($prop['url']);
         $fld_readable = isset($prop['readable']);
     }
     $pageSet = $this->getPageSet();
     $titles = $pageSet->getGoodTitles();
     $missing = $pageSet->getMissingTitles();
     $result = $this->getResult();
     $pageRestrictions = $pageSet->getCustomField('page_restrictions');
     $pageIsRedir = $pageSet->getCustomField('page_is_redirect');
     $pageIsNew = $pageSet->getCustomField('page_is_new');
     $pageCounter = $pageSet->getCustomField('page_counter');
     $pageTouched = $pageSet->getCustomField('page_touched');
     $pageLatest = $pageSet->getCustomField('page_latest');
     $pageLength = $pageSet->getCustomField('page_len');
     $db = $this->getDB();
     if ($fld_protection && count($titles)) {
         $this->addTables('page_restrictions');
         $this->addFields(array('pr_page', 'pr_type', 'pr_level', 'pr_expiry', 'pr_cascade'));
         $this->addWhereFld('pr_page', array_keys($titles));
         $res = $this->select(__METHOD__);
         while ($row = $db->fetchObject($res)) {
             $a = array('type' => $row->pr_type, 'level' => $row->pr_level, 'expiry' => Block::decodeExpiry($row->pr_expiry, TS_ISO_8601));
             if ($row->pr_cascade) {
                 $a['cascade'] = '';
             }
             $protections[$row->pr_page][] = $a;
             # Also check old restrictions
             if ($pageRestrictions[$row->pr_page]) {
                 foreach (explode(':', trim($pageRestrictions[$pageid])) as $restrict) {
                     $temp = explode('=', trim($restrict));
                     if (count($temp) == 1) {
                         // old old format should be treated as edit/move restriction
                         $restriction = trim($temp[0]);
                         if ($restriction == '') {
                             continue;
                         }
                         $protections[$row->pr_page][] = array('type' => 'edit', 'level' => $restriction, 'expiry' => 'infinity');
                         $protections[$row->pr_page][] = array('type' => 'move', 'level' => $restriction, 'expiry' => 'infinity');
                     } else {
                         $restriction = trim($temp[1]);
                         if ($restriction == '') {
                             continue;
                         }
                         $protections[$row->pr_page][] = array('type' => $temp[0], 'level' => $restriction, 'expiry' => 'infinity');
                     }
                 }
             }
         }
         $db->freeResult($res);
         $imageIds = array();
         foreach ($titles as $id => $title) {
             if ($title->getNamespace() == NS_FILE) {
                 $imageIds[] = $id;
             }
         }
         // To avoid code duplication
         $cascadeTypes = array(array('prefix' => 'tl', 'table' => 'templatelinks', 'ns' => 'tl_namespace', 'title' => 'tl_title', 'ids' => array_diff(array_keys($titles), $imageIds)), array('prefix' => 'il', 'table' => 'imagelinks', 'ns' => NS_FILE, 'title' => 'il_to', 'ids' => $imageIds));
         foreach ($cascadeTypes as $type) {
             if (count($type['ids']) != 0) {
                 $this->resetQueryParams();
                 $this->addTables(array('page_restrictions', $type['table']));
                 $this->addTables('page', 'page_source');
                 $this->addTables('page', 'page_target');
                 $this->addFields(array('pr_type', 'pr_level', 'pr_expiry', 'page_target.page_id AS page_target_id', 'page_source.page_namespace AS page_source_namespace', 'page_source.page_title AS page_source_title'));
                 $this->addWhere(array("{$type['prefix']}_from = pr_page", 'page_target.page_namespace = ' . $type['ns'], 'page_target.page_title = ' . $type['title'], 'page_source.page_id = pr_page'));
                 $this->addWhereFld('pr_cascade', 1);
                 $this->addWhereFld('page_target.page_id', $type['ids']);
                 $res = $this->select(__METHOD__);
                 while ($row = $db->fetchObject($res)) {
                     $source = Title::makeTitle($row->page_source_namespace, $row->page_source_title);
                     $a = array('type' => $row->pr_type, 'level' => $row->pr_level, 'expiry' => Block::decodeExpiry($row->pr_expiry, TS_ISO_8601), 'source' => $source->getPrefixedText());
                     $protections[$row->page_target_id][] = $a;
                 }
                 $db->freeResult($res);
             }
         }
     }
     // We don't need to check for pt stuff if there are no nonexistent titles
     if ($fld_protection && count($missing)) {
         $this->resetQueryParams();
         // Construct a custom WHERE clause that matches all titles in $missing
         $lb = new LinkBatch($missing);
         $this->addTables('protected_titles');
         $this->addFields(array('pt_title', 'pt_namespace', 'pt_create_perm', 'pt_expiry'));
         $this->addWhere($lb->constructSet('pt', $db));
         $res = $this->select(__METHOD__);
         $prottitles = array();
         while ($row = $db->fetchObject($res)) {
             $prottitles[$row->pt_namespace][$row->pt_title][] = array('type' => 'create', 'level' => $row->pt_create_perm, 'expiry' => Block::decodeExpiry($row->pt_expiry, TS_ISO_8601));
         }
         $db->freeResult($res);
         $images = array();
         $others = array();
         foreach ($missing as $title) {
             if ($title->getNamespace() == NS_FILE) {
                 $images[] = $title->getDBKey();
             } else {
                 $others[] = $title;
             }
         }
         if (count($others) != 0) {
             $lb = new LinkBatch($others);
             $this->resetQueryParams();
             $this->addTables(array('page_restrictions', 'page', 'templatelinks'));
             $this->addFields(array('pr_type', 'pr_level', 'pr_expiry', 'page_title', 'page_namespace', 'tl_title', 'tl_namespace'));
             $this->addWhere($lb->constructSet('tl', $db));
             $this->addWhere('pr_page = page_id');
             $this->addWhere('pr_page = tl_from');
             $this->addWhereFld('pr_cascade', 1);
             $res = $this->select(__METHOD__);
             while ($row = $db->fetchObject($res)) {
                 $source = Title::makeTitle($row->page_namespace, $row->page_title);
                 $a = array('type' => $row->pr_type, 'level' => $row->pr_level, 'expiry' => Block::decodeExpiry($row->pr_expiry, TS_ISO_8601), 'source' => $source->getPrefixedText());
                 $prottitles[$row->tl_namespace][$row->tl_title][] = $a;
             }
             $db->freeResult($res);
         }
         if (count($images) != 0) {
             $this->resetQueryParams();
             $this->addTables(array('page_restrictions', 'page', 'imagelinks'));
             $this->addFields(array('pr_type', 'pr_level', 'pr_expiry', 'page_title', 'page_namespace', 'il_to'));
             $this->addWhere('pr_page = page_id');
             $this->addWhere('pr_page = il_from');
             $this->addWhereFld('pr_cascade', 1);
             $this->addWhereFld('il_to', $images);
             $res = $this->select(__METHOD__);
             while ($row = $db->fetchObject($res)) {
                 $source = Title::makeTitle($row->page_namespace, $row->page_title);
                 $a = array('type' => $row->pr_type, 'level' => $row->pr_level, 'expiry' => Block::decodeExpiry($row->pr_expiry, TS_ISO_8601), 'source' => $source->getPrefixedText());
                 $prottitles[NS_FILE][$row->il_to][] = $a;
             }
             $db->freeResult($res);
         }
     }
     // Run the talkid/subjectid query
     if ($fld_talkid || $fld_subjectid) {
         $talktitles = $subjecttitles = $talkids = $subjectids = array();
         $everything = array_merge($titles, $missing);
         foreach ($everything as $t) {
             if (MWNamespace::isTalk($t->getNamespace())) {
                 if ($fld_subjectid) {
                     $subjecttitles[] = $t->getSubjectPage();
                 }
             } else {
                 if ($fld_talkid) {
                     $talktitles[] = $t->getTalkPage();
                 }
             }
         }
         if (count($talktitles) || count($subjecttitles)) {
             // Construct a custom WHERE clause that matches
             // all titles in $talktitles and $subjecttitles
             $lb = new LinkBatch(array_merge($talktitles, $subjecttitles));
             $this->resetQueryParams();
             $this->addTables('page');
             $this->addFields(array('page_title', 'page_namespace', 'page_id'));
             $this->addWhere($lb->constructSet('page', $db));
             $res = $this->select(__METHOD__);
             while ($row = $db->fetchObject($res)) {
                 if (MWNamespace::isTalk($row->page_namespace)) {
                     $talkids[MWNamespace::getSubject($row->page_namespace)][$row->page_title] = $row->page_id;
                 } else {
                     $subjectids[MWNamespace::getTalk($row->page_namespace)][$row->page_title] = $row->page_id;
                 }
             }
         }
     }
     foreach ($titles as $pageid => $title) {
         $pageInfo = array('touched' => wfTimestamp(TS_ISO_8601, $pageTouched[$pageid]), 'lastrevid' => intval($pageLatest[$pageid]), 'counter' => intval($pageCounter[$pageid]), 'length' => intval($pageLength[$pageid]));
         if ($pageIsRedir[$pageid]) {
             $pageInfo['redirect'] = '';
         }
         if ($pageIsNew[$pageid]) {
             $pageInfo['new'] = '';
         }
         if (!is_null($params['token'])) {
             $tokenFunctions = $this->getTokenFunctions();
             $pageInfo['starttimestamp'] = wfTimestamp(TS_ISO_8601, time());
             foreach ($params['token'] as $t) {
                 $val = call_user_func($tokenFunctions[$t], $pageid, $title);
                 if ($val === false) {
                     $this->setWarning("Action '{$t}' is not allowed for the current user");
                 } else {
                     $pageInfo[$t . 'token'] = $val;
                 }
             }
         }
         if ($fld_protection) {
             $pageInfo['protection'] = array();
             if (isset($protections[$pageid])) {
                 $pageInfo['protection'] = $protections[$pageid];
                 $result->setIndexedTagName($pageInfo['protection'], 'pr');
             }
         }
         if ($fld_talkid && isset($talkids[$title->getNamespace()][$title->getDBKey()])) {
             $pageInfo['talkid'] = $talkids[$title->getNamespace()][$title->getDBKey()];
         }
         if ($fld_subjectid && isset($subjectids[$title->getNamespace()][$title->getDBKey()])) {
             $pageInfo['subjectid'] = $subjectids[$title->getNamespace()][$title->getDBKey()];
         }
         if ($fld_url) {
             $pageInfo['fullurl'] = $title->getFullURL();
             $pageInfo['editurl'] = $title->getFullURL('action=edit');
         }
         if ($fld_readable) {
             if ($title->userCanRead()) {
                 $pageInfo['readable'] = '';
             }
         }
         $result->addValue(array('query', 'pages'), $pageid, $pageInfo);
     }
     // Get properties for missing titles if requested
     if (!is_null($params['token']) || $fld_protection || $fld_talkid || $fld_subjectid || $fld_url || $fld_readable) {
         $res =& $result->getData();
         foreach ($missing as $pageid => $title) {
             if (!is_null($params['token'])) {
                 $tokenFunctions = $this->getTokenFunctions();
                 $res['query']['pages'][$pageid]['starttimestamp'] = wfTimestamp(TS_ISO_8601, time());
                 foreach ($params['token'] as $t) {
                     $val = call_user_func($tokenFunctions[$t], $pageid, $title);
                     if ($val === false) {
                         $this->setWarning("Action '{$t}' is not allowed for the current user");
                     } else {
                         $res['query']['pages'][$pageid][$t . 'token'] = $val;
                     }
                 }
             }
             if ($fld_protection) {
                 // Apparently the XML formatting code doesn't like array(null)
                 // This is painful to fix, so we'll just work around it
                 if (isset($prottitles[$title->getNamespace()][$title->getDBkey()])) {
                     $res['query']['pages'][$pageid]['protection'] = $prottitles[$title->getNamespace()][$title->getDBkey()];
                 } else {
                     $res['query']['pages'][$pageid]['protection'] = array();
                 }
                 $result->setIndexedTagName($res['query']['pages'][$pageid]['protection'], 'pr');
             }
             if ($fld_talkid && isset($talkids[$title->getNamespace()][$title->getDBKey()])) {
                 $res['query']['pages'][$pageid]['talkid'] = $talkids[$title->getNamespace()][$title->getDBKey()];
             }
             if ($fld_subjectid && isset($subjectids[$title->getNamespace()][$title->getDBKey()])) {
                 $res['query']['pages'][$pageid]['subjectid'] = $subjectids[$title->getNamespace()][$title->getDBKey()];
             }
             if ($fld_url) {
                 $res['query']['pages'][$pageid]['fullurl'] = $title->getFullURL();
                 $res['query']['pages'][$pageid]['editurl'] = $title->getFullURL('action=edit');
             }
             if ($fld_readable) {
                 if ($title->userCanRead()) {
                     $res['query']['pages'][$pageid]['readable'] = '';
                 }
             }
         }
     }
 }