/** * Send a packet to SFlow daemon * * @param $app_name * @param $op_name * @param string $attributes * @param int $status * @param string $status_descr * @param int $req_bytes * @param int $resp_bytes * @param int $uS */ private static function app_operation($app_name, $op_name, $attributes = "", $status = 0, $status_descr = "", $req_bytes = 0, $resp_bytes = 0, $uS = 0) { global $wgSFlowHost, $wgSFlowPort, $wgSFlowSampling; // sampling handling $sampling_rate = $wgSFlowSampling; if ($sampling_rate > 1) { if (mt_rand(1, $sampling_rate) != 1) { return; } } wfProfileIn(__METHOD__); try { $sock = fsockopen("udp://" . $wgSFlowHost, $wgSFlowPort, $errno, $errstr); if (!$sock) { wfProfileOut(__METHOD__); return; } $data = ["flow_sample" => ["app_name" => $app_name, "sampling_rate" => $sampling_rate, "app_operation" => ["operation" => $op_name, "attributes" => $attributes, "status_descr" => $status_descr, "status" => $status, "req_bytes" => $req_bytes, "resp_bytes" => $resp_bytes, "uS" => $uS]]]; $payload = json_encode($data); wfDebug(sprintf("%s: sending '%s'\n", __METHOD__, $payload)); fwrite($sock, $payload); fclose($sock); } catch (\Exception $e) { \Wikia::log(__METHOD__, 'send', $e->getMessage(), true); \Wikia::logBacktrace(__METHOD__); } wfProfileOut(__METHOD__); }
/** * Constructor * * @link http://pl2.php.net/manual/en/exception.construct.php * @param string $message * @param int $code * @param Exception $exception */ public function __construct($message = '', $code = 0, Exception $previous = null) { if (version_compare(PHP_VERSION, '5.3.0', '<')) { parent::__construct($message, $code); $this->_previous = $previous; } else { parent::__construct($message, $code, $previous); } // log more details (macbre) Wikia::logBacktrace(__METHOD__); }
protected function loadStructuredData(EditHubModel $model, $params) { try { $apiResponse = $this->app->sendRequest('WAMApi', 'getWAMIndex', $params)->getData(); } catch (WikiaHttpException $e) { $logMsg = 'Message: ' . $e->getLogMessage() . ' Details: ' . $e->getDetails(); Wikia::log(__METHOD__, false, $logMsg); Wikia::logBacktrace(__METHOD__); } $data = ['vertical_id' => $params['vertical_id'], 'api_response' => $apiResponse]; return $this->getStructuredData($data); }
protected static function renderDataList($list) { $result = array(); foreach ($list as $v) { if (is_object($v)) { $item = $v->getRenderData(); if ($item) { $result[] = $item; } } else { Wikia::log(__METHOD__, false, 'BugID: 21498'); Wikia::logBacktrace(__METHOD__); } } return $result; }
protected function getTouchedKey($title) { //fb#24914 if ($title instanceof Title) { $key = wfMemcKey('category_touched', md5($title->getDBKey()), self::CACHE_VERSION); return $key; } else { Wikia::log(__METHOD__, '', '$title not an instance of Title'); Wikia::logBacktrace(__METHOD__); return null; } }
/** * Get messages for a given package as key => value structure * * Resolve messages list (entries matching "feature-*" pattern) * * @param string $name - name of the messages package * @param boolean $allowWildcards - can packages with wildcard be added? * @return array - key/value array of messages */ private static function getPackage($name, $allowWildcards = true) { wfProfileIn(__METHOD__); $ret = null; if (isset(self::$packages[$name])) { self::log(__METHOD__, $name); // get messages $messages = self::$packages[$name]; $ret = array(); foreach ($messages as $message) { // pattern to match messages (e.g. "feature-*") if (substr($message, -1) == '*') { // BugId:18482 if ($allowWildcards) { $msgs = self::resolveMessagesPattern($message); if (!empty($msgs)) { $ret = array_merge($ret, $msgs); } } else { Wikia::logBacktrace(__METHOD__); wfProfileOut(__METHOD__); trigger_error("JSMessages: '{$name}' package with wildcard matching can only be used in EXTERNAL mode", E_USER_ERROR); return; } } else { //@todo - this removes the {{PLURAL prefix, so plurals won't work in JS //on the other hand we cannot simply set $transform to true, as we want the wiki links to be parsed $msg = wfMsgGetKey($message, true); // check for not existing message if ($msg == htmlspecialchars("<{$message}>")) { $msg = false; } $ret[$message] = $msg; } } } wfProfileOut(__METHOD__); return $ret; }
function wfDevBoxLogExceptions($errorText) { Wikia::logBacktrace("wfDevBoxLogExceptions"); Wikia::log($errorText); return $errorText; }
/** * dispatch the request * * @param WikiaApp $app * @param WikiaRequest $request * @throws WikiaException * @throws Exception * @throws WikiaHttpException * @throws WikiaDispatchedException * @return WikiaResponse */ public function dispatch(WikiaApp $app, WikiaRequest $request) { wfProfileIn(__METHOD__); global $wgAutoloadClasses; if (empty($wgAutoloadClasses)) { wfProfileOut(__METHOD__); throw new WikiaException("wgAutoloadClasses is empty, cannot dispatch Request"); } $format = $request->getVal('format', WikiaResponse::FORMAT_HTML); $response = new WikiaResponse($format, $request); $controller = null; $profilename = 'unset'; // Main dispatch is a loop because Controllers can forward to each other // Error condition is also handled via forwarding to the error controller do { // First time through the loop we skip this section // If we got through the dispatch loop and have a nextCall, then call it. // Request and Response are re-used, Response data can be optionally reset if ($controller && $controller->hasNext()) { $nextCall = $controller->getNext(); $request->setVal('controller', $nextCall['controller']); $request->setVal('method', $nextCall['method']); if ($nextCall['reset']) { $response->resetData(); } } $profilename = null; try { // Determine the "base" name for the controller, stripping off Controller/Service/Module $controllerName = $app->getBaseName($request->getVal('controller')); if (empty($controllerName)) { throw new WikiaException("Controller parameter missing or invalid: {$controllerName}"); } // Service classes must be dispatched by full name otherwise we look for a controller. if ($app->isService($request->getVal('controller'))) { $controllerClassName = $app->getServiceClassName($controllerName); } else { $controllerClassName = $app->getControllerClassName($controllerName); } if (empty($wgAutoloadClasses[$controllerClassName])) { throw new ControllerNotFoundException($controllerName); } // Determine the final name for the controller and method based on any routing rules $callNext = $this->applyRouting($app, $response, $controllerClassName, $request->getVal('method', self::DEFAULT_METHOD_NAME)); $controllerClassName = $response->getControllerName(); // might have been changed $controllerName = $app->getBaseName($controllerClassName); // chop off Service/Controller $method = $response->getMethodName(); // might have been changed $profilename = __METHOD__ . " ({$controllerClassName}_{$method})"; wfProfileIn($profilename); $controller = new $controllerClassName(); /* @var $controller WikiaController */ $response->setTemplateEngine($controllerClassName::DEFAULT_TEMPLATE_ENGINE); if ($callNext) { list($nextController, $nextMethod, $resetData) = explode("::", $callNext); $controller->forward($nextController, $nextMethod, $resetData); } // map X to executeX method names for things that used to be modules if (!method_exists($controller, $method)) { $method = ucfirst($method); $hookMethod = $method; // the original module hook naming scheme does not use the "Execute" part // This will throw an exception if the template is missing // Refactor the offending class to not use executeXYZ methods or set format in request params // Warning: this means you can't use the new Dispatcher routing to switch templates in modules if ($format == WikiaResponse::FORMAT_HTML) { try { $response->getView()->setTemplate($controllerName, $method); } catch (WikiaException $e) { throw new MethodNotFoundException("{$controllerClassName}::{$method}"); } } $method = "execute{$method}"; $params = $request->getParams(); // old modules expect params in a different place } else { $hookMethod = $method; $params = array(); } if (!$request->isInternal() && !$controller->allowsExternalRequests() || in_array($method, array('allowsExternalRequests', 'getRequest', 'setRequest', 'getResponse', 'setResponse', 'getApp', 'setApp', 'init')) || !method_exists($controller, $method) || !is_callable(array($controller, $method))) { throw new MethodNotFoundException("{$controllerClassName}::{$method}"); } if (!$request->isInternal()) { $this->testIfUserHasPermissionsOrThrow($app, $controller, $method); } // Initialize the RequestContext object if it is not already set // SpecialPageController context is already set by SpecialPageFactory::execute by the time it gets here if ($controller->getContext() === null) { $controller->setContext(RequestContext::getMain()); } // If a SpecialPageController is dispatching a request to itself, preserve the original request context // TODO: come up with a better fix for this (it's because of the setInstance call in WikiaSpecialPageController) $originalRequest = $controller->getRequest(); $originalResponse = $controller->getResponse(); $controller->setRequest($request); $controller->setResponse($response); $controller->setApp($app); $controller->init(); if (method_exists($controller, 'preventBlockedUsage') && $controller->preventBlockedUsage($controller->getContext()->getUser(), $method)) { $result = false; } elseif (method_exists($controller, 'userAllowedRequirementCheck') && $controller->userAllowedRequirementCheck($controller->getContext()->getUser(), $method)) { $result = false; } else { // Actually call the controller::method! $result = $controller->{$method}($params); } if ($result === false) { // skip template rendering when false returned $controller->skipRendering(); } // Preserve original request (this is for SpecialPageControllers) if ($originalRequest != null) { $controller->setRequest($originalRequest); } if ($originalResponse != null) { $controller->setResponse($originalResponse); } // keep the AfterExecute hooks for now, refactor later using "after" dispatching $app->runHook("{$controllerName}{$hookMethod}AfterExecute", array(&$controller, &$params)); wfProfileOut($profilename); } catch (WikiaHttpException $e) { if ($request->isInternal()) { //if it is internal call rethrow it so we can apply normal handling wfProfileOut(__METHOD__); throw $e; } else { wfProfileOut($profilename); $response->setException($e); $response->setFormat('json'); $response->setCode($e->getCode()); $response->setVal('error', get_class($e)); $details = $e->getDetails(); if (!empty($details)) { $response->setVal('message', $details); } } } catch (Exception $e) { if ($profilename) { wfProfileOut($profilename); } $response->setException($e); Wikia::log(__METHOD__, $e->getMessage()); // if we catch an exception, forward to the WikiaError controller unless we are already dispatching Error if (empty($controllerClassName) || $controllerClassName != 'WikiaErrorController') { $controller = new WikiaErrorController(); $controller->forward('WikiaError', 'error', false); // keep params for error controller $response->getView()->setTemplatePath(null); // response is re-used so skip the original template } } } while ($controller && $controller->hasNext()); if ($request->isInternal() && $response->hasException() && $request->getExceptionMode() !== WikiaRequest::EXCEPTION_MODE_RETURN) { Wikia::logBacktrace(__METHOD__ . '::exception'); wfProfileOut(__METHOD__); switch ($request->getExceptionMode()) { case WikiaRequest::EXCEPTION_MODE_THROW: throw $response->getException(); // case WikiaRequest::EXCEPTION_MODE_WRAP_AND_THROW: // case WikiaRequest::EXCEPTION_MODE_WRAP_AND_THROW: default: throw new WikiaDispatchedException("Internal Throw ({$response->getException()->getMessage()})", $response->getException()); } } wfProfileOut(__METHOD__); return $response; }
/** * constructor * @param $globalRegistry WikiaGlobalRegistry * @param $localRegistry WikiaLocalRegistry * @param $hookDispatcher WikiaHookDispatcher */ public function __construct(WikiaGlobalRegistry $globalRegistry = null, WikiaLocalRegistry $localRegistry = null, WikiaHookDispatcher $hookDispatcher = null, WikiaFunctionWrapper $functionWrapper = null) { if (!is_object($globalRegistry)) { F::setInstance('WikiaGlobalRegistry', new WikiaGlobalRegistry()); $globalRegistry = F::build('WikiaGlobalRegistry'); } if (!is_object($localRegistry)) { F::setInstance('WikiaLocalRegistry', new WikiaLocalRegistry()); $localRegistry = F::build('WikiaLocalRegistry'); } if (!is_object($hookDispatcher)) { F::setInstance('WikiaHookDispatcher', new WikiaHookDispatcher()); $hookDispatcher = F::build('WikiaHookDispatcher'); } if (!is_object($functionWrapper)) { $functionWrapper = F::build('WikiaFunctionWrapper'); } $this->localRegistry = $localRegistry; $this->hookDispatcher = $hookDispatcher; // set helper accessors $this->wg = $globalRegistry; $this->wf = $functionWrapper; // register ajax dispatcher if (is_object($this->wg)) { $this->wg->append('wgAjaxExportList', 'WikiaApp::ajax'); } else { Wikia::log(__METHOD__, false, 'WikiaGlobalRegistry not set in ' . __CLASS__ . ' ' . __METHOD__); Wikia::logBacktrace(__METHOD__); } }
/** * dispatch the request * * @param WikiaApp $app * @param WikiaRequest $request * @return WikiaResponse */ public function dispatch(WikiaApp $app, WikiaRequest $request) { $autoloadClasses = $app->wg->AutoloadClasses; if (empty($autoloadClasses)) { throw new WikiaException("wgAutoloadClasses is empty, cannot dispatch Request"); } $format = $request->getVal('format', WikiaResponse::FORMAT_HTML); $response = F::build('WikiaResponse', array('format' => $format, 'request' => $request)); if ($app->wg->EnableSkinTemplateOverride && $app->isSkinInitialized()) { $response->setSkinName($app->wg->User->getSkin()->getSkinName()); } // Main dispatch is a loop because Controllers can forward to each other // Error condition is also handled via dispatching to the error controller do { $request->setDispatched(true); try { $method = $this->getMethodName($request); // Determine the "base" name for the controller, stripping off Controller/Service/Module $controllerName = $app->getBaseName($request->getVal('controller')); // Service classes must be dispatched by full name otherwise we look for a controller. if ($app->isService($request->getVal('controller'))) { $controllerClassName = $app->getServiceClassName($controllerName); } else { $controllerClassName = $app->getControllerClassName($controllerName); } $profilename = __METHOD__ . " ({$controllerName}_{$method})"; if (empty($controllerName)) { throw new WikiaException("Invalid controller name: {$controllerName}"); } if (empty($autoloadClasses[$controllerClassName])) { throw new WikiaException("Controller class does not exist: {$controllerClassName}"); } $app->wf->profileIn($profilename); $response->setControllerName($controllerClassName); $response->setMethodName($method); $controller = F::build($controllerClassName); /* @var $controller WikiaController */ // map X to executeX method names for things that used to be modules if (!method_exists($controller, $method)) { $method = ucfirst($method); // This will throw an exception if the template is missing // Refactor the offending class to not use executeXYZ methods or set format in request params if ($format == WikiaResponse::FORMAT_HTML) { $response->getView()->setTemplate($controllerName, $method); } $method = "execute{$method}"; $params = $request->getParams(); // old modules expect params in a different place } if (!$request->isInternal() && !$controller->allowsExternalRequests() || in_array($method, array('allowsExternalRequests', 'getRequest', 'setRequest', 'getResponse', 'setResponse', 'getApp', 'setApp', 'init')) || !method_exists($controller, $method) || !is_callable(array($controller, $method))) { throw new WikiaException("Could not dispatch {$controllerClassName}::{$method}"); } // Initialize the RequestContext object if it is not already set // SpecialPageController context is already set by SpecialPageFactory::execute by the time it gets here if ($controller->getContext() === null) { $controller->setContext(RequestContext::getMain()); } // If a SpecialPageController is dispatching a request to itself, preserve the original request context // TODO: come up with a better fix for this (it's because of the setInstance call in WikiaSpecialPageController) $originalRequest = $controller->getRequest(); $originalResponse = $controller->getResponse(); $controller->setRequest($request); $controller->setResponse($response); $controller->setApp($app); $controller->init(); // BugId:5125 - keep old hooks naming convention $hookMethod = ucfirst($this->getMethodName($request)); $hookResult = $app->runHook("{$controllerName}{$hookMethod}BeforeExecute", array(&$controller, &$params)); if ($hookResult) { $result = $controller->{$method}($params); if ($result === false) { // skip template rendering when false returned $controller->skipRendering(); } } // Preserve original request (this is for SpecialPageControllers) if ($originalRequest != null) { $controller->setRequest($originalRequest); } if ($originalResponse != null) { $controller->setResponse($originalResponse); } // we ignore the result of the AfterExecute hook $app->runHook("{$controllerName}{$hookMethod}AfterExecute", array(&$controller, &$params)); $app->wf->profileOut($profilename); } catch (Exception $e) { $app->wf->profileOut($profilename); $response->setException($e); Wikia::log(__METHOD__, $e->getMessage()); // if we catch an exception, redirect to the WikiaError controller if ($controllerClassName != 'WikiaErrorController' && $method != 'error') { $response->getView()->setTemplatePath(null); $request->setVal('controller', 'WikiaError'); $request->setVal('method', 'error'); $request->setDispatched(false); } } } while (!$request->isDispatched()); if ($request->isInternal() && $response->hasException()) { Wikia::logBacktrace(__METHOD__ . '::exception'); throw new WikiaDispatchedException("Internal Throw ({$response->getException()->getMessage()})", $response->getException()); } return $response; }
/** * Defines error handler to log backtrace for PHP (catchable) fatal errors * * @author Maciej Brencz <*****@*****.**> */ function wfWikiaErrorHandler($errno, $errstr, $errfile, $errline) { switch ($errno) { case E_RECOVERABLE_ERROR: Wikia::logBacktrace("PHP fatal error caught ({$errstr})"); break; } // error was not really handled return false; }
/** * @static * @param $body * @param $page * @param $user * @param string $metaTitle * @param bool|WallMessage $parent * @param array $relatedTopics * @param bool $notify * @param bool $notifyEveryone * @return WallMessage|Bool */ public static function buildNewMessageAndPost($body, $page, $user, $metaTitle = '', $parent = false, $relatedTopics = array(), $notify = true, $notifyEveryone = false) { wfProfileIn(__METHOD__); if ($page instanceof Title) { $userPageTitle = $page; } else { $userPageTitle = Title::newFromText($page, NS_USER_WALL); } // if message wall was just created, we should later use MASTER db when creating title object $useMasterDB = false; // create wall page by bot if not exist if ($userPageTitle instanceof Title && !$userPageTitle->exists()) { $userPageTitle = self::addMessageWall($userPageTitle); $useMasterDB = true; } if (empty($userPageTitle)) { Wikia::log(__METHOD__, '', '$userPageTitle not an instance of Title'); Wikia::logBacktrace(__METHOD__); wfProfileOut(__METHOD__); return false; } if ($parent === false) { $metaData = array('title' => $metaTitle); if ($notifyEveryone) { $metaData['notify_everyone'] = time(); } if (!empty($relatedTopics)) { $metaData['related_topics'] = implode('|', $relatedTopics); } $acStatus = ArticleComment::doPost($body, $user, $userPageTitle, false, $metaData); } else { if (!$parent->canReply()) { wfProfileOut(__METHOD__); return false; } $acStatus = ArticleComment::doPost($body, $user, $userPageTitle, $parent->getId(), null); } if ($acStatus === false) { wfProfileOut(__METHOD__); return false; } $ac = ArticleComment::newFromId($acStatus[1]->getId()); if (empty($ac)) { wfProfileOut(__METHOD__); return false; } // after successful posting invalidate Wall cache /** * @var $class WallMessage */ $class = new WallMessage($ac->getTitle(), $ac); if ($parent === false) { // $db = DB_SLAVE $class->storeRelatedTopicsInDB($relatedTopics); $class->setOrderId(1); $class->getWall()->invalidateCache(); } else { $count = $parent->getOrderId(true); // this is not work perfect with transations if (is_numeric($count)) { $count++; $parent->setOrderId($count); $class->setOrderId($count); } // after successful posting invalidate Thread cache $class->getThread()->invalidateCache(); $rp = new WallRelatedPages(); $rp->setLastUpdate($parent->getId()); } // Build data for sweet url ? id#number_of_comment // notify if ($notify) { $class->sendNotificationAboutLastRev($useMasterDB); } if ($parent === false && $notifyEveryone) { $class->notifyEveryone(); } $class->addWatch($user); wfRunHooks('AfterBuildNewMessageAndPost', array(&$class)); wfProfileOut(__METHOD__); return $class; }
/** * Record a file upload in the upload log and the image table */ function recordUpload2($oldver, $comment, $pageText, $props = false, $timestamp = false, $user = null) { global $wgCityId; if (is_null($user)) { global $wgUser; $user = $wgUser; } $dbw = $this->repo->getMasterDB(); $dbw->begin(); if (!$props) { $props = $this->repo->getFileProps($this->getVirtualUrl()); } if ($timestamp === false) { $timestamp = $dbw->timestamp(); } $props['description'] = $comment; $props['user'] = $user->getId(); $props['user_text'] = $user->getName(); $props['timestamp'] = wfTimestamp(TS_MW, $timestamp); // DB -> TS_MW $this->setProps($props); # Fail now if the file isn't there if (!$this->fileExists) { wfDebug(__METHOD__ . ": File " . $this->getRel() . " went missing!\n"); return false; } $reupload = false; # Test to see if the row exists using INSERT IGNORE # This avoids race conditions by locking the row until the commit, and also # doesn't deadlock. SELECT FOR UPDATE causes a deadlock for every race condition. $dbw->insert('image', array('img_name' => $this->getName(), 'img_size' => $this->size, 'img_width' => intval($this->width), 'img_height' => intval($this->height), 'img_bits' => $this->bits, 'img_media_type' => $this->media_type, 'img_major_mime' => $this->major_mime, 'img_minor_mime' => $this->minor_mime, 'img_timestamp' => $timestamp, 'img_description' => $comment, 'img_user' => $user->getId(), 'img_user_text' => $user->getName(), 'img_metadata' => $this->metadata, 'img_sha1' => $this->sha1), __METHOD__, 'IGNORE'); if ($dbw->affectedRows() == 0) { if ($oldver == '') { // XXX # (bug 34993) publish() can displace the current file and yet fail to save # a new one. The next publish attempt will treat the file as a brand new file # and pass an empty $oldver. Allow this bogus value so we can displace the # `image` row to `oldimage`, leaving room for the new current file `image` row. #throw new MWException( "Empty oi_archive_name. Database and storage out of sync?" ); Wikia::logBacktrace(__METHOD__ . "::oi_archive_name - [{$this->getName()}]"); // Wikia change (BAC-1068) } $reupload = true; # Collision, this is an update of a file # Insert previous contents into oldimage $dbw->insertSelect('oldimage', 'image', array('oi_name' => 'img_name', 'oi_archive_name' => $dbw->addQuotes($oldver), 'oi_size' => 'img_size', 'oi_width' => 'img_width', 'oi_height' => 'img_height', 'oi_bits' => 'img_bits', 'oi_timestamp' => 'img_timestamp', 'oi_description' => 'img_description', 'oi_user' => 'img_user', 'oi_user_text' => 'img_user_text', 'oi_metadata' => 'img_metadata', 'oi_media_type' => 'img_media_type', 'oi_major_mime' => 'img_major_mime', 'oi_minor_mime' => 'img_minor_mime', 'oi_sha1' => 'img_sha1'), array('img_name' => $this->getName()), __METHOD__); # Update the current image row $dbw->update('image', array('img_size' => $this->size, 'img_width' => intval($this->width), 'img_height' => intval($this->height), 'img_bits' => $this->bits, 'img_media_type' => $this->media_type, 'img_major_mime' => $this->major_mime, 'img_minor_mime' => $this->minor_mime, 'img_timestamp' => $timestamp, 'img_description' => $comment, 'img_user' => $user->getId(), 'img_user_text' => $user->getName(), 'img_metadata' => $this->metadata, 'img_sha1' => $this->sha1), array('img_name' => $this->getName()), __METHOD__); } else { # This is a new file # Update the image count $dbw->begin(__METHOD__); $dbw->update('site_stats', array('ss_images = ss_images+1'), '*', __METHOD__); $dbw->commit(__METHOD__); } $descTitle = $this->getTitle(); $wikiPage = new WikiFilePage($descTitle); $wikiPage->setFile($this); # Add the log entry $log = new LogPage('upload'); $action = $reupload ? 'overwrite' : 'upload'; $log->addEntry($action, $descTitle, $comment, array(), $user); if ($descTitle->exists()) { # Create a null revision $latest = $descTitle->getLatestRevID(); $nullRevision = Revision::newNullRevision($dbw, $descTitle->getArticleId(), $log->getRcComment(), false); if (!is_null($nullRevision)) { $nullRevision->insertOn($dbw); wfRunHooks('NewRevisionFromEditComplete', array($wikiPage, $nullRevision, $latest, $user)); $wikiPage->updateRevisionOn($dbw, $nullRevision); } # Invalidate the cache for the description page $descTitle->invalidateCache(); $descTitle->purgeSquid(); } else { # New file; create the description page. # There's already a log entry, so don't make a second RC entry # Squid and file cache for the description page are purged by doEdit. $wikiPage->doEdit($pageText, $comment, EDIT_NEW | EDIT_SUPPRESS_RC, false, $user); } /* wikia change - begin (VID-1568) */ // Update/Insert video info try { \VideoInfoHooksHelper::upsertVideoInfo($this, $reupload); } catch (\Exception $e) { $dbw->rollback(); return false; } /* wikia change - end (VID-1568) */ # Commit the transaction now, in case something goes wrong later # The most important thing is that files don't get lost, especially archives $dbw->commit(); # Save to cache and purge the squid # We shall not saveToCache before the commit since otherwise # in case of a rollback there is an usable file from memcached # which in fact doesn't really exist (bug 24978) $this->saveToCache(); if ($reupload) { # Delete old thumbnails wfProfileIn(__METHOD__ . '-purge'); $this->purgeThumbnails(); wfProfileOut(__METHOD__ . '-purge'); # Remove the old file from the squid cache SquidUpdate::purge(array($this->getURL())); /* wikia change - begin (VID-1568) */ \VideoInfoHooksHelper::purgeVideoInfoCache($this); /* wikia change - end (VID-1568) */ } # Hooks, hooks, the magic of hooks... wfRunHooks('FileUpload', array($this, $reupload, $descTitle->exists())); # Invalidate cache for all pages using this file // Wikia change begin @author Scott Rabin (srabin@wikia-inc.com) $task = (new \Wikia\Tasks\Tasks\HTMLCacheUpdateTask())->wikiId($wgCityId)->title($this->getTitle()); $task->call('purge', 'imagelinks'); $task->queue(); // Wikia change end # Invalidate cache for all pages that redirects on this page $redirs = $this->getTitle()->getRedirectsHere(); foreach ($redirs as $redir) { // Wikia change begin @author Scott Rabin (srabin@wikia-inc.com) $task = (new \Wikia\Tasks\Tasks\HTMLCacheUpdateTask())->wikiId($wgCityId)->title($redir); $task->call('purge', 'imagelinks'); $task->queue(); // Wikia change end } return true; }
/** * Get an associative array containing information about * a file with the given storage path. * * @param $ext Mixed: the file extension, or true to extract it from the filename. * Set it to false to ignore the extension. * * @return array */ public function getProps($ext = true) { wfProfileIn(__METHOD__); wfDebug(__METHOD__ . ": Getting file info for {$this->path}\n"); $info = self::placeholderProps(); $info['fileExists'] = $this->exists(); if ($info['fileExists']) { $magic = MimeMagic::singleton(); # get the file extension if ($ext === true) { $ext = self::extensionFromPath($this->path); } # mime type according to file contents $info['file-mime'] = $this->getMimeType(); # logical mime type $info['mime'] = $magic->improveTypeFromExtension($info['file-mime'], $ext); list($info['major_mime'], $info['minor_mime']) = File::splitMime($info['mime']); $info['media_type'] = $magic->getMediaType($this->path, $info['mime']); # Get size in bytes $info['size'] = $this->getSize(); # Wikia change - begin # @author macbre - BAC-773 if (empty($info['size'])) { Wikia::log(__METHOD__, 'emptySize', sprintf('filesize() returned "%s"', print_r($info['size'], true)), true); Wikia::logBacktrace(__METHOD__ . '-emptySize'); } # Wikia change - end # Height, width and metadata $handler = MediaHandler::getHandler($info['mime']); if ($handler) { $tempImage = (object) array(); $info['metadata'] = $handler->getMetadata($tempImage, $this->path); $gis = $handler->getImageSize($tempImage, $this->path, $info['metadata']); if (is_array($gis)) { $info = $this->extractImageSizeInfo($gis) + $info; } } $info['sha1'] = $this->getSha1Base36(); wfDebug(__METHOD__ . ": {$this->path} loaded, {$info['size']} bytes, {$info['mime']}.\n"); } else { wfDebug(__METHOD__ . ": {$this->path} NOT FOUND!\n"); } wfProfileOut(__METHOD__); return $info; }
protected function doIncrementalUpdate() { // Wikia change - start (BAC-597) if ($this->mId === 0) { Wikia::logBacktrace(__CLASS__ . '::mIdIsZero - update skipped'); return; } // Wikia change - end wfProfileIn(__METHOD__); # Page links $existing = $this->getExistingLinks(); $this->incrTableUpdate('pagelinks', 'pl', $this->getLinkDeletions($existing), $this->getLinkInsertions($existing)); # Image links $existing = $this->getExistingImages(); $imageDeletes = $this->getImageDeletions($existing); /* Wikia change begin - @author: mech */ $imageInserts = $this->getImageInsertions($existing); Wikia::setVar('imageDeletes', $imageDeletes); // images are in array keys! Wikia::setVar('imageInserts', $imageInserts); $this->incrTableUpdate('imagelinks', 'il', $imageDeletes, $imageInserts); /* Wikia change end */ # Invalidate all image description pages which had links added or removed $imageUpdates = $imageDeletes + array_diff_key($this->mImages, $existing); /* Wikia change CE-677 @author Kamil Koterba kamil@wikia-inc.com */ $this->queueImageDescriptionsInvalidation($imageUpdates); /* Wikia change end */ # External links $existing = $this->getExistingExternals(); $this->incrTableUpdate('externallinks', 'el', $this->getExternalDeletions($existing), $this->getExternalInsertions($existing)); # Language links $existing = $this->getExistingInterlangs(); $this->incrTableUpdate('langlinks', 'll', $this->getInterlangDeletions($existing), $this->getInterlangInsertions($existing)); # Inline interwiki links $existing = $this->getExistingInterwikis(); $this->incrTableUpdate('iwlinks', 'iwl', $this->getInterwikiDeletions($existing), $this->getInterwikiInsertions($existing)); # Template links $existing = $this->getExistingTemplates(); $this->incrTableUpdate('templatelinks', 'tl', $this->getTemplateDeletions($existing), $this->getTemplateInsertions($existing)); # Category links $existing = $this->getExistingCategories(); $categoryDeletes = $this->getCategoryDeletions($existing); $this->incrTableUpdate('categorylinks', 'cl', $categoryDeletes, $this->getCategoryInsertions($existing)); # Invalidate all categories which were added, deleted or changed (set symmetric difference) $categoryInserts = array_diff_assoc($this->mCategories, $existing); $categoryUpdates = $categoryInserts + $categoryDeletes; /* Wikia change CE-677 @author Kamil Koterba kamil@wikia-inc.com */ $this->queueCategoriesInvalidation($categoryUpdates); # do the actual invalidation in all pages queued so far $this->invalidatePages(); /* Wikia change end */ $this->updateCategoryCounts($categoryInserts, $categoryDeletes); wfRunHooks('AfterCategoriesUpdate', array($categoryInserts, $categoryDeletes, $this->mTitle)); Wikia::setVar('categoryInserts', $categoryInserts); # Page properties $existing = $this->getExistingProperties(); $propertiesDeletes = $this->getPropertyDeletions($existing); $this->incrTableUpdate('page_props', 'pp', $propertiesDeletes, $this->getPropertyInsertions($existing)); # Invalidate the necessary pages $changed = $propertiesDeletes + array_diff_assoc($this->mProperties, $existing); $this->invalidateProperties($changed); # Refresh links of all pages including this page # This will be in a separate transaction if ($this->mRecursive) { $this->queueRecursiveJobs(); } wfProfileOut(__METHOD__); }
/** * Get messages for a given package as key => value structure * * Resolve messages list (entries matching "feature-*" pattern) * * @param string $name - name of the messages package * @param boolean $allowWildcards - can packages with wildcard be added? * @return array - key/value array of messages */ private function getPackage($name, $allowWildcards = true) { $this->app->wf->ProfileIn(__METHOD__); $ret = null; if (isset($this->packages[$name])) { $this->log(__METHOD__, $name); // get messages $messages = $this->packages[$name]; $ret = array(); foreach ($messages as $message) { // pattern to match messages (e.g. "feature-*") if (substr($message, -1) == '*') { // BugId:18482 if ($allowWildcards) { $msgs = $this->resolveMessagesPattern($message); if (!empty($msgs)) { $ret = array_merge($ret, $msgs); } } else { Wikia::logBacktrace(__METHOD__); trigger_error("JSMessages: '{$name}' package with wildcard matching can only be used in EXTERNAL mode", E_USER_ERROR); return; } } else { $msg = $this->app->wf->MsgGetKey($message, true); // check for not existing message if ($msg == htmlspecialchars("<{$message}>")) { $msg = false; } $ret[$message] = $msg; } } } $this->app->wf->ProfileOut(__METHOD__); return $ret; }
static function render($input, $params, $parser) { global $wgScriptPath, $wgUrlProtocols, $wgNoFollowLinks; $lines = explode("\n", $input); $first = true; $lineNum = 0; $mapHTML = ''; $links = array(); # Define canonical desc types to allow i18n of 'imagemap_desc_types' $descTypesCanonical = 'top-right, bottom-right, bottom-left, top-left, none'; $descType = self::BOTTOM_RIGHT; $defaultLinkAttribs = false; $realmap = true; foreach ($lines as $line) { ++$lineNum; $externLink = false; $line = trim($line); if ($line == '' || $line[0] == '#') { continue; } if ($first) { $first = false; # The first line should have an image specification on it # Extract it and render the HTML $bits = explode('|', $line, 2); if (count($bits) == 1) { $image = $bits[0]; $options = ''; } else { list($image, $options) = $bits; } $imageTitle = Title::newFromText($image); if (!$imageTitle || $imageTitle->getNamespace() != NS_IMAGE) { return self::error('imagemap_no_image'); } if (wfIsBadImage($imageTitle->getDBkey(), $parser->mTitle)) { return self::error('imagemap_bad_image'); } // Parse the options so we can use links and the like in the caption $parsedOptions = $parser->recursiveTagParse($options); $imageHTML = $parser->makeImage($imageTitle, $parsedOptions); $parser->replaceLinkHolders($imageHTML); $imageHTML = $parser->mStripState->unstripBoth($imageHTML); $imageHTML = Sanitizer::normalizeCharReferences($imageHTML); $parser->mOutput->addImage($imageTitle->getDBkey()); $domDoc = new DOMDocument(); wfSuppressWarnings(); $ok = $domDoc->loadHTML($imageHTML); wfRestoreWarnings(); if (!$ok) { return self::error('imagemap_invalid_image'); } $xpath = new DOMXPath($domDoc); $imgs = $xpath->query('//img'); if (!$imgs->length) { return self::error('imagemap_invalid_image'); } $imageNode = $imgs->item(0); $thumbWidth = $imageNode->getAttribute('width'); $thumbHeight = $imageNode->getAttribute('height'); if (function_exists('wfFindFile')) { $imageObj = wfFindFile($imageTitle); } else { // Old MW $imageObj = wfFindFile($imageTitle); } if (!$imageObj || !$imageObj->exists()) { return self::error('imagemap_invalid_image'); } # Add the linear dimensions to avoid inaccuracy in the scale # factor when one is much larger than the other # (sx+sy)/(x+y) = s $denominator = $imageObj->getWidth() + $imageObj->getHeight(); $numerator = $thumbWidth + $thumbHeight; if ($denominator <= 0 || $numerator <= 0) { return self::error('imagemap_invalid_image'); } $scale = $numerator / $denominator; continue; } # Handle desc spec $cmd = strtok($line, " \t"); if ($cmd == 'desc') { $typesText = wfMsgForContent('imagemap_desc_types'); if ($descTypesCanonical != $typesText) { // i18n desc types exists $typesText = $descTypesCanonical . ', ' . $typesText; } $types = array_map('trim', explode(',', $typesText)); $type = trim(strtok('')); $descType = array_search($type, $types); if ($descType > 4) { // A localized descType is used. Subtract 5 to reach the canonical desc type. $descType = $descType - 5; } if ($descType === false || $descType < 0) { // <0? In theory never, but paranoia... return self::error('imagemap_invalid_desc', $typesText); } continue; } # Find the link $link = trim(strstr($line, '[')); if (preg_match('/^ \\[\\[ ([^|]*+) \\| ([^\\]]*+) \\]\\] \\w* $ /x', $link, $m)) { $title = Title::newFromText($m[1]); if (!$title instanceof Title) { return self::error('imagemap_invalid_title', $lineNum); } $alt = trim($m[2]); } elseif (preg_match('/^ \\[\\[ ([^\\]]*+) \\]\\] \\w* $ /x', $link, $m)) { $title = Title::newFromText($m[1]); if (!$title instanceof Title) { return self::error('imagemap_invalid_title', $lineNum); } $alt = $title->getFullText(); } elseif (in_array(substr($link, 1, strpos($link, '//') + 1), $wgUrlProtocols) || in_array(substr($link, 1, strpos($link, ':')), $wgUrlProtocols)) { if (preg_match('/^ \\[ ([^\\s]*+) \\s ([^\\]]*+) \\] \\w* $ /x', $link, $m)) { $title = $m[1]; $alt = trim($m[2]); $externLink = true; } elseif (preg_match('/^ \\[ ([^\\]]*+) \\] \\w* $ /x', $link, $m)) { $title = $alt = trim($m[1]); $externLink = true; } // end nested elseif } else { return self::error('imagemap_no_link', $lineNum); } if (!$title) { return self::error('imagemap_invalid_title', $lineNum); } $shapeSpec = substr($line, 0, -strlen($link)); # Tokenize shape spec $shape = strtok($shapeSpec, " \t"); switch ($shape) { case 'default': $coords = array(); break; case 'rect': $coords = self::tokenizeCoords(4, $lineNum); if (!is_array($coords)) { return $coords; } break; case 'circle': $coords = self::tokenizeCoords(3, $lineNum); if (!is_array($coords)) { return $coords; } break; case 'poly': $coords = array(); $coord = strtok(" \t"); while ($coord !== false) { $coords[] = $coord; $coord = strtok(" \t"); } if (!count($coords)) { return self::error('imagemap_missing_coord', $lineNum); } if (count($coords) % 2 !== 0) { return self::error('imagemap_poly_odd', $lineNum); } break; default: return self::error('imagemap_unrecognised_shape', $lineNum); } # Scale the coords using the size of the source image foreach ($coords as $i => $c) { $coords[$i] = intval(round($c * $scale)); } # Construct the area tag $attribs = array(); if ($externLink) { $attribs['href'] = $title; $attribs['class'] = 'plainlinks'; if ($wgNoFollowLinks) { $attribs['rel'] = 'nofollow'; } } elseif ($title instanceof Title) { if ($title->getFragment() != '' && $title->getPrefixedDBkey() == '') { # XXX: kluge to handle [[#Fragment]] links, should really fix getLocalURL() # in Title.php to return an empty string in this case $attribs['href'] = $title->getFragmentForURL(); } else { $attribs['href'] = $title->escapeLocalURL() . $title->getFragmentForURL(); } } else { $attribs['href'] = '#'; Wikia::log(__METHOD__, false, '$title empty in imagemap'); Wikia::logBacktrace(__METHOD__); } if ($shape != 'default') { $attribs['shape'] = $shape; } if ($coords) { $attribs['coords'] = implode(',', $coords); } if ($alt != '') { if ($shape != 'default') { $attribs['alt'] = $alt; } $attribs['title'] = $alt; } if ($shape == 'default') { $defaultLinkAttribs = $attribs; } else { $mapHTML .= Xml::element('area', $attribs) . "\n"; } if ($externLink) { $extLinks[] = $title; } else { $links[] = $title; } } if ($first) { return self::error('imagemap_no_image'); } if ($mapHTML == '' && $defaultLinkAttribs == '') { return self::error('imagemap_no_areas'); } elseif ($mapHTML == '' && $defaultLinkAttribs != '') { // no areas defined, default only. It's not a real imagemap, so we do not need some tags $realmap = false; } if ($realmap) { # Construct the map # Add random number to avoid breaking cached HTML fragments that are # later joined together on the one page (bug 16471) $mapName = "ImageMap_" . ++self::$id . '_' . mt_rand(0, 0x7fffffff); $mapHTML = "<map name=\"{$mapName}\">\n{$mapHTML}</map>\n"; # Alter the image tag $imageNode->setAttribute('usemap', "#{$mapName}"); } # Add a surrounding div, remove the default link to the description page $anchor = $imageNode->parentNode; $parent = $anchor->parentNode; if ($parent instanceof DOMElement || $parent instanceof DOMDocument) { $div = $parent->insertBefore(new DOMElement('div'), $anchor); } else { return self::error('imagemap_no_parent'); } if ($defaultLinkAttribs) { $defaultAnchor = $div->appendChild(new DOMElement('a')); foreach ($defaultLinkAttribs as $name => $value) { $defaultAnchor->setAttribute($name, $value); } $imageParent = $defaultAnchor; } else { $imageParent = $div; } # Add the map HTML to the div # We used to add it before the div, but that made tidy unhappy if ($mapHTML != '') { $mapDoc = new DOMDocument(); $mapDoc->loadXML($mapHTML); $mapNode = $domDoc->importNode($mapDoc->documentElement, true); $div->appendChild($mapNode); } $imageParent->appendChild($imageNode->cloneNode(true)); $parent->removeChild($anchor); # Determine whether a "magnify" link is present $xpath = new DOMXPath($domDoc); $magnify = $xpath->query('//div[@class="magnify"]'); if (!$magnify->length && $descType != self::NONE) { # Add image description link if ($descType == self::TOP_LEFT || $descType == self::BOTTOM_LEFT) { $marginLeft = 0; } else { $marginLeft = $thumbWidth - 20; } if ($descType == self::TOP_LEFT || $descType == self::TOP_RIGHT) { $marginTop = -$thumbHeight; // 1px hack for IE, to stop it poking out the top $marginTop += 1; } else { $marginTop = -20; } $div->setAttribute('style', "height: {$thumbHeight}px; width: {$thumbWidth}px; "); $descWrapper = $div->appendChild(new DOMElement('div')); $descWrapper->setAttribute('style', "margin-left: {$marginLeft}px; " . "margin-top: {$marginTop}px; " . "text-align: left;"); $descAnchor = $descWrapper->appendChild(new DOMElement('a')); $descAnchor->setAttribute('href', $imageTitle->escapeLocalURL()); $descAnchor->setAttribute('title', wfMsgForContent('imagemap_description')); $descImg = $descAnchor->appendChild(new DOMElement('img')); $descImg->setAttribute('alt', wfMsgForContent('imagemap_description')); $descImg->setAttribute('src', "{$wgScriptPath}/extensions/ImageMap/desc-20.png"); $descImg->setAttribute('style', 'border: none;'); } # Output the result # We use saveXML() not saveHTML() because then we get XHTML-compliant output. # The disadvantage is that we have to strip out the DTD /* Wikia change begin - @author: Marooned */ /* output HTML5 to properly display elements */ global $wgHtml5; if ($wgHtml5) { $output = $domDoc->saveHTML(); } else { $output = preg_replace('/<\\?xml[^?]*\\?>/', '', $domDoc->saveXML()); } /* Wikia change end */ # Register links foreach ($links as $title) { if ($title instanceof Title) { if ($title->isExternal() || $title->getNamespace() == NS_SPECIAL) { // Don't register special or interwiki links... } elseif ($title->getNamespace() == NS_MEDIA) { // Regular Media: links are recorded as image usages $parser->mOutput->addImage($title->getDBkey()); } else { // Plain ol' link $parser->mOutput->addLink($title); } } else { Wikia::log(__METHOD__, false, '$title is not an instance of Title in $links'); Wikia::logBacktrace(__METHOD__); } } if (isset($extLinks)) { foreach ($extLinks as $title) { $parser->mOutput->addExternalLink($title); } } # Armour output against broken parser $output = str_replace("\n", '', $output); return $output; }
/** * Render default page header (with edit dropdown, history dropdown, ...) * * @param: array $params * key: showSearchBox (default: false) */ public function executeIndex($params) { global $wgTitle, $wgArticle, $wgOut, $wgUser, $wgContLang, $wgSupressPageTitle, $wgSupressPageSubtitle, $wgSuppressNamespacePrefix, $wgCityId, $wgEnableWallExt; wfProfileIn(__METHOD__); $this->isUserLoggedIn = $wgUser->isLoggedIn(); // page namespace $ns = $wgTitle->getNamespace(); /** start of wikia changes @author nAndy */ $this->isWallEnabled = (!empty($wgEnableWallExt) && $ns == NS_USER_WALL); /** end of wikia changes */ // currently used skin $skin = RequestContext::getMain()->getSkin(); // action button (edit / view soruce) and dropdown for it $this->prepareActionButton(); // dropdown actions $this->dropdown = $this->getDropdownActions(); /** start of wikia changes @author nAndy */ $response = $this->getResponse(); if( $response instanceof WikiaResponse ) { wfRunHooks( 'PageHeaderIndexAfterActionButtonPrepared', array($response, $ns, $skin) ); /** @author Jakub */ $this->extraButtons = array(); wfRunHooks( 'PageHeaderIndexExtraButtons', array( $response ) ); } else { //it happened on TimQ's devbox that $response was probably null fb#28747 Wikia::logBacktrace(__METHOD__); } /** end of wikia changes */ // for not existing pages page header is a bit different $this->pageExists = !empty($wgTitle) && $wgTitle->exists(); // default title "settings" (RT #145371), don't touch special pages if ($ns != NS_SPECIAL) { $this->displaytitle = true; $this->title = $wgOut->getPageTitle(); } else { // on special pages titles are already properly encoded (BugId:5983) $this->displaytitle = true; } // perform namespace and special page check // use service to get data $service = PageStatsService::newFromTitle( $wgTitle ); // comments - moved here to display comments even on deleted/non-existant pages $this->comments = $service->getCommentsCount(); if ($this->pageExists) { // show likes $this->likes = true; // get two popular categories this article is in $categories = array(); // FIXME: Might want to make a WikiFactory variable for controlling this feature if we aren't // comfortable with its performance. // NOTE: Skip getMostLinkedCategories() on Lyrics and Marvel because we're not sure yet that it's fast enough. $LYRICS_CITY_ID = "43339"; $MARVEL_CITY_ID = "2233"; if(($wgCityId != $LYRICS_CITY_ID) && ($wgCityId != $MARVEL_CITY_ID)){ $categories = $service->getMostLinkedCategories(); } // render links to most linked category page $categoriesVar = array(); foreach($categories as $category => $cnt) { $title = Title::newFromText($category, NS_CATEGORY); if($title) { $categoriesVar[] = Wikia::link($title, $title->getText()); } } $this->categories = $categoriesVar; // get info about current revision and list of authors of recent five edits $this->revisions = $this->getRecentRevisions(); // mainpage? if (WikiaPageType::isMainPage()) { $this->isMainPage = true; } // number of pages on this wiki $this->tallyMsg = wfMsgExt('oasis-total-articles-mainpage', array( 'parsemag' ), SiteStats::articles() ); } // remove namespaces prefix from title $namespaces = array(NS_MEDIAWIKI, NS_TEMPLATE, NS_CATEGORY, NS_FILE); if (defined('NS_VIDEO')) { $namespaces[] = NS_VIDEO; } if ( in_array($ns, array_merge( $namespaces, $wgSuppressNamespacePrefix ) ) ) { $this->title = $wgTitle->getText(); $this->displaytitle = false; } // talk pages if ($wgTitle->isTalkPage()) { // remove comments & FB like button $this->comments = false; // Talk: <page name without namespace prefix> $this->displaytitle = true; $this->title = Xml::element('strong', array(), $wgContLang->getNsText(NS_TALK) . ':'); $this->title .= htmlspecialchars($wgTitle->getText()); // back to subject article link switch($ns) { case NS_TEMPLATE_TALK: $msgKey = 'oasis-page-header-back-to-template'; break; case NS_MEDIAWIKI_TALK: $msgKey = 'oasis-page-header-back-to-mediawiki'; break; case NS_CATEGORY_TALK: $msgKey = 'oasis-page-header-back-to-category'; break; case NS_FILE_TALK: $msgKey = 'oasis-page-header-back-to-file'; break; default: $msgKey = 'oasis-page-header-back-to-article'; } $this->pageTalkSubject = Wikia::link($wgTitle->getSubjectPage(), wfMsg($msgKey), array('accesskey' => 'c')); } // category pages if ($ns == NS_CATEGORY) { // hide revisions / categories bar $this->categories = false; $this->revisions = false; } // forum namespace if ($ns == NS_FORUM) { // remove comments button $this->comments = false; // remove namespace prefix $this->title = $wgTitle->getText(); $this->displaytitle = false; } // mainpage if (WikiaPageType::isMainPage()) { // change page title to just "Home" $this->title = wfMsg('oasis-home'); // hide revisions / categories bar $this->categories = false; $this->revisions = false; } // render page type info switch($ns) { case NS_MEDIAWIKI: $this->pageType = wfMsg('oasis-page-header-subtitle-mediawiki'); break; case NS_TEMPLATE: $this->pageType = wfMsg('oasis-page-header-subtitle-template'); break; case NS_SPECIAL: $this->pageType = wfMsg('oasis-page-header-subtitle-special'); // remove comments button (fix FB#3404 - Marooned) $this->comments = false; // FIXME: use PageHeaderIndexAfterExecute hook or $wgSupressPageSubtitle instead if($wgTitle->isSpecial('PageLayoutBuilderForm') || $wgTitle->isSpecial('PageLayoutBuilder') ) { $this->displaytitle = true; $this->pageType = ""; } if($wgTitle->isSpecial('Newimages')) { $this->isNewFiles = true; } if($wgTitle->isSpecial('Videos')) { $this->isSpecialVideos = true; $mediaService = F::build( 'MediaQueryService' ); $this->tallyMsg = wfMsgExt('specialvideos-wiki-videos-tally', array( 'parsemag' ), $mediaService->getTotalVideos() ); } break; case NS_CATEGORY: $this->pageType = wfMsg('oasis-page-header-subtitle-category'); break; case NS_FORUM: $this->pageType = wfMsg('oasis-page-header-subtitle-forum'); break; } // render subpage info $this->pageSubject = $skin->subPageSubtitle(); if ( in_array($wgTitle->getNamespace(), BodyController::getUserPagesNamespaces() ) ) { $title = explode(':', $this->title); if(count($title) >= 2 && $wgTitle->getNsText() == str_replace(' ', '_', $title[0]) ) // in case of error page (showErrorPage) $title is just a string (cannot explode it) $this->title = $title[1]; } // render MW subtitle (contains old revision data) $this->subtitle = $wgOut->getSubtitle(); // render redirect info (redirected from) if (!empty($wgArticle->mRedirectedFrom)) { $this->pageRedirect = trim($this->subtitle, '()'); $this->subtitle = ''; } // render redirect page (redirect to) if ($wgTitle->isRedirect()) { $this->pageType = $this->subtitle; $this->subtitle = ''; } // if page is rendered using one column layout, show search box as a part of page header $this->showSearchBox = isset($params['showSearchBox']) ? $params['showSearchBox'] : false ; if (!empty($wgSupressPageTitle)) { $this->title = ''; $this->subtitle = ''; } if (!empty($wgSupressPageSubtitle)) { $this->subtitle = ''; $this->pageSubtitle = ''; } else { // render pageType, pageSubject and pageSubtitle as one message $subtitle = array_filter(array( $this->pageType, $this->pageTalkSubject, $this->pageSubject, $this->pageRedirect, )); /* * support for language variants * this adds links which automatically convert the content to that variant * * @author tor@wikia-inc.com */ if ( $wgContLang->hasVariants() ) { foreach ( $wgContLang->getVariants() as $variant ) { if ( $variant != $wgContLang->getCode() ) { $subtitle[] = Xml::element( 'a', array( 'href' => $wgTitle->getLocalUrl( array( 'variant' => $variant ) ), 'rel' => 'nofollow' ), $wgContLang->getVariantname( $variant ) ); } } } $pipe = wfMsg('pipe-separator'); $this->pageSubtitle = implode(" {$pipe} ", $subtitle); } // force AjaxLogin popup for "Add a page" button (moved from the template) $this->loginClass = !empty($this->wg->DisableAnonymousEditing) ? ' require-login' : ''; if ( $this->wg->OasisNavV2 && $response instanceof WikiaResponse ) { $response->getView()->setTemplatePath( dirname( __FILE__ ) .'/templates/PageHeader_IndexV2.php' ); } wfProfileOut(__METHOD__); }