示例#1
0
 public function execute()
 {
     $action = InfoAction::newFromContext($this->getContext());
     $action->doAction();
     $this->setAction($action);
     $this->content = $this->initContent();
 }
示例#2
0
 function showPage()
 {
     if ($this->minimal) {
         // Even more minimal -- we're in a machine API
         // and don't want to flood the output.
         $this->extraHeaders();
         $this->showContent();
     } else {
         parent::showPage();
     }
     // We don't want to have any more output after this
     exit;
 }
示例#3
0
	/**
	 * Purge caches on page update etc
	 *
	 * @param $title Title object
	 * @todo Verify that $title is always a Title object (and never false or null), add Title hint to parameter $title
	 */
	public static function onArticleEdit( $title ) {
		// Invalidate caches of articles which include this page
		DeferredUpdates::addHTMLCacheUpdate( $title, 'templatelinks' );

		// Invalidate the caches of all pages which redirect here
		DeferredUpdates::addHTMLCacheUpdate( $title, 'redirect' );

		// Purge squid for this page only
		$title->purgeSquid();

		// Clear file cache for this page only
		HTMLFileCache::clearFileCache( $title );
		InfoAction::invalidateCache( $title );
	}
示例#4
0
 /**
  * @param Title $title
  * @return bool
  */
 protected function runForTitle(Title $title)
 {
     // Wait for the DB of the current/next slave DB handle to catch up to the master.
     // This way, we get the correct page_latest for templates or files that just changed
     // milliseconds ago, having triggered this job to begin with.
     if (isset($this->params['masterPos']) && $this->params['masterPos'] !== false) {
         wfGetLB()->waitFor($this->params['masterPos']);
     }
     // Fetch the current page and revision...
     $page = WikiPage::factory($title);
     $revision = Revision::newFromTitle($title, false, Revision::READ_NORMAL);
     if (!$revision) {
         $this->setLastError("refreshLinks: Article not found {$title->getPrefixedDBkey()}");
         return false;
         // XXX: what if it was just deleted?
     }
     $content = $revision->getContent(Revision::RAW);
     if (!$content) {
         // If there is no content, pretend the content is empty
         $content = $revision->getContentHandler()->makeEmptyContent();
     }
     $parserOutput = false;
     $parserOptions = $page->makeParserOptions('canonical');
     // If page_touched changed after this root job, then it is likely that
     // any views of the pages already resulted in re-parses which are now in
     // cache. The cache can be reused to avoid expensive parsing in some cases.
     if (isset($this->params['rootJobTimestamp'])) {
         $opportunistic = !empty($this->params['isOpportunistic']);
         $skewedTimestamp = $this->params['rootJobTimestamp'];
         if ($opportunistic) {
             // Neither clock skew nor DB snapshot/slave lag matter much for such
             // updates; focus on reusing the (often recently updated) cache
         } else {
             // For transclusion updates, the template changes must be reflected
             $skewedTimestamp = wfTimestamp(TS_MW, wfTimestamp(TS_UNIX, $skewedTimestamp) + self::CLOCK_FUDGE);
         }
         if ($page->getLinksTimestamp() > $skewedTimestamp) {
             // Something already updated the backlinks since this job was made
             return true;
         }
         if ($page->getTouched() >= $skewedTimestamp || $opportunistic) {
             // Something bumped page_touched since this job was made
             // or the cache is otherwise suspected to be up-to-date
             $parserOutput = ParserCache::singleton()->getDirty($page, $parserOptions);
             if ($parserOutput && $parserOutput->getCacheTime() < $skewedTimestamp) {
                 $parserOutput = false;
                 // too stale
             }
         }
     }
     // Fetch the current revision and parse it if necessary...
     if ($parserOutput == false) {
         $start = microtime(true);
         // Revision ID must be passed to the parser output to get revision variables correct
         $parserOutput = $content->getParserOutput($title, $revision->getId(), $parserOptions, false);
         $elapsed = microtime(true) - $start;
         // If it took a long time to render, then save this back to the cache to avoid
         // wasted CPU by other apaches or job runners. We don't want to always save to
         // cache as this can cause high cache I/O and LRU churn when a template changes.
         if ($elapsed >= self::PARSE_THRESHOLD_SEC && $page->shouldCheckParserCache($parserOptions, $revision->getId()) && $parserOutput->isCacheable()) {
             $ctime = wfTimestamp(TS_MW, (int) $start);
             // cache time
             ParserCache::singleton()->save($parserOutput, $page, $parserOptions, $ctime, $revision->getId());
         }
     }
     $updates = $content->getSecondaryDataUpdates($title, null, !empty($this->params['useRecursiveLinksUpdate']), $parserOutput);
     foreach ($updates as $key => $update) {
         if ($update instanceof LinksUpdate) {
             if (!empty($this->params['triggeredRecursive'])) {
                 $update->setTriggeredRecursive();
             }
             if (!empty($this->params['triggeringUser'])) {
                 $userInfo = $this->params['triggeringUser'];
                 if ($userInfo['userId']) {
                     $user = User::newFromId($userInfo['userId']);
                 } else {
                     // Anonymous, use the username
                     $user = User::newFromName($userInfo['userName'], false);
                 }
                 $update->setTriggeringUser($user);
             }
             if (!empty($this->params['triggeringRevisionId'])) {
                 $revision = Revision::newFromId($this->params['triggeringRevisionId']);
                 if ($revision === null) {
                     $revision = Revision::newFromId($this->params['triggeringRevisionId'], Revision::READ_LATEST);
                 }
                 $update->setRevision($revision);
             }
         }
     }
     DataUpdate::runUpdates($updates);
     InfoAction::invalidateCache($title);
     return true;
 }
示例#5
0
 /**
  * Purge caches on page update etc
  *
  * @param Title $title
  * @param Revision|null $revision Revision that was just saved, may be null
  */
 public static function onArticleEdit(Title $title, Revision $revision = null)
 {
     // Invalidate caches of articles which include this page
     DeferredUpdates::addUpdate(new HTMLCacheUpdate($title, 'templatelinks'));
     // Invalidate the caches of all pages which redirect here
     DeferredUpdates::addUpdate(new HTMLCacheUpdate($title, 'redirect'));
     MediaWikiServices::getInstance()->getLinkCache()->invalidateTitle($title);
     // Purge CDN for this page only
     $title->purgeSquid();
     // Clear file cache for this page only
     HTMLFileCache::clearFileCache($title);
     $revid = $revision ? $revision->getId() : null;
     DeferredUpdates::addCallableUpdate(function () use($title, $revid) {
         InfoAction::invalidateCache($title, $revid);
     });
 }
示例#6
0
 /**
  * @param $title Title
  * @param $revision Revision
  * @param $fname string
  * @return void
  */
 public static function runForTitleInternal(Title $title, Revision $revision, $fname)
 {
     wfProfileIn($fname);
     $content = $revision->getContent(Revision::RAW);
     if (!$content) {
         // if there is no content, pretend the content is empty
         $content = $revision->getContentHandler()->makeEmptyContent();
     }
     // Revision ID must be passed to the parser output to get revision variables correct
     $parserOutput = $content->getParserOutput($title, $revision->getId(), null, false);
     $updates = $content->getSecondaryDataUpdates($title, null, false, $parserOutput);
     DataUpdate::runUpdates($updates);
     InfoAction::invalidateCache($title);
     wfProfileOut($fname);
 }
示例#7
0
    /**
     * Be careful to never throw exceptions from here if we're already
     * on the Error500Page. e.g. if content of FooPage is empty, this throws
     * an exception but then index.php instantiates a new page (Error500Page),
     * which does have content. So any exception thrown from here (either directly
     * or indirectly from an Action class), should either be caught or made sure
     * that it doesn't occurr for a Error500Page).
     */
    public function output()
    {
        $this->execute();
        if (!$this->getContent()) {
            throw new SwarmException("Page `content` must not be empty.");
        }
        if (!$this->getTitle()) {
            throw new SwarmException("Page `title` must not be empty.");
        }
        if (headers_sent($filename, $linenum)) {
            throw new SwarmException("Headers already sent in `{$filename}` on line {$linenum}.");
        }
        header("Content-Type: text/html; charset=utf-8");
        $request = $this->getContext()->getRequest();
        // ProjectsAction could throw an exception, which needs to be caught here,
        // since Error500Page (exception handler) also uses Page::output() eventually.
        // @todo: Find a cleaner way to deal with exceptions in the final page out,
        // because page output is also used on the Error500Page.
        $projects = array();
        if (!isset($this->exceptionObj)) {
            try {
                $projectsActionContext = $this->getContext()->createDerivedRequestContext(array("action" => "projects", "sort" => "name", "sort_oder" => "asc"));
                $projectsAction = ProjectsAction::newFromContext($projectsActionContext);
                $projectsAction->doAction();
                $projects = $projectsAction->getData();
            } catch (Exception $e) {
                $pageObj = Error500Page::newFromContext($this->getContext());
                $pageObj->setExceptionObj($e);
                $pageObj->output();
                exit;
            }
        }
        ?>
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<?php 
        foreach ($this->metaTags as $metaTag) {
            echo "\t" . html_tag("meta", $metaTag) . "\n";
        }
        $subTitleSuffix = $this->getSubTitle() ? ": {$this->getSubTitle()}" : "";
        $htmlTitle = $this->getTitle() . $subTitleSuffix . " - " . $this->getContext()->getConf()->web->title;
        $displayTitleHtml = $this->getDisplayTitleHtml();
        ?>
	<title><?php 
        echo htmlentities($htmlTitle);
        ?>
</title>
	<link rel="stylesheet" href="<?php 
        echo swarmpath("css/bootstrap.min.css");
        ?>
">
	<link rel="stylesheet" href="<?php 
        echo swarmpath("css/testswarm.css");
        ?>
">
	<script src="<?php 
        echo swarmpath("js/jquery.js");
        ?>
"></script>
	<script src="<?php 
        echo swarmpath("js/bootstrap-dropdown.js");
        ?>
"></script>
	<script>window.SWARM = <?php 
        $infoAction = InfoAction::newFromContext($this->getContext());
        $infoAction->doAction();
        echo json_encode($infoAction->getData());
        ?>
;</script><?php 
        foreach ($this->styleSheets as $styleSheet) {
            echo "\n\t" . html_tag("link", array("rel" => "stylesheet", "href" => $styleSheet));
        }
        foreach ($this->headScripts as $headScript) {
            echo "\n\t" . html_tag("script", array("src" => $headScript));
        }
        ?>
</head>
<body>
	<div class="navbar navbar-fixed-top">
		<div class="navbar-inner">
			<div class="container">
				<a class="brand" href="<?php 
        echo swarmpath("");
        ?>
"><?php 
        echo htmlspecialchars($this->getContext()->getConf()->web->title);
        ?>
</a>
				<div class="nav-collapse">
					<ul class="nav">
						<li><a href="<?php 
        echo swarmpath("");
        ?>
">Home</a></li>
						<li class="dropdown" id="swarm-projectsmenu">
							<a href="<?php 
        echo swarmpath("projects");
        ?>
" class="dropdown-toggle" data-toggle="dropdown" data-target="#swarm-projectsmenu">
								Projects
								<b class="caret"></b>
							</a>
							<ul class="dropdown-menu">
								<li><a href="<?php 
        echo swarmpath("projects");
        ?>
">All projects</a></li>
								<li class="divider"></li>
								<li class="nav-header">Projects</li>
<?php 
        foreach ($projects as $project) {
            ?>
								<li><a href="<?php 
            echo htmlspecialchars(swarmpath("user/{$project["name"]}"));
            ?>
"><?php 
            echo htmlspecialchars($project["name"]);
            ?>
</a></li>
<?php 
        }
        ?>
							</ul>
						</li>
						<li><a href="<?php 
        echo swarmpath("scores");
        ?>
">Scores</a></li>
						<li><a href="<?php 
        echo swarmpath("about");
        ?>
">About</a></li>
					</ul>
					<ul class="nav pull-right">
<?php 
        if ($request->getSessionData("username") && $request->getSessionData("auth") == "yes") {
            $username = htmlspecialchars($request->getSessionData("username"));
            ?>
						<li><a href="<?php 
            echo swarmpath("user/{$username}");
            ?>
">Hello, <?php 
            echo $username;
            ?>
!</a></li>
						<li><a href="<?php 
            echo swarmpath("run/{$username}");
            ?>
">Join the Swarm</a></li>
						<li><a href="<?php 
            echo swarmpath("logout");
            ?>
">Logout</a></li>
<?php 
        } else {
            ?>
						<li><a href="<?php 
            echo swarmpath("login");
            ?>
">Login</a></li>
						<li><a href="<?php 
            echo swarmpath("signup");
            ?>
">Signup</a></li>
<?php 
        }
        ?>
					</ul>
				</div><!--/.nav-collapse -->
			</div>
		</div>
	</div>

	<div class="container">
		<div class="hero-unit">
			<h1><?php 
        echo $displayTitleHtml;
        ?>
</h1>
		</div>
<?php 
        echo $this->getContent();
        ?>

		<hr>
		<footer class="swarm-page-footer">
			<p>Powered by <a href="//github.com/jquery/testswarm">TestSwarm</a>:
			<a href="//github.com/jquery/testswarm">Source Code</a>
			| <a href="//github.com/jquery/testswarm/issues">Issue Tracker</a>
			| <a href="//github.com/jquery/testswarm/wiki">About</a>
			| <a href="//twitter.com/testswarm">Twitter</a>
			</p>
		</footer>
	</div>
	<script src="<?php 
        echo swarmpath("js/pretty.js");
        ?>
"></script>
	<script src="<?php 
        echo swarmpath("js/testswarm.js");
        ?>
"></script><?php 
        foreach ($this->bodyScripts as $bodyScript) {
            echo "\n\t" . html_tag("script", array("src" => $bodyScript));
        }
        if ($this->getContext()->getConf()->debug->dbLogQueries) {
            $queryLog = $this->getContext()->getDB()->getQueryLog();
            $queryLogHtml = '<hr><h3>Database query log</h3><div class="well"><ul class="unstyled">';
            foreach ($queryLog as $i => $queryInfo) {
                if ($i !== 0) {
                    $queryLogHtml .= '<hr>';
                }
                $queryLogHtml .= '<li>' . '<pre>' . htmlspecialchars($queryInfo["sql"]) . '</pre>' . '<table class="table table-bordered table-condensed"><tbody><tr>' . '<td>Caller: <code>' . htmlspecialchars($queryInfo["caller"]) . '</code></td>' . '<td>Num rows: <code>' . htmlspecialchars($queryInfo["numRows"]) . '</code></td>' . '<td>Insert ID: <code>' . htmlspecialchars($queryInfo["insertId"]) . '</code></td>' . '<td>Affected rows: <code>' . htmlspecialchars($queryInfo["affectedRows"]) . '</code></td>' . '<td>Query time: <code>' . htmlspecialchars(substr($queryInfo["queryTime"], 0, 8)) . '</code></td>' . '</tr></table>' . '</li>';
            }
            $queryLogHtml .= '</ul>';
            echo $queryLogHtml;
        }
        ?>
</body>
</html>
<?php 
        // End of Page::output
    }
 /**
  * @param Title $title
  * @return bool
  */
 protected function runForTitle(Title $title = null)
 {
     $linkCache = LinkCache::singleton();
     $linkCache->clear();
     if (is_null($title)) {
         $this->setLastError("refreshLinks: Invalid title");
         return false;
     }
     // Wait for the DB of the current/next slave DB handle to catch up to the master.
     // This way, we get the correct page_latest for templates or files that just changed
     // milliseconds ago, having triggered this job to begin with.
     if (isset($this->params['masterPos']) && $this->params['masterPos'] !== false) {
         wfGetLB()->waitFor($this->params['masterPos']);
     }
     $page = WikiPage::factory($title);
     // Fetch the current revision...
     $revision = Revision::newFromTitle($title, false, Revision::READ_NORMAL);
     if (!$revision) {
         $this->setLastError("refreshLinks: Article not found {$title->getPrefixedDBkey()}");
         return false;
         // XXX: what if it was just deleted?
     }
     $content = $revision->getContent(Revision::RAW);
     if (!$content) {
         // If there is no content, pretend the content is empty
         $content = $revision->getContentHandler()->makeEmptyContent();
     }
     $parserOutput = false;
     $parserOptions = $page->makeParserOptions('canonical');
     // If page_touched changed after this root job (with a good slave lag skew factor),
     // then it is likely that any views of the pages already resulted in re-parses which
     // are now in cache. This can be reused to avoid expensive parsing in some cases.
     if (isset($this->params['rootJobTimestamp'])) {
         $skewedTimestamp = wfTimestamp(TS_UNIX, $this->params['rootJobTimestamp']) + 5;
         if ($page->getLinksTimestamp() > wfTimestamp(TS_MW, $skewedTimestamp)) {
             // Something already updated the backlinks since this job was made
             return true;
         }
         if ($page->getTouched() > wfTimestamp(TS_MW, $skewedTimestamp)) {
             $parserOutput = ParserCache::singleton()->getDirty($page, $parserOptions);
             if ($parserOutput && $parserOutput->getCacheTime() <= $skewedTimestamp) {
                 $parserOutput = false;
                 // too stale
             }
         }
     }
     // Fetch the current revision and parse it if necessary...
     if ($parserOutput == false) {
         $start = microtime(true);
         // Revision ID must be passed to the parser output to get revision variables correct
         $parserOutput = $content->getParserOutput($title, $revision->getId(), $parserOptions, false);
         $ellapsed = microtime(true) - $start;
         // If it took a long time to render, then save this back to the cache to avoid
         // wasted CPU by other apaches or job runners. We don't want to always save to
         // cache as this can cause high cache I/O and LRU churn when a template changes.
         if ($ellapsed >= self::PARSE_THRESHOLD_SEC && $page->isParserCacheUsed($parserOptions, $revision->getId()) && $parserOutput->isCacheable()) {
             $ctime = wfTimestamp(TS_MW, (int) $start);
             // cache time
             ParserCache::singleton()->save($parserOutput, $page, $parserOptions, $ctime, $revision->getId());
         }
     }
     $updates = $content->getSecondaryDataUpdates($title, null, false, $parserOutput);
     DataUpdate::runUpdates($updates);
     InfoAction::invalidateCache($title);
     return true;
 }
示例#9
0
 function showFooter()
 {
     if ($this->desktopMode == false) {
         parent::showFooter();
     }
 }
示例#10
0
    /**
     * Be careful to never throw exceptions from here if we're already
     * on the Error500Page. e.g. if content of FooPage is empty, this throws
     * an exception but then index.php instantiates a new page (Error500Page),
     * which does have content. So any exception thrown from here (either directly
     * or indirectly from an Action class), should either be caught or made sure
     * that it doesn't occurr for a Error500Page).
     */
    public function output()
    {
        $this->execute();
        if (!$this->getContent()) {
            throw new SwarmException('Page `content` must not be empty.');
        }
        if (!$this->getTitle()) {
            throw new SwarmException('Page `title` must not be empty.');
        }
        if (headers_sent($filename, $linenum)) {
            throw new SwarmException("Headers already sent in `{$filename}` on line {$linenum}.");
        }
        header('Content-Type: text/html; charset=UTF-8');
        $frameOptions = $this->getFrameOptions();
        if ($frameOptions) {
            header('X-Frame-Options: ' . $frameOptions, true);
        }
        $context = $this->getContext();
        $request = $context->getRequest();
        $auth = $context->getAuth();
        // ProjectsAction could throw an exception, which needs to be caught here,
        // since Error500Page (exception handler) also uses Page::output() eventually.
        // @todo: Find a cleaner way to deal with exceptions in the final page out,
        // because page output is also used on the Error500Page.
        $projects = array();
        if (!isset($this->exceptionObj)) {
            try {
                $projectsAction = ProjectsAction::newFromContext($context);
                $projectsAction->doAction();
                $projects = $projectsAction->getData();
            } catch (Exception $e) {
                $pageObj = Error500Page::newFromContext($context);
                $pageObj->setExceptionObj($e);
                $pageObj->output();
                exit;
            }
        }
        ?>
<!DOCTYPE html>
<html lang="en" dir="ltr" class="no-js">
<head>
<?php 
        foreach ($this->metaTags as $metaTag) {
            echo "\t" . html_tag('meta', $metaTag) . "\n";
        }
        $subTitleSuffix = $this->getSubTitle() ? ": {$this->getSubTitle()}" : "";
        $htmlTitle = $this->getTitle() . $subTitleSuffix . ' - ' . $context->getConf()->web->title;
        $displayTitleHtml = $this->getDisplayTitleHtml();
        ?>
	<title><?php 
        echo htmlentities($htmlTitle);
        ?>
</title>
	<link rel="stylesheet" href="<?php 
        echo swarmpath('external/bootstrap/css/bootstrap.css');
        ?>
">
	<link rel="stylesheet" href="<?php 
        echo swarmpath('external/bootstrap/css/bootstrap-responsive.css');
        ?>
">
	<link rel="stylesheet" href="<?php 
        echo swarmpath('css/testswarm.css');
        ?>
">
	<script>
	(function (h) { h.className = h.className.replace(/\bno-js\b/,'js')})(document.documentElement);
	SWARM = <?php 
        $infoAction = InfoAction::newFromContext($context);
        $infoAction->doAction();
        echo json_encode2($infoAction->getData());
        ?>
;
	SWARM.auth = <?php 
        echo json_encode2($auth);
        ?>
;
	</script>
<?php 
        foreach ($this->styleSheets as $styleSheet) {
            echo "\t" . html_tag('link', array('rel' => 'stylesheet', 'href' => $styleSheet)) . "\n";
        }
        foreach ($this->headScripts as $headScript) {
            echo "\t" . html_tag('script', array('src' => $headScript)) . "\n";
        }
        ?>
</head>
<body>
	<div class="navbar navbar-fixed-top">
		<div class="navbar-inner">
			<div class="container">
				<a class="brand" href="<?php 
        echo swarmpath('');
        ?>
"><?php 
        echo htmlspecialchars($context->getConf()->web->title);
        ?>
</a>
				<ul class="nav">
					<?php 
        echo $this->getPageLink('home', 'Home');
        ?>
					<li class="dropdown<?php 
        if (strpos($this->getSelfPath(), 'projects') === 0) {
            echo ' active';
        }
        ?>
">
						<a href="<?php 
        echo swarmpath('projects');
        ?>
" class="dropdown-toggle" data-toggle="dropdown">
							Projects
							<b class="caret"></b>
						</a>
						<ul class="dropdown-menu">
							<?php 
        echo $this->getPageLink('projects', 'All projects');
        ?>
							<li class="divider"></li>
							<li class="nav-header">Projects</li>
<?php 
        foreach ($projects as $project) {
            echo $this->getPageLink("project/{$project['id']}", $project['displayTitle']);
        }
        ?>
						</ul>
					</li>
					<?php 
        echo $this->getPageLink('clients', 'Clients');
        ?>
					<?php 
        echo $this->getPageLink('info', 'Info');
        ?>
				</ul>
				<ul class="nav pull-right">
<?php 
        if ($auth) {
            ?>
					<li><a href="<?php 
            echo htmlspecialchars(swarmpath("project/{$auth->project->id}"));
            ?>
"><?php 
            echo htmlspecialchars($auth->project->display_title);
            ?>
</a></li>
					<li><a href="<?php 
            echo swarmpath("addjob");
            ?>
">Add job</a></li>
					<li><a href="<?php 
            echo swarmpath('logout');
            ?>
" class="swarm-logout-link">Logout</a></li>
<?php 
        } else {
            echo $this->getPageLink('login', 'Login');
        }
        ?>
				</ul>
			</div>
		</div>
	</div>

	<div class="container">
		<div class="hero-unit">
			<h1><?php 
        echo $displayTitleHtml;
        ?>
</h1>
		</div>
<?php 
        echo $this->getContent();
        ?>

		<hr>
		<footer class="swarm-page-footer">
			<p>Powered by <a href="https://github.com/jquery/testswarm">TestSwarm</a>:
			<a href="https://github.com/jquery/testswarm">Source Code</a>
			| <a href="https://github.com/jquery/testswarm/issues">Issue Tracker</a>
			| <a href="https://github.com/jquery/testswarm/wiki">About</a>
			| <a href="https://twitter.com/testswarm">Twitter</a>
			</p>
		</footer>
	</div>
	<script src="<?php 
        echo swarmpath('external/jquery/jquery.js');
        ?>
"></script>
	<script src="<?php 
        echo swarmpath('external/bootstrap/js/bootstrap-dropdown.js');
        ?>
"></script>
	<script src="<?php 
        echo swarmpath('js/pretty.js');
        ?>
"></script>
	<script src="<?php 
        echo swarmpath('js/testswarm.js');
        ?>
"></script><?php 
        foreach ($this->bodyScripts as $bodyScript) {
            echo "\n\t" . html_tag('script', array('src' => $bodyScript));
        }
        if ($context->getConf()->debug->dbLogQueries) {
            $queryLog = $context->getDB()->getQueryLog();
            $queryLogHtml = '<hr><h3>Database query log</h3><div class="well"><ul class="unstyled">';
            foreach ($queryLog as $i => $queryInfo) {
                if ($i !== 0) {
                    $queryLogHtml .= '<hr>';
                }
                $queryLogHtml .= '<li>' . '<pre>' . htmlspecialchars($queryInfo["sql"]) . '</pre>' . '<table class="table table-bordered table-condensed"><tbody><tr>' . '<td>Caller: <code>' . htmlspecialchars($queryInfo['caller']) . '</code></td>' . '<td>Num rows: <code>' . htmlspecialchars($queryInfo['numRows']) . '</code></td>' . '<td>Insert ID: <code>' . htmlspecialchars($queryInfo['insertId']) . '</code></td>' . '<td>Affected rows: <code>' . htmlspecialchars($queryInfo['affectedRows']) . '</code></td>' . '<td>Query time: <code>' . htmlspecialchars(substr($queryInfo['queryTime'], 0, 8)) . '</code></td>' . '</tr></table>' . '</li>';
            }
            $queryLogHtml .= '</ul>';
            echo $queryLogHtml;
        }
        ?>
</body>
</html>
<?php 
        // End of Page::output
    }
 function showAuthorized()
 {
     $title = null;
     $msg = null;
     if ($this->app->name == 'anonymous') {
         $title = _('You have successfully authorized the application');
         $msg = _('Please return to the application and enter the following security code to complete the process.');
     } else {
         $title = sprintf(_('You have successfully authorized %s'), $this->app->name);
         $msg = sprintf(_('Please return to %s and enter the following security code to complete the process.'), $this->app->name);
     }
     if ($this->reqToken->verified_callback == 'oob') {
         $pin = new ApiOauthPinAction($title, $msg, $this->reqToken->verifier, $this->desktopMode());
         $pin->showPage();
     } else {
         // NOTE: This would only happen if an application registered as
         // a web application but sent in 'oob' for the oauth_callback
         // parameter. Usually web apps will send in a callback and
         // not use the pin-based workflow.
         $info = new InfoAction($title, $msg, $this->oauthTokenParam, $this->reqToken->verifier);
         $info->showPage();
     }
 }
示例#12
0
 /**
  * @param Title $title
  * @return bool
  */
 protected function runForTitle(Title $title)
 {
     $page = WikiPage::factory($title);
     if (!empty($this->params['triggeringRevisionId'])) {
         // Fetch the specified revision; lockAndGetLatest() below detects if the page
         // was edited since and aborts in order to avoid corrupting the link tables
         $revision = Revision::newFromId($this->params['triggeringRevisionId'], Revision::READ_LATEST);
     } else {
         // Fetch current revision; READ_LATEST reduces lockAndGetLatest() check failures
         $revision = Revision::newFromTitle($title, false, Revision::READ_LATEST);
     }
     if (!$revision) {
         $this->setLastError("Revision not found for {$title->getPrefixedDBkey()}");
         return false;
         // just deleted?
     }
     $content = $revision->getContent(Revision::RAW);
     if (!$content) {
         // If there is no content, pretend the content is empty
         $content = $revision->getContentHandler()->makeEmptyContent();
     }
     $parserOutput = false;
     $parserOptions = $page->makeParserOptions('canonical');
     // If page_touched changed after this root job, then it is likely that
     // any views of the pages already resulted in re-parses which are now in
     // cache. The cache can be reused to avoid expensive parsing in some cases.
     if (isset($this->params['rootJobTimestamp'])) {
         $opportunistic = !empty($this->params['isOpportunistic']);
         $skewedTimestamp = $this->params['rootJobTimestamp'];
         if ($opportunistic) {
             // Neither clock skew nor DB snapshot/slave lag matter much for such
             // updates; focus on reusing the (often recently updated) cache
         } else {
             // For transclusion updates, the template changes must be reflected
             $skewedTimestamp = wfTimestamp(TS_MW, wfTimestamp(TS_UNIX, $skewedTimestamp) + self::CLOCK_FUDGE);
         }
         if ($page->getLinksTimestamp() > $skewedTimestamp) {
             // Something already updated the backlinks since this job was made
             return true;
         }
         if ($page->getTouched() >= $skewedTimestamp || $opportunistic) {
             // Something bumped page_touched since this job was made
             // or the cache is otherwise suspected to be up-to-date
             $parserOutput = ParserCache::singleton()->getDirty($page, $parserOptions);
             if ($parserOutput && $parserOutput->getCacheTime() < $skewedTimestamp) {
                 $parserOutput = false;
                 // too stale
             }
         }
     }
     // Fetch the current revision and parse it if necessary...
     if ($parserOutput == false) {
         $start = microtime(true);
         // Revision ID must be passed to the parser output to get revision variables correct
         $parserOutput = $content->getParserOutput($title, $revision->getId(), $parserOptions, false);
         $elapsed = microtime(true) - $start;
         // If it took a long time to render, then save this back to the cache to avoid
         // wasted CPU by other apaches or job runners. We don't want to always save to
         // cache as this can cause high cache I/O and LRU churn when a template changes.
         if ($elapsed >= self::PARSE_THRESHOLD_SEC && $page->shouldCheckParserCache($parserOptions, $revision->getId()) && $parserOutput->isCacheable()) {
             $ctime = wfTimestamp(TS_MW, (int) $start);
             // cache time
             ParserCache::singleton()->save($parserOutput, $page, $parserOptions, $ctime, $revision->getId());
         }
     }
     $updates = $content->getSecondaryDataUpdates($title, null, !empty($this->params['useRecursiveLinksUpdate']), $parserOutput);
     foreach ($updates as $key => $update) {
         // FIXME: This code probably shouldn't be here?
         // Needed by things like Echo notifications which need
         // to know which user caused the links update
         if ($update instanceof LinksUpdate) {
             if (!empty($this->params['triggeringUser'])) {
                 $userInfo = $this->params['triggeringUser'];
                 if ($userInfo['userId']) {
                     $user = User::newFromId($userInfo['userId']);
                 } else {
                     // Anonymous, use the username
                     $user = User::newFromName($userInfo['userName'], false);
                 }
                 $update->setTriggeringUser($user);
             }
         }
     }
     $latestNow = $page->lockAndGetLatest();
     if (!$latestNow || $revision->getId() != $latestNow) {
         // Do not clobber over newer updates with older ones. If all jobs where FIFO and
         // serialized, it would be OK to update links based on older revisions since it
         // would eventually get to the latest. Since that is not the case (by design),
         // only update the link tables to a state matching the current revision's output.
         $this->setLastError("page_latest changed from {$revision->getId()} to {$latestNow}");
         return false;
     }
     DataUpdate::runUpdates($updates);
     InfoAction::invalidateCache($title);
     return true;
 }
示例#13
0
 /**
  * @param Title $title
  * @return bool
  */
 protected function runForTitle(Title $title)
 {
     $services = MediaWikiServices::getInstance();
     $stats = $services->getStatsdDataFactory();
     $lbFactory = $services->getDBLoadBalancerFactory();
     $ticket = $lbFactory->getEmptyTransactionTicket(__METHOD__);
     $page = WikiPage::factory($title);
     $page->loadPageData(WikiPage::READ_LATEST);
     // Serialize links updates by page ID so they see each others' changes
     $dbw = $lbFactory->getMainLB()->getConnection(DB_MASTER);
     /** @noinspection PhpUnusedLocalVariableInspection */
     $scopedLock = LinksUpdate::acquirePageLock($dbw, $page->getId(), 'job');
     // Get the latest ID *after* acquirePageLock() flushed the transaction.
     // This is used to detect edits/moves after loadPageData() but before the scope lock.
     // The works around the chicken/egg problem of determining the scope lock key.
     $latest = $title->getLatestRevID(Title::GAID_FOR_UPDATE);
     if (!empty($this->params['triggeringRevisionId'])) {
         // Fetch the specified revision; lockAndGetLatest() below detects if the page
         // was edited since and aborts in order to avoid corrupting the link tables
         $revision = Revision::newFromId($this->params['triggeringRevisionId'], Revision::READ_LATEST);
     } else {
         // Fetch current revision; READ_LATEST reduces lockAndGetLatest() check failures
         $revision = Revision::newFromTitle($title, false, Revision::READ_LATEST);
     }
     if (!$revision) {
         $stats->increment('refreshlinks.rev_not_found');
         $this->setLastError("Revision not found for {$title->getPrefixedDBkey()}");
         return false;
         // just deleted?
     } elseif ($revision->getId() != $latest || $revision->getPage() !== $page->getId()) {
         // Do not clobber over newer updates with older ones. If all jobs where FIFO and
         // serialized, it would be OK to update links based on older revisions since it
         // would eventually get to the latest. Since that is not the case (by design),
         // only update the link tables to a state matching the current revision's output.
         $stats->increment('refreshlinks.rev_not_current');
         $this->setLastError("Revision {$revision->getId()} is not current");
         return false;
     }
     $content = $revision->getContent(Revision::RAW);
     if (!$content) {
         // If there is no content, pretend the content is empty
         $content = $revision->getContentHandler()->makeEmptyContent();
     }
     $parserOutput = false;
     $parserOptions = $page->makeParserOptions('canonical');
     // If page_touched changed after this root job, then it is likely that
     // any views of the pages already resulted in re-parses which are now in
     // cache. The cache can be reused to avoid expensive parsing in some cases.
     if (isset($this->params['rootJobTimestamp'])) {
         $opportunistic = !empty($this->params['isOpportunistic']);
         $skewedTimestamp = $this->params['rootJobTimestamp'];
         if ($opportunistic) {
             // Neither clock skew nor DB snapshot/replica DB lag matter much for such
             // updates; focus on reusing the (often recently updated) cache
         } else {
             // For transclusion updates, the template changes must be reflected
             $skewedTimestamp = wfTimestamp(TS_MW, wfTimestamp(TS_UNIX, $skewedTimestamp) + self::CLOCK_FUDGE);
         }
         if ($page->getLinksTimestamp() > $skewedTimestamp) {
             // Something already updated the backlinks since this job was made
             $stats->increment('refreshlinks.update_skipped');
             return true;
         }
         if ($page->getTouched() >= $this->params['rootJobTimestamp'] || $opportunistic) {
             // Cache is suspected to be up-to-date. As long as the cache rev ID matches
             // and it reflects the job's triggering change, then it is usable.
             $parserOutput = ParserCache::singleton()->getDirty($page, $parserOptions);
             if (!$parserOutput || $parserOutput->getCacheRevisionId() != $revision->getId() || $parserOutput->getCacheTime() < $skewedTimestamp) {
                 $parserOutput = false;
                 // too stale
             }
         }
     }
     // Fetch the current revision and parse it if necessary...
     if ($parserOutput) {
         $stats->increment('refreshlinks.parser_cached');
     } else {
         $start = microtime(true);
         // Revision ID must be passed to the parser output to get revision variables correct
         $parserOutput = $content->getParserOutput($title, $revision->getId(), $parserOptions, false);
         $elapsed = microtime(true) - $start;
         // If it took a long time to render, then save this back to the cache to avoid
         // wasted CPU by other apaches or job runners. We don't want to always save to
         // cache as this can cause high cache I/O and LRU churn when a template changes.
         if ($elapsed >= self::PARSE_THRESHOLD_SEC && $page->shouldCheckParserCache($parserOptions, $revision->getId()) && $parserOutput->isCacheable()) {
             $ctime = wfTimestamp(TS_MW, (int) $start);
             // cache time
             ParserCache::singleton()->save($parserOutput, $page, $parserOptions, $ctime, $revision->getId());
         }
         $stats->increment('refreshlinks.parser_uncached');
     }
     $updates = $content->getSecondaryDataUpdates($title, null, !empty($this->params['useRecursiveLinksUpdate']), $parserOutput);
     foreach ($updates as $key => $update) {
         // FIXME: This code probably shouldn't be here?
         // Needed by things like Echo notifications which need
         // to know which user caused the links update
         if ($update instanceof LinksUpdate) {
             $update->setRevision($revision);
             if (!empty($this->params['triggeringUser'])) {
                 $userInfo = $this->params['triggeringUser'];
                 if ($userInfo['userId']) {
                     $user = User::newFromId($userInfo['userId']);
                 } else {
                     // Anonymous, use the username
                     $user = User::newFromName($userInfo['userName'], false);
                 }
                 $update->setTriggeringUser($user);
             }
         }
     }
     foreach ($updates as $update) {
         $update->setTransactionTicket($ticket);
         $update->doUpdate();
     }
     InfoAction::invalidateCache($title);
     return true;
 }