Esempio n. 1
0
 /**
  * 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__);
 }
Esempio n. 2
0
 /**
  * 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);
 }
Esempio n. 4
0
 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;
     }
 }
Esempio n. 6
0
 /**
  * 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;
 }
Esempio n. 7
0
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;
 }
Esempio n. 9
0
 /**
  * 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__);
     }
 }
Esempio n. 10
0
 /**
  * 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;
 }
Esempio n. 11
0
/**
 * 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;
}
Esempio n. 12
0
 /**
  * @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;
 }
Esempio n. 13
0
 /**
  * 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;
 }
Esempio n. 14
0
 /**
  * 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;
 }
Esempio n. 15
0
 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__);
 }
Esempio n. 16
0
 /**
  * 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;
 }
Esempio n. 17
0
 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__);
	}