/**
  * @see ValueFormatter::format
  *
  * @param string $conceptUri
  *
  * @throws InvalidArgumentException
  * @return string|null Null if the concept URI refers to a unitless unit. Otherwise a label or
  * an entity ID or the original concept URI.
  */
 public function format($conceptUri)
 {
     if (!is_string($conceptUri)) {
         throw new InvalidArgumentException('$conceptUri must be a string');
     }
     if (array_key_exists($conceptUri, $this->unitlessUnitIds)) {
         return null;
     }
     try {
         $entityId = $this->externalEntityIdParser->parse($conceptUri);
         try {
             // TODO: Ideally we would show unit *symbols*, taking from a config file,
             // a system message, or a statement on the unit's item.
             $term = $this->labelLookup->getLabel($entityId);
         } catch (LabelDescriptionLookupException $ex) {
             $term = null;
         }
         if ($term !== null) {
             return $term->getText();
         } else {
             // Fall back to the entity ID.
             return $entityId->getSerialization();
         }
     } catch (EntityIdParsingException $ex) {
         // Fall back to the raw concept URI.
         return $conceptUri;
     }
 }
 /**
  * @see StringValueParser::stringParse
  *
  * @since 0.4
  *
  * @param string $value
  *
  * @throws ParseException
  * @return EntityIdValue
  */
 protected function stringParse($value)
 {
     try {
         return new EntityIdValue($this->parser->parse($value));
     } catch (EntityIdParsingException $ex) {
         throw new ParseException($ex->getMessage(), $value, self::FORMAT_NAME);
     }
 }
 /**
  * Parses the given string into an EntityId by first stripping a fixed prefix.
  * If the string does not start with the expected prefix, an EntityIdParsingException
  * is thrown.
  *
  * @param string $idSerialization An entity ID with some prefix attached, e.g. an entity URI.
  *
  * @throws EntityIdParsingException If the string does not start with the expected prefix,
  *         or the remaining suffix is not a valid entity ID string.
  * @return EntityId
  */
 public function parse($idSerialization)
 {
     $prefixLength = strlen($this->prefix);
     if (strncmp($idSerialization, $this->prefix, $prefixLength) !== 0) {
         throw new EntityIdParsingException('Missing expected prefix "' . $this->prefix . '" in "' . $idSerialization . '"');
     }
     $idSerialization = substr($idSerialization, $prefixLength);
     return $this->idParser->parse($idSerialization);
 }
 /**
  * @see Deserializer::deserialize
  *
  * @param string $serialization
  *
  * @throws DeserializationException
  * @return EntityId
  */
 public function deserialize($serialization)
 {
     $this->assertEntityIdIsString($serialization);
     try {
         return $this->entityIdParser->parse($serialization);
     } catch (EntityIdParsingException $e) {
         throw new DeserializationException("'{$serialization}' is not a valid entity ID", $e);
     }
 }
 private function parseResult(array $result, $search)
 {
     $search = $this->cleanLabel($search);
     $results = $this->filterResults($result['search'], $search);
     $entityIds = array();
     foreach ($results as $entry) {
         $entityIds[] = $this->entityIdParser->parse($entry['id']);
     }
     return $entityIds;
 }
 /**
  * @param string $name
  *
  * @return EntityId|null
  * @throws UserInputException
  */
 private function getEntityIdParam($name)
 {
     $rawId = $this->getTextParam($name);
     if ($rawId === '') {
         return null;
     }
     try {
         return $this->idParser->parse($rawId);
     } catch (EntityIdParsingException $ex) {
         throw new UserInputException('wikibase-wikibaserepopage-invalid-id', array($rawId), 'Entity id is not valid');
     }
 }
 private function propertyMatchesFilter(EntityId $propertyId)
 {
     if (isset($this->requestParams['property'])) {
         try {
             $parsedProperty = $this->idParser->parse($this->requestParams['property']);
         } catch (EntityIdParsingException $e) {
             $this->errorReporter->dieException($e, 'param-invalid');
         }
         /** @var EntityId $parsedProperty */
         return $propertyId->equals($parsedProperty);
     }
     return true;
 }
 /**
  * @see ApiBase::execute()
  */
 public function execute()
 {
     $params = $this->extractRequestParams();
     $bot = $this->getUser()->isAllowed('bot') && $params['bot'];
     try {
         $fromId = $this->idParser->parse($params['from']);
         $toId = $this->idParser->parse($params['to']);
         $this->createRedirect($fromId, $toId, $bot, $this->getResult());
     } catch (EntityIdParsingException $ex) {
         $this->errorReporter->dieException($ex, 'invalid-entity-id');
     } catch (RedirectCreationException $ex) {
         $this->handleRedirectCreationException($ex);
     }
 }
 /**
  * @since 0.4
  *
  * @param Title $title
  * @param string $action
  * @param bool $hasLangLinks
  * @param string[]|null $noExternalLangLinks
  * @param string|null $prefixedId
  *
  * @return string|null HTML or null for no link
  */
 public function getLink(Title $title, $action, $hasLangLinks, array $noExternalLangLinks = null, $prefixedId)
 {
     if ($this->canHaveLink($title, $action, $noExternalLangLinks)) {
         $entityId = null;
         if (is_string($prefixedId)) {
             $entityId = $this->entityIdParser->parse($prefixedId);
         }
         if ($entityId && $hasLangLinks) {
             return $this->getEditLinksLink($entityId);
         }
         return $this->getAddLinksLink($title, $entityId);
     }
     return null;
 }
 /**
  * @see EntityIdLookup::getEntityIds
  *
  * @param Title[] $titles
  *
  * @return EntityId[]
  */
 public function getEntityIds(array $titles)
 {
     $db = $this->loadBalancer->getConnection(DB_SLAVE);
     $pageIds = array_map(function (Title $title) {
         return $title->getArticleID();
     }, $titles);
     $res = $db->select('page_props', array('pp_page', 'pp_value'), array('pp_page' => $pageIds, 'pp_propname' => 'wikibase_item'), __METHOD__);
     $entityIds = array();
     foreach ($res as $row) {
         $entityIds[$row->pp_page] = $this->idParser->parse($row->pp_value);
     }
     $this->loadBalancer->reuseConnection($db);
     return $entityIds;
 }
 /**
  * @param string $serialization
  *
  * @return StatementGuid
  * @throws StatementGuidParsingException
  */
 public function parse($serialization)
 {
     if (!is_string($serialization)) {
         throw new StatementGuidParsingException('$serialization must be a string; got ' . gettype($serialization));
     }
     $keyParts = explode(StatementGuid::SEPARATOR, $serialization);
     if (count($keyParts) !== 2) {
         throw new StatementGuidParsingException('$serialization does not have the correct number of parts');
     }
     try {
         return new StatementGuid($this->entityIdParser->parse($keyParts[0]), $keyParts[1]);
     } catch (EntityIdParsingException $ex) {
         throw new StatementGuidParsingException('$serialization contains invalid EntityId: ' . $ex->getMessage());
     }
 }
 /**
  * @see ValueValidator::validate()
  *
  * @param string $value The value to validate
  *
  * @return Result
  */
 public function validate($value)
 {
     $result = Result::newSuccess();
     try {
         $entityId = $this->idParser->parse($value);
         if ($this->forbiddenTypes === null || in_array($entityId->getEntityType(), $this->forbiddenTypes)) {
             // The label looks like a valid ID - we don't like that!
             $error = Error::newError('Looks like an Entity ID: ' . $value, null, $this->errorCode, array($value));
             $result = Result::newError(array($error));
         }
     } catch (EntityIdParsingException $parseException) {
         // All fine, the parsing did not work, so there is no entity id :)
     }
     return $result;
 }
 /**
  * @see ApiBase::execute
  *
  * @since 0.3
  */
 public function execute()
 {
     $params = $this->extractRequestParams();
     $this->validateParameters($params);
     list($idString, $guid) = $this->getIdentifiers($params);
     try {
         $entityId = $this->idParser->parse($idString);
     } catch (EntityIdParsingException $e) {
         $this->errorReporter->dieException($e, 'param-invalid');
     }
     /** @var EntityId $entityId */
     $entityRevision = $this->entityLoadingHelper->loadEntityRevision($entityId, EntityRevisionLookup::LATEST_FROM_SLAVE);
     $entity = $entityRevision->getEntity();
     $statements = $this->getStatements($entity, $guid);
     $this->resultBuilder->addStatements($statements, null, $params['props']);
 }
 /**
  * Gets an EntityId object from a string (with error handling)
  *
  * @param string $entityId
  *
  * @return EntityId
  * @throws InvalidArgumentException
  */
 private function getEntityIdFromString($entityId)
 {
     if (!is_string($entityId)) {
         throw new InvalidArgumentException('The first argument must be an entity ID encoded as a string');
     }
     return $this->entityIdParser->parse($entityId);
 }
 /**
  * @dataProvider provideGetCacheableUrls
  */
 public function testGetCacheableUrls($id, $expected)
 {
     $id = $this->idParser->parse($id);
     $uriManager = $this->makeUriManager();
     $actual = $uriManager->getCacheableUrls($id);
     $this->assertEquals($expected, $actual);
 }
 /**
  * @param string $name
  *
  * @return ItemId|null
  * @throws UserInputException
  */
 private function getItemIdParam($name)
 {
     $rawId = $this->getTextParam($name);
     if ($rawId === '') {
         return null;
     }
     try {
         $id = $this->idParser->parse($rawId);
         if (!$id instanceof ItemId) {
             throw new UserInputException('wikibase-itemmerge-not-item', array($name), 'Id does not refer to an item: ' . $name);
         }
         return $id;
     } catch (EntityIdParsingException $ex) {
         throw new UserInputException('wikibase-wikibaserepopage-invalid-id', array($rawId), 'Entity id is not valid');
     }
 }
 /**
  * @param array $document
  * @return EntityId
  * @throws EntityIdParsingException
  */
 public function buildEntityIdForDocument(array $document)
 {
     if (!array_key_exists('_id', $document)) {
         throw new EntityIdParsingException();
     }
     return $this->entityIdParser->parse($document['_id']);
 }
 /**
  * @param OutputPage $out
  *
  * @return EntityId|null
  */
 public function getEntityIdFromOutputPage(OutputPage $out)
 {
     if (!$this->entityContentFactory->isEntityContentModel($out->getTitle()->getContentModel())) {
         return null;
     }
     $jsConfigVars = $out->getJsConfigVars();
     if (array_key_exists('wbEntityId', $jsConfigVars)) {
         $idString = $jsConfigVars['wbEntityId'];
         try {
             return $this->entityIdParser->parse($idString);
         } catch (EntityIdParsingException $ex) {
             wfLogWarning('Failed to parse EntityId config var: ' . $idString);
         }
     }
     return null;
 }
 private function formatIfEntityId($value)
 {
     try {
         return $this->idFormatter->formatEntityId($this->idParser->parse($value));
     } catch (EntityIdParsingException $ex) {
         return $value;
     }
 }
 /**
  * @param string $uri
  */
 private function processUri($uri)
 {
     try {
         $entityId = $this->externalEntityIdParser->parse($uri);
         $this->entityIds[$entityId->getSerialization()] = $entityId;
     } catch (EntityIdParsingException $ex) {
         // noop
     }
 }
 /**
  * Validate the statement guid prefix is a valid entity id
  *
  * @since 0.4
  *
  * @param string $prefixedId
  *
  * @return boolean
  */
 protected function validateStatementGuidPrefix($prefixedId)
 {
     try {
         $this->entityIdParser->parse($prefixedId);
         return true;
     } catch (EntityIdParsingException $ex) {
         return false;
     }
 }
 /**
  * @param string $idString
  *
  * @return EntityId|null
  */
 private function tryParseId($idString)
 {
     try {
         return $this->entityIdParser->parse($idString);
     } catch (EntityIdParsingException $e) {
         wfDebugLog(__CLASS__, 'Invalid entity id ' . $idString);
     }
     return null;
 }
 /**
  * Parses an entity id string coming from the user
  *
  * @param string $entityIdParam
  *
  * @throws UsageException
  * @return EntityId
  * @todo this could go into an EntityModificationHelper or even in a ApiWikibaseHelper
  */
 public function getEntityIdFromString($entityIdParam)
 {
     try {
         $entityId = $this->entityIdParser->parse($entityIdParam);
     } catch (EntityIdParsingException $ex) {
         $this->errorReporter->dieException($ex, 'invalid-entity-id');
     }
     /** @var EntityId $entityId */
     return $entityId;
 }
 /**
  * @param array $data
  * @param EntityId|string|null $id
  *
  * @return object
  */
 public function unserializeEntity(array $data, $id = null)
 {
     if ($id !== null) {
         if (is_string($id)) {
             $id = $this->idParser->parse($id);
         }
         $data['id'] = $id->getSerialization();
         $data['type'] = $id->getEntityType();
     }
     $entity = $this->deserializer->deserialize($data);
     return $entity;
 }
 /**
  * @param array $data
  * @param EntityId|null $entityId
  */
 private function checkEntityId(array $data, EntityId $entityId = null)
 {
     if (isset($data['id'])) {
         if (!$entityId) {
             $this->errorReporter->dieError('Illegal field used in call: "id", must not be given when creating a new entity', 'param-illegal');
         }
         $dataId = $this->idParser->parse($data['id']);
         if (!$entityId->equals($dataId)) {
             $this->errorReporter->dieError('Invalid field used in call: "id", must match id parameter', 'param-invalid');
         }
     }
 }
 /**
  * Gets exact match for the search term as an EntityId if it can be found.
  *
  * @param string $term
  * @param string $entityType
  *
  * @return EntityId|null
  */
 private function getExactMatchForEntityId($term, $entityType)
 {
     try {
         $entityId = $this->idParser->parse($term);
         $title = $this->titleLookup->getTitleForId($entityId);
         if ($title && $title->exists() && $entityId->getEntityType() === $entityType) {
             return $entityId;
         }
     } catch (EntityIdParsingException $ex) {
         // never mind, doesn't look like an ID.
     }
     return null;
 }
 /**
  * @param ResultWrapper $res
  *
  * @return EntityId[] An associative array mapping page IDs to Entity IDs.
  */
 private function slurpEntityIds(ResultWrapper $res)
 {
     $entityPerPage = array();
     foreach ($res as $row) {
         try {
             $entityId = $this->idParser->parse($row->pp_value);
             $entityPerPage[$row->pp_page] = $entityId;
         } catch (Exception $ex) {
             $this->exceptionHandler->handleException($ex, 'badEntityId', __METHOD__ . ': ' . 'Failed to parse entity ID: ' . $row->pp_value . ' at page ' . $row->pp_page);
         }
     }
     return $entityPerPage;
 }
 /**
  * Gets the entity and increments the expensive parser function count.
  *
  * @param Parser $parser
  * @param string $entityIdString
  *
  * @return EntityId|null
  */
 private function getEntityIdFromString(Parser $parser, $entityIdString)
 {
     try {
         $entityId = $this->entityIdParser->parse($entityIdString);
     } catch (EntityIdParsingException $ex) {
         // Just ignore this
         return null;
     }
     // Getting a foreign item is expensive (unless we already loaded it and it's cached)
     if (!$this->restrictedEntityLookup->entityHasBeenAccessed($entityId)) {
         $parser->incrementExpensiveFunctionCount();
     }
     return $entityId;
 }
 /**
  * @param array $params
  * @return EntityId[]
  */
 private function getEntityIdsFromIdParam($params)
 {
     $ids = array();
     if (isset($params['ids'])) {
         foreach ($params['ids'] as $id) {
             try {
                 $ids[] = $this->idParser->parse($id);
             } catch (EntityIdParsingException $e) {
                 $this->errorReporter->dieError("Invalid id: {$id}", 'no-such-entity', 0, array('id' => $id));
             }
         }
     }
     return $ids;
 }
 /**
  * Main method for handling requests.
  *
  * @since 0.4
  *
  * @param string $doc Document name, e.g. Q5 or Q5.json or Q5:33.xml
  * @param WebRequest $request The request parameters. Known parameters are:
  *        - id: the entity ID
  *        - format: the format
  *        - oldid|revision: the revision ID
  *        - action=purge: to purge cached data from (web) caches
  * @param OutputPage $output
  *
  * @note: Instead of an output page, a WebResponse could be sufficient, but
  *        redirect logic is currently implemented in OutputPage.
  *
  * @throws HttpError
  */
 public function handleRequest($doc, WebRequest $request, OutputPage $output)
 {
     $revision = 0;
     list($id, $format) = $this->uriManager->parseDocName($doc);
     // get entity id and format from request parameter
     $format = $request->getText('format', $format);
     $id = $request->getText('id', $id);
     $revision = $request->getInt('oldid', $revision);
     $revision = $request->getInt('revision', $revision);
     //TODO: malformed revision IDs should trigger a code 400
     // If there is no ID, fail
     if ($id === null || $id === '') {
         //TODO: different error message?
         throw new HttpError(400, wfMessage('wikibase-entitydata-bad-id')->params($id));
     }
     try {
         $entityId = $this->entityIdParser->parse($id);
     } catch (EntityIdParsingException $ex) {
         throw new HttpError(400, wfMessage('wikibase-entitydata-bad-id')->params($id));
     }
     //XXX: allow for logged in users only?
     if ($request->getText('action') === 'purge') {
         $this->purgeWebCache($entityId);
         //XXX: Now what? Proceed to show the data?
     }
     if ($format === null || $format === '') {
         // if no format is given, apply content negotiation and return.
         $this->httpContentNegotiation($request, $output, $entityId, $revision);
         return;
     }
     //NOTE: will trigger a 415 if the format is not supported
     $format = $this->getCanonicalFormat($format);
     if ($doc !== null && $doc !== '') {
         // if subpage syntax is used, always enforce the canonical form
         $canonicalDoc = $this->uriManager->getDocName($entityId, $format);
         if ($doc !== $canonicalDoc) {
             $url = $this->uriManager->getDocUrl($entityId, $format, $revision);
             $output->redirect($url, 301);
             return;
         }
     }
     // if the format is HTML, redirect to the entity's wiki page
     if ($format === 'html') {
         $url = $this->uriManager->getDocUrl($entityId, 'html', $revision);
         $output->redirect($url, 303);
         return;
     }
     $this->showData($request, $output, $format, $entityId, $revision);
 }