/** * @see EntityRedirectLookup::getRedirectForEntityId * * @since 0.5 * * @param EntityId $entityId * @param string $forUpdate * * @return EntityId|null The ID of the redirect target, or null if $entityId * does not refer to a redirect * @throws EntityRedirectLookupException */ public function getRedirectForEntityId(EntityId $entityId, $forUpdate = '') { try { $title = $this->entityTitleLookup->getTitleForId($entityId); } catch (\Exception $ex) { // TODO: catch more specific type of exception once EntityTitleLookup contract is clarified throw new EntityRedirectLookupException($entityId, null, $ex); } $forUpdate = $forUpdate === 'for update' ? DB_MASTER : DB_SLAVE; try { $db = $this->loadBalancer->getConnection($forUpdate); } catch (MWException $ex) { throw new EntityRedirectLookupException($entityId, null, $ex); } $row = $db->selectRow(array('page', 'redirect'), array('page_id', 'rd_namespace', 'rd_title'), array('page_title' => $title->getDBkey(), 'page_namespace' => $title->getNamespace()), __METHOD__, array(), array('redirect' => array('LEFT JOIN', 'rd_from=page_id'))); try { $this->loadBalancer->reuseConnection($db); } catch (MWException $ex) { throw new EntityRedirectLookupException($entityId, null, $ex); } if (!$row) { throw new EntityRedirectLookupException($entityId); } if ($row->rd_namespace === null) { return null; } $title = Title::makeTitle($row->rd_namespace, $row->rd_title); return $this->entityIdLookup->getEntityIdForTitle($title); }
/** * @param Title $target * @param string &$html * @param array &$customAttribs * @param RequestContext $context */ public function doOnLinkBegin(Title $target, &$html, array &$customAttribs, RequestContext $context) { $out = $context->getOutput(); if (!$this->entityNamespaceLookup->isEntityNamespace($target->getNamespace())) { return; } // Only continue on pages with edit summaries (histories / diffs) or on special pages. // Don't run this code when accessing it through the api (eg. for parsing) as the title is // set to a special page dummy in api.php, see https://phabricator.wikimedia.org/T111346 if (defined('MW_API') || !$this->shouldConvert($out->getTitle(), $context)) { return; } $targetText = $target->getText(); // Handle "fake" titles for new entities as generated by // EditEntity::getContextForEditFilter(). For instance, a link to Property:NewProperty // would be replaced by a link to Special:NewProperty. This is useful in logs, // to indicate that the logged action occurred while creating an entity. if (SpecialPageFactory::exists($targetText)) { $target = Title::makeTitle(NS_SPECIAL, $targetText); $html = Linker::linkKnown($target); return; } if (!$target->exists()) { // The link points to a non-existing item. return; } // if custom link text is given, there is no point in overwriting it // but not if it is similar to the plain title if ($html !== null && $target->getFullText() !== $html) { return; } $entityId = $this->entityIdLookup->getEntityIdForTitle($target); if (!$entityId) { return; } // @todo: this re-implements the logic in LanguageFallbackLabelDescriptionLookup, // as that didn't support descriptions back when this code was written. // NOTE: keep in sync with with fallback languages in LabelPrefetchHookHandler::newFromGlobalState try { $labels = $this->termLookup->getLabels($entityId, $this->languageFallback->getFetchLanguageCodes()); $descriptions = $this->termLookup->getDescriptions($entityId, $this->languageFallback->getFetchLanguageCodes()); } catch (StorageException $ex) { // This shouldn't happen if $target->exists() return true! return; } $labelData = $this->getPreferredTerm($labels); $descriptionData = $this->getPreferredTerm($descriptions); $html = $this->getHtml($target, $labelData); $customAttribs['title'] = $this->getTitleAttribute($target, $labelData, $descriptionData); // add wikibase styles in all cases, so we can format the link properly: $out->addModuleStyles(array('wikibase.common')); }