| @@ -27,48 +27,48 @@ | ||
| 27 | 27 | */ | 
| 28 | 28 |  class Time extends Property { | 
| 29 | 29 | |
| 30 | - /** | |
| 31 | - * @return DateTime | |
| 32 | - */ | |
| 33 | -	public function getDateTime() { | |
| 34 | - return new DateTime( $this->claim['mainsnak']['datavalue']['value']['time'] ); | |
| 35 | - } | |
| 30 | + /** | |
| 31 | + * @return DateTime | |
| 32 | + */ | |
| 33 | +    public function getDateTime() { | |
| 34 | + return new DateTime( $this->claim['mainsnak']['datavalue']['value']['time'] ); | |
| 35 | + } | |
| 36 | 36 | |
| 37 | - /** | |
| 38 | - * @return DateTimeZone | |
| 39 | - */ | |
| 40 | -	public function getTimezone() { | |
| 41 | - return new DateTimeZone( $this->claim['mainsnak']['datavalue']['value']['timezone'] ); | |
| 42 | - } | |
| 37 | + /** | |
| 38 | + * @return DateTimeZone | |
| 39 | + */ | |
| 40 | +    public function getTimezone() { | |
| 41 | + return new DateTimeZone( $this->claim['mainsnak']['datavalue']['value']['timezone'] ); | |
| 42 | + } | |
| 43 | 43 | |
| 44 | - /** | |
| 45 | - * @return mixed | |
| 46 | - */ | |
| 47 | -	public function getBefore() { | |
| 48 | - return $this->claim['mainsnak']['datavalue']['value']['before']; | |
| 49 | - } | |
| 44 | + /** | |
| 45 | + * @return mixed | |
| 46 | + */ | |
| 47 | +    public function getBefore() { | |
| 48 | + return $this->claim['mainsnak']['datavalue']['value']['before']; | |
| 49 | + } | |
| 50 | 50 | |
| 51 | - /** | |
| 52 | - * @return mixed | |
| 53 | - */ | |
| 54 | -	public function getAfter() { | |
| 55 | - return $this->claim['mainsnak']['datavalue']['value']['time']; | |
| 56 | - } | |
| 51 | + /** | |
| 52 | + * @return mixed | |
| 53 | + */ | |
| 54 | +    public function getAfter() { | |
| 55 | + return $this->claim['mainsnak']['datavalue']['value']['time']; | |
| 56 | + } | |
| 57 | 57 | |
| 58 | - /** | |
| 59 | - * @return int The numbers have the following meanings: 0 - billion years, | |
| 60 | - * 1 - hundred million years, ..., | |
| 61 | - * 6 - millennium, 7 - century, 8 - decade, 9 - year, 10 - month, 11 - day, 12 - hour, | |
| 62 | - * 13 - minute, 14 - second. | |
| 63 | - */ | |
| 64 | -	public function getPrecision() { | |
| 65 | - return $this->claim['mainsnak']['datavalue']['value']['precision']; | |
| 66 | - } | |
| 58 | + /** | |
| 59 | + * @return int The numbers have the following meanings: 0 - billion years, | |
| 60 | + * 1 - hundred million years, ..., | |
| 61 | + * 6 - millennium, 7 - century, 8 - decade, 9 - year, 10 - month, 11 - day, 12 - hour, | |
| 62 | + * 13 - minute, 14 - second. | |
| 63 | + */ | |
| 64 | +    public function getPrecision() { | |
| 65 | + return $this->claim['mainsnak']['datavalue']['value']['precision']; | |
| 66 | + } | |
| 67 | 67 | |
| 68 | - /** | |
| 69 | - * @return mixed | |
| 70 | - */ | |
| 71 | -	public function getCalendarModel() { | |
| 72 | - return $this->claim['mainsnak']['datavalue']['value']['calendarmodel']; | |
| 73 | - } | |
| 68 | + /** | |
| 69 | + * @return mixed | |
| 70 | + */ | |
| 71 | +    public function getCalendarModel() { | |
| 72 | + return $this->claim['mainsnak']['datavalue']['value']['calendarmodel']; | |
| 73 | + } | |
| 74 | 74 | } | 
| @@ -6,11 +6,11 @@ | ||
| 6 | 6 | |
| 7 | 7 |  class Item extends Property { | 
| 8 | 8 | |
| 9 | - /** | |
| 10 | - * @return \Samwilson\SimpleWikidata\Item | |
| 11 | - */ | |
| 12 | -	public function getItem() { | |
| 13 | - $itemId = $this->claim['mainsnak']['datavalue']['value']['id']; | |
| 14 | - return \Samwilson\SimpleWikidata\Item::factory( $itemId, $this->lang, $this->cache ); | |
| 15 | - } | |
| 9 | + /** | |
| 10 | + * @return \Samwilson\SimpleWikidata\Item | |
| 11 | + */ | |
| 12 | +    public function getItem() { | |
| 13 | + $itemId = $this->claim['mainsnak']['datavalue']['value']['id']; | |
| 14 | + return \Samwilson\SimpleWikidata\Item::factory( $itemId, $this->lang, $this->cache ); | |
| 15 | + } | |
| 16 | 16 | } | 
| @@ -8,78 +8,78 @@ | ||
| 8 | 8 | |
| 9 | 9 |  class Query { | 
| 10 | 10 | |
| 11 | - /** @var string */ | |
| 12 | - protected $query; | |
| 11 | + /** @var string */ | |
| 12 | + protected $query; | |
| 13 | 13 | |
| 14 | - /** @var string */ | |
| 15 | - protected $lang; | |
| 14 | + /** @var string */ | |
| 15 | + protected $lang; | |
| 16 | 16 | |
| 17 | - /** @var CacheItemPoolInterface */ | |
| 18 | - protected $cache; | |
| 17 | + /** @var CacheItemPoolInterface */ | |
| 18 | + protected $cache; | |
| 19 | 19 | |
| 20 | - /** | |
| 21 | - * Query constructor. | |
| 22 | - * @param string $query The Sparql query. | |
| 23 | - * @param string $lang The language. | |
| 24 | - * @param CacheItemPoolInterface $cache The cache. | |
| 25 | - */ | |
| 26 | -	public function __construct( $query, $lang, CacheItemPoolInterface $cache ) { | |
| 27 | - $this->query = $query; | |
| 28 | - $this->lang = $lang; | |
| 29 | - $this->cache = $cache; | |
| 30 | - } | |
| 20 | + /** | |
| 21 | + * Query constructor. | |
| 22 | + * @param string $query The Sparql query. | |
| 23 | + * @param string $lang The language. | |
| 24 | + * @param CacheItemPoolInterface $cache The cache. | |
| 25 | + */ | |
| 26 | +    public function __construct( $query, $lang, CacheItemPoolInterface $cache ) { | |
| 27 | + $this->query = $query; | |
| 28 | + $this->lang = $lang; | |
| 29 | + $this->cache = $cache; | |
| 30 | + } | |
| 31 | 31 | |
| 32 | - /** | |
| 33 | - * Get the items. | |
| 34 | - * @return Item[] The results. | |
| 35 | - */ | |
| 36 | -	public function getItems() { | |
| 37 | - $xml = $this->getXml( $this->query ); | |
| 38 | - $results = []; | |
| 39 | -		foreach ( $xml->results->result as $res ) { | |
| 40 | - $result = $this->getBindings( $res ); | |
| 41 | - $id = substr( $result['item'], strrpos( $result['item'], '/' ) + 1 ); | |
| 42 | - $item = Item::factory( $id, $this->lang, $this->cache ); | |
| 43 | - $results[] = $item; | |
| 44 | - } | |
| 45 | - return $results; | |
| 46 | - } | |
| 32 | + /** | |
| 33 | + * Get the items. | |
| 34 | + * @return Item[] The results. | |
| 35 | + */ | |
| 36 | +    public function getItems() { | |
| 37 | + $xml = $this->getXml( $this->query ); | |
| 38 | + $results = []; | |
| 39 | +        foreach ( $xml->results->result as $res ) { | |
| 40 | + $result = $this->getBindings( $res ); | |
| 41 | + $id = substr( $result['item'], strrpos( $result['item'], '/' ) + 1 ); | |
| 42 | + $item = Item::factory( $id, $this->lang, $this->cache ); | |
| 43 | + $results[] = $item; | |
| 44 | + } | |
| 45 | + return $results; | |
| 46 | + } | |
| 47 | 47 | |
| 48 | - /** | |
| 49 | - * @param string $query The Sparql query. | |
| 50 | - * @return SimpleXmlElement | |
| 51 | - * @throws Exception | |
| 52 | - */ | |
| 53 | -	protected function getXml( $query ) { | |
| 54 | - $url = "https://query.wikidata.org/bigdata/namespace/wdq/sparql?query=" . urlencode( $query ); | |
| 55 | -		try { | |
| 56 | - $result = file_get_contents( $url ); | |
| 57 | -		} catch ( Exception $e ) { | |
| 58 | - throw new Exception( "Unable to run query: <pre>" . htmlspecialchars( $query ) . "</pre>", 500 ); | |
| 59 | - } | |
| 60 | -		if ( empty( $result ) ) { | |
| 61 | - $msg = "No result from query: <pre>" . htmlspecialchars( $query ) . "</pre>"; | |
| 62 | - throw new Exception( $msg, 500 ); | |
| 63 | - } | |
| 64 | - $xml = new SimpleXmlElement( $result ); | |
| 65 | - return $xml; | |
| 66 | - } | |
| 48 | + /** | |
| 49 | + * @param string $query The Sparql query. | |
| 50 | + * @return SimpleXmlElement | |
| 51 | + * @throws Exception | |
| 52 | + */ | |
| 53 | +    protected function getXml( $query ) { | |
| 54 | + $url = "https://query.wikidata.org/bigdata/namespace/wdq/sparql?query=" . urlencode( $query ); | |
| 55 | +        try { | |
| 56 | + $result = file_get_contents( $url ); | |
| 57 | +        } catch ( Exception $e ) { | |
| 58 | + throw new Exception( "Unable to run query: <pre>" . htmlspecialchars( $query ) . "</pre>", 500 ); | |
| 59 | + } | |
| 60 | +        if ( empty( $result ) ) { | |
| 61 | + $msg = "No result from query: <pre>" . htmlspecialchars( $query ) . "</pre>"; | |
| 62 | + throw new Exception( $msg, 500 ); | |
| 63 | + } | |
| 64 | + $xml = new SimpleXmlElement( $result ); | |
| 65 | + return $xml; | |
| 66 | + } | |
| 67 | 67 | |
| 68 | - /** | |
| 69 | - * @param SimpleXmlElement $xml The query result XML. | |
| 70 | - * @return array | |
| 71 | - */ | |
| 72 | -	protected function getBindings( $xml ) { | |
| 73 | - $out = []; | |
| 74 | -		foreach ( $xml->binding as $binding ) { | |
| 75 | -			if ( isset( $binding->literal ) ) { | |
| 76 | - $out[(string)$binding['name']] = (string)$binding->literal; | |
| 77 | - } | |
| 78 | -			if ( isset( $binding->uri ) ) { | |
| 79 | - $out[(string)$binding['name']] = (string)$binding->uri; | |
| 80 | - } | |
| 81 | - } | |
| 82 | - return $out; | |
| 83 | - } | |
| 68 | + /** | |
| 69 | + * @param SimpleXmlElement $xml The query result XML. | |
| 70 | + * @return array | |
| 71 | + */ | |
| 72 | +    protected function getBindings( $xml ) { | |
| 73 | + $out = []; | |
| 74 | +        foreach ( $xml->binding as $binding ) { | |
| 75 | +            if ( isset( $binding->literal ) ) { | |
| 76 | + $out[(string)$binding['name']] = (string)$binding->literal; | |
| 77 | + } | |
| 78 | +            if ( isset( $binding->uri ) ) { | |
| 79 | + $out[(string)$binding['name']] = (string)$binding->uri; | |
| 80 | + } | |
| 81 | + } | |
| 82 | + return $out; | |
| 83 | + } | |
| 84 | 84 | |
| 85 | 85 | } | 
| @@ -6,37 +6,37 @@ | ||
| 6 | 6 | |
| 7 | 7 |  class Reference { | 
| 8 | 8 | |
| 9 | - const STATED_IN = 'P248'; | |
| 10 | - | |
| 11 | - /** @var array */ | |
| 12 | - protected $data; | |
| 13 | - | |
| 14 | - /** @var string */ | |
| 15 | - protected $lang; | |
| 16 | - | |
| 17 | - /** @var CacheItemPoolInterface */ | |
| 18 | - protected $cache; | |
| 19 | - | |
| 20 | - /** | |
| 21 | - * @param string[] $data The data. | |
| 22 | - * @param string $lang ISO639 language code. | |
| 23 | - * @param CacheItemPoolInterface $cache The cache. | |
| 24 | - */ | |
| 25 | -	public function __construct( $data, $lang, $cache ) { | |
| 26 | - $this->data = $data; | |
| 27 | - $this->lang = $lang; | |
| 28 | - $this->cache = $cache; | |
| 29 | - } | |
| 30 | - | |
| 31 | - /** | |
| 32 | - * @return Item|bool The item, or false if there isn't one. | |
| 33 | - */ | |
| 34 | -	public function statedIn() { | |
| 35 | -		if ( !isset( $this->data['snaks'][self::STATED_IN] ) ) { | |
| 36 | - return false; | |
| 37 | - } | |
| 38 | -		foreach ( $this->data['snaks'][self::STATED_IN] as $snak ) { | |
| 39 | - return Item::factory( $snak['datavalue']['value']['id'], $this->lang, $this->cache ); | |
| 40 | - } | |
| 41 | - } | |
| 9 | + const STATED_IN = 'P248'; | |
| 10 | + | |
| 11 | + /** @var array */ | |
| 12 | + protected $data; | |
| 13 | + | |
| 14 | + /** @var string */ | |
| 15 | + protected $lang; | |
| 16 | + | |
| 17 | + /** @var CacheItemPoolInterface */ | |
| 18 | + protected $cache; | |
| 19 | + | |
| 20 | + /** | |
| 21 | + * @param string[] $data The data. | |
| 22 | + * @param string $lang ISO639 language code. | |
| 23 | + * @param CacheItemPoolInterface $cache The cache. | |
| 24 | + */ | |
| 25 | +    public function __construct( $data, $lang, $cache ) { | |
| 26 | + $this->data = $data; | |
| 27 | + $this->lang = $lang; | |
| 28 | + $this->cache = $cache; | |
| 29 | + } | |
| 30 | + | |
| 31 | + /** | |
| 32 | + * @return Item|bool The item, or false if there isn't one. | |
| 33 | + */ | |
| 34 | +    public function statedIn() { | |
| 35 | +        if ( !isset( $this->data['snaks'][self::STATED_IN] ) ) { | |
| 36 | + return false; | |
| 37 | + } | |
| 38 | +        foreach ( $this->data['snaks'][self::STATED_IN] as $snak ) { | |
| 39 | + return Item::factory( $snak['datavalue']['value']['id'], $this->lang, $this->cache ); | |
| 40 | + } | |
| 41 | + } | |
| 42 | 42 | } | 
| @@ -9,56 +9,56 @@ | ||
| 9 | 9 | */ | 
| 10 | 10 |  class Human extends Item { | 
| 11 | 11 | |
| 12 | - const PROP_DATE_OF_BIRTH = 'P569'; | |
| 13 | - const PROP_PLACE_OF_BIRTH = 'P19'; | |
| 12 | + const PROP_DATE_OF_BIRTH = 'P569'; | |
| 13 | + const PROP_PLACE_OF_BIRTH = 'P19'; | |
| 14 | 14 | |
| 15 | - const PROP_DATE_OF_DEATH = 'P570'; | |
| 16 | - const PROP_PLACE_OF_DEATH = 'P20'; | |
| 15 | + const PROP_DATE_OF_DEATH = 'P570'; | |
| 16 | + const PROP_PLACE_OF_DEATH = 'P20'; | |
| 17 | 17 | |
| 18 | - const PROP_FATHER = 'P22'; | |
| 19 | - const PROP_MOTHER = 'P25'; | |
| 20 | - const PROP_SPOUSE = 'P26'; | |
| 21 | - const PROP_CHILD = 'P40'; | |
| 18 | + const PROP_FATHER = 'P22'; | |
| 19 | + const PROP_MOTHER = 'P25'; | |
| 20 | + const PROP_SPOUSE = 'P26'; | |
| 21 | + const PROP_CHILD = 'P40'; | |
| 22 | 22 | |
| 23 | - /** | |
| 24 | - * @return bool|\Samwilson\SimpleWikidata\Properties\Time[] | |
| 25 | - */ | |
| 26 | -	public function getDatesOfBirth() { | |
| 27 | - return $this->getPropertyOfTypeTime( self::PROP_DATE_OF_BIRTH ); | |
| 28 | - } | |
| 23 | + /** | |
| 24 | + * @return bool|\Samwilson\SimpleWikidata\Properties\Time[] | |
| 25 | + */ | |
| 26 | +    public function getDatesOfBirth() { | |
| 27 | + return $this->getPropertyOfTypeTime( self::PROP_DATE_OF_BIRTH ); | |
| 28 | + } | |
| 29 | 29 | |
| 30 | - /** | |
| 31 | - * @return bool|\Samwilson\SimpleWikidata\Properties\Time[] | |
| 32 | - */ | |
| 33 | -	public function getDatesOfDeath() { | |
| 34 | - return $this->getPropertyOfTypeTime( self::PROP_DATE_OF_DEATH ); | |
| 35 | - } | |
| 30 | + /** | |
| 31 | + * @return bool|\Samwilson\SimpleWikidata\Properties\Time[] | |
| 32 | + */ | |
| 33 | +    public function getDatesOfDeath() { | |
| 34 | + return $this->getPropertyOfTypeTime( self::PROP_DATE_OF_DEATH ); | |
| 35 | + } | |
| 36 | 36 | |
| 37 | - /** | |
| 38 | - * @return \Samwilson\SimpleWikidata\Properties\Item[] | |
| 39 | - */ | |
| 40 | -	public function fathers() { | |
| 41 | - return $this->getPropertyOfTypeItem( self::PROP_FATHER ); | |
| 42 | - } | |
| 37 | + /** | |
| 38 | + * @return \Samwilson\SimpleWikidata\Properties\Item[] | |
| 39 | + */ | |
| 40 | +    public function fathers() { | |
| 41 | + return $this->getPropertyOfTypeItem( self::PROP_FATHER ); | |
| 42 | + } | |
| 43 | 43 | |
| 44 | - /** | |
| 45 | - * @return \Samwilson\SimpleWikidata\Properties\Item[] | |
| 46 | - */ | |
| 47 | -	public function mothers() { | |
| 48 | - return $this->getPropertyOfTypeItem( self::PROP_FATHER ); | |
| 49 | - } | |
| 44 | + /** | |
| 45 | + * @return \Samwilson\SimpleWikidata\Properties\Item[] | |
| 46 | + */ | |
| 47 | +    public function mothers() { | |
| 48 | + return $this->getPropertyOfTypeItem( self::PROP_FATHER ); | |
| 49 | + } | |
| 50 | 50 | |
| 51 | - /** | |
| 52 | - * @return \Samwilson\SimpleWikidata\Properties\Item[] | |
| 53 | - */ | |
| 54 | -	public function spouses() { | |
| 55 | - return $this->getPropertyOfTypeItem( self::PROP_SPOUSE ); | |
| 56 | - } | |
| 51 | + /** | |
| 52 | + * @return \Samwilson\SimpleWikidata\Properties\Item[] | |
| 53 | + */ | |
| 54 | +    public function spouses() { | |
| 55 | + return $this->getPropertyOfTypeItem( self::PROP_SPOUSE ); | |
| 56 | + } | |
| 57 | 57 | |
| 58 | - /** | |
| 59 | - * @return \Samwilson\SimpleWikidata\Properties\Item[] | |
| 60 | - */ | |
| 61 | -	public function children() { | |
| 62 | - return $this->getPropertyOfTypeItem( self::PROP_CHILD ); | |
| 63 | - } | |
| 58 | + /** | |
| 59 | + * @return \Samwilson\SimpleWikidata\Properties\Item[] | |
| 60 | + */ | |
| 61 | +    public function children() { | |
| 62 | + return $this->getPropertyOfTypeItem( self::PROP_CHILD ); | |
| 63 | + } | |
| 64 | 64 | } | 
| @@ -8,44 +8,44 @@ | ||
| 8 | 8 | |
| 9 | 9 |  class Search { | 
| 10 | 10 | |
| 11 | - /** @var string */ | |
| 12 | - protected $lang; | |
| 11 | + /** @var string */ | |
| 12 | + protected $lang; | |
| 13 | 13 | |
| 14 | - /** @var CacheItemPoolInterface */ | |
| 15 | - protected $cache; | |
| 14 | + /** @var CacheItemPoolInterface */ | |
| 15 | + protected $cache; | |
| 16 | 16 | |
| 17 | - /** | |
| 18 | - * Search constructor. | |
| 19 | - * @param string $searchTerm What to search for. | |
| 20 | - * @param string $lang Language to use for the search results. | |
| 21 | - * @param CacheItemPoolInterface $cache The cache to use. | |
| 22 | - */ | |
| 23 | -	public function __construct( $searchTerm, $lang, CacheItemPoolInterface $cache ) { | |
| 24 | - $this->searchTerm = $searchTerm; | |
| 25 | - $this->lang = $lang; | |
| 26 | - $this->cache = $cache; | |
| 27 | - } | |
| 17 | + /** | |
| 18 | + * Search constructor. | |
| 19 | + * @param string $searchTerm What to search for. | |
| 20 | + * @param string $lang Language to use for the search results. | |
| 21 | + * @param CacheItemPoolInterface $cache The cache to use. | |
| 22 | + */ | |
| 23 | +    public function __construct( $searchTerm, $lang, CacheItemPoolInterface $cache ) { | |
| 24 | + $this->searchTerm = $searchTerm; | |
| 25 | + $this->lang = $lang; | |
| 26 | + $this->cache = $cache; | |
| 27 | + } | |
| 28 | 28 | |
| 29 | - /** | |
| 30 | - * @param string $limit The number of search results to return. | |
| 31 | - * @return Item[] | |
| 32 | - */ | |
| 33 | -	public function getItems( $limit = 'max' ) { | |
| 34 | - $api = MediawikiApi::newFromApiEndpoint( 'https://www.wikidata.org/w/api.php' ); | |
| 35 | - $req = FluentRequest::factory() | |
| 36 | - ->setAction( 'wbsearchentities' ) | |
| 37 | - ->addParams( [ | |
| 38 | - 'search' => $this->searchTerm, | |
| 39 | - 'type' => 'item', | |
| 40 | - 'limit' => $limit, | |
| 41 | - 'language' => 'en', | |
| 42 | - ] ); | |
| 43 | - $results = []; | |
| 44 | - $response = $api->getRequest( $req ); | |
| 45 | -		foreach ( $response['search'] as $info ) { | |
| 46 | - $item = Item::factory( $info['id'], $this->lang, $this->cache ); | |
| 47 | - $results[] = $item; | |
| 48 | - } | |
| 49 | - return $results; | |
| 50 | - } | |
| 29 | + /** | |
| 30 | + * @param string $limit The number of search results to return. | |
| 31 | + * @return Item[] | |
| 32 | + */ | |
| 33 | +    public function getItems( $limit = 'max' ) { | |
| 34 | + $api = MediawikiApi::newFromApiEndpoint( 'https://www.wikidata.org/w/api.php' ); | |
| 35 | + $req = FluentRequest::factory() | |
| 36 | + ->setAction( 'wbsearchentities' ) | |
| 37 | + ->addParams( [ | |
| 38 | + 'search' => $this->searchTerm, | |
| 39 | + 'type' => 'item', | |
| 40 | + 'limit' => $limit, | |
| 41 | + 'language' => 'en', | |
| 42 | + ] ); | |
| 43 | + $results = []; | |
| 44 | + $response = $api->getRequest( $req ); | |
| 45 | +        foreach ( $response['search'] as $info ) { | |
| 46 | + $item = Item::factory( $info['id'], $this->lang, $this->cache ); | |
| 47 | + $results[] = $item; | |
| 48 | + } | |
| 49 | + return $results; | |
| 50 | + } | |
| 51 | 51 | } | 
| @@ -12,180 +12,180 @@ discard block | ||
| 12 | 12 | |
| 13 | 13 |  class Item { | 
| 14 | 14 | |
| 15 | - /** @var string|bool */ | |
| 16 | - const INSTANCE_OF = false; | |
| 17 | - | |
| 18 | - const PROP_INSTANCE_OF = 'P31'; | |
| 19 | - const PROP_TITLE = 'P1476'; | |
| 20 | - const PROP_IMAGE = 'P18'; | |
| 21 | - const PROP_AUTHOR = 'P50'; | |
| 22 | - | |
| 23 | - /** @var string[] List of Q-numbers of registered classes. */ | |
| 24 | - protected static $registeredClasses = []; | |
| 25 | - | |
| 26 | - /** @var string */ | |
| 27 | - protected $id; | |
| 28 | - | |
| 29 | - /** @var MediawikiApi */ | |
| 30 | - protected $wdApi; | |
| 31 | - | |
| 32 | - /** @var string */ | |
| 33 | - protected $lang; | |
| 34 | - | |
| 35 | - /** @var CacheItemPoolInterface */ | |
| 36 | - protected $cache; | |
| 37 | - | |
| 38 | - /** @var string The base URL of Wikidata, with trailing slash. */ | |
| 39 | - protected $wikidataUrlBase = 'https://www.wikidata.org/wiki/'; | |
| 40 | - | |
| 41 | -	private function __construct( $id, $lang, CacheItemPoolInterface $cache ) { | |
| 42 | -		if ( !is_string( $id ) || preg_match( '/[QP][0-9]*/i', $id ) !== 1 ) { | |
| 43 | - throw new Exception( "Not a valid ID: " . var_export( $id, true ) ); | |
| 44 | - } | |
| 45 | - $this->id = $id; | |
| 46 | - $this->wdApi = new MediawikiApi( 'https://www.wikidata.org/w/api.php' ); | |
| 47 | - $this->entities = []; | |
| 48 | - $this->lang = $lang; | |
| 49 | - $this->cache = $cache; | |
| 50 | - } | |
| 51 | - | |
| 52 | - /** | |
| 53 | - * Create a new Item object with class based on the item's 'instance of' statement. | |
| 54 | - * | |
| 55 | - * @param string $id The item ID (Q-number). | |
| 56 | - * @param string $lang The language code. | |
| 57 | - * @param CacheItemPoolInterface $cache The cache to use. | |
| 58 | - * @return Item | |
| 59 | - */ | |
| 60 | -	public static function factory( $id, $lang, CacheItemPoolInterface $cache ) { | |
| 61 | - $item = new Item( $id, $lang, $cache ); | |
| 62 | -		foreach ( $item->getPropertyOfTypeItem( self::PROP_INSTANCE_OF ) as $instanceOf ) { | |
| 63 | - // Try to find a class matching the registered 'instance of'. | |
| 64 | -			foreach ( static::$registeredClasses as $classId => $className ) { | |
| 65 | - // If this 'instance of' is registered, use it. | |
| 66 | -				if ( $classId === $instanceOf->getItem()->getId() ) { | |
| 67 | - // This won't re-request the metadata, because that's cached. | |
| 68 | - return new $className( $id, $lang, $cache ); | |
| 69 | - } | |
| 70 | - } | |
| 71 | - } | |
| 72 | - | |
| 73 | - // If we're here, just leave it as a basic Item. | |
| 74 | - $item->setCache( $cache ); | |
| 75 | - return $item; | |
| 76 | - } | |
| 77 | - | |
| 78 | - /** | |
| 79 | - * Register this class as a candidate for being created by Item::factory. | |
| 80 | - * Should only be called on subclasses of Item. | |
| 81 | - * @throws Exception if called on Item or the registering class does not have INSTANCE_OF set. | |
| 82 | - */ | |
| 83 | -	public static function register() { | |
| 84 | -		if ( static::class === self::class ) { | |
| 85 | - throw new Exception( __METHOD__ . ' should only be called on subclasses of Item' ); | |
| 86 | - } | |
| 87 | -		if ( !static::INSTANCE_OF ) { | |
| 88 | - throw new Exception( 'Please set INSTANCE_OF for ' . static::class ); | |
| 89 | - } | |
| 90 | - static::$registeredClasses[ static::INSTANCE_OF ] = static::class; | |
| 91 | - } | |
| 92 | - | |
| 93 | - /** | |
| 94 | - * @param CacheItemPoolInterface $cache The cache to use. | |
| 95 | - */ | |
| 96 | -	public function setCache( CacheItemPoolInterface $cache ) { | |
| 97 | - $this->cache = $cache; | |
| 98 | - } | |
| 99 | - | |
| 100 | - /** | |
| 101 | - * Get the ID (Q-number) of this item. | |
| 102 | - * @return string|bool The ID or false if it couldn't be determined. | |
| 103 | - */ | |
| 104 | -	public function getId() { | |
| 105 | - $entity = $this->getEntity( $this->id ); | |
| 106 | - return isset( $entity['id'] ) ? $entity['id'] : false; | |
| 107 | - } | |
| 108 | - | |
| 109 | - /** | |
| 110 | - * Get this item's label. | |
| 111 | - * @return string | |
| 112 | - */ | |
| 113 | -	public function getLabel() { | |
| 114 | - $entity = $this->getEntity( $this->id ); | |
| 115 | -		if ( !empty( $entity['labels'][ $this->lang ]['value'] ) ) { | |
| 116 | - // Use the label if there is one. | |
| 117 | - return $entity['labels'][ $this->lang ]['value']; | |
| 118 | - } | |
| 119 | - // Or just use the ID. | |
| 120 | - return $entity['id']; | |
| 121 | - } | |
| 122 | - | |
| 123 | - /** | |
| 124 | - * @return string The Wikidata.org URL for this item. | |
| 125 | - */ | |
| 126 | -	public function getWikidataUrl() { | |
| 127 | - return $this->wikidataUrlBase . $this->id; | |
| 128 | - } | |
| 129 | - | |
| 130 | - /** | |
| 131 | - * Wikiprojects list their properties like this: | |
| 132 | - * | |
| 133 | -	 *     {{List of properties/Header}} | |
| 134 | -	 *     {{List of properties/Row|id=31|example-subject=Q923767|example-object=Q3331189}} | |
| 135 | - * </table> | |
| 136 | - * | |
| 137 | - * @param string $wikiProject The name of the WikiProject (must exist as a Wikidata page e.g. | |
| 138 | - * [[Wikidata:$wikiProject]]). | |
| 139 | - * @param string $type | |
| 140 | - * @return array | |
| 141 | - */ | |
| 142 | -	public function getStandardProperties( $wikiProject = 'WikiProject_Books', $type = 'work' ) { | |
| 143 | -		if ( $type !== 'work' ) { | |
| 144 | - $type = 'edition'; | |
| 145 | - } | |
| 146 | - $cacheKey = $type . '_item_property_IDs'; | |
| 147 | -		if ( $this->cache->hasItem( $cacheKey ) ) { | |
| 148 | - $propIds = $this->cache->getItem( $cacheKey )->get(); | |
| 149 | -		} else { | |
| 150 | - $domCrawler = new Crawler(); | |
| 151 | - $wikiProjectUrl = 'https://www.wikidata.org/wiki/Wikidata:' . $wikiProject; | |
| 152 | - $domCrawler->addHtmlContent( file_get_contents( $wikiProjectUrl ) ); | |
| 153 | - $propAncors = "//h3/span[@id='" . ucfirst( $type ) . "_item_properties']" | |
| 154 | - . "/../following-sibling::table[1]//td[2]/a"; | |
| 155 | - $propCells = $domCrawler->filterXPath( $propAncors ); | |
| 156 | - $propIds = []; | |
| 157 | -			$propCells->each( function ( Crawler $node, $i ) use ( &$propIds ) { | |
| 158 | - $propId = $node->text(); | |
| 159 | - $propIds[] = $propId; | |
| 160 | - } ); | |
| 161 | - $cacheItem = $this->cache->getItem( $cacheKey ) | |
| 162 | - ->expiresAfter( new DateInterval( 'PT1H' ) ) | |
| 163 | - ->set( $propIds ); | |
| 164 | - $this->cache->save( $cacheItem ); | |
| 165 | - } | |
| 166 | - $workProperties = []; | |
| 167 | -		foreach ( $propIds as $propId ) { | |
| 168 | - $workProperties[] = self::factory( $propId, $this->lang, $this->cache ); | |
| 169 | - } | |
| 170 | - | |
| 171 | - return $workProperties; | |
| 172 | - } | |
| 173 | - | |
| 174 | - /** | |
| 175 | - * @param string $propertyId | |
| 176 | - * @return bool|Time[] | |
| 177 | - */ | |
| 178 | -	public function getPropertyOfTypeTime( $propertyId ) { | |
| 179 | - $times = []; | |
| 180 | - $entity = $this->getEntity(); | |
| 181 | -		if ( !isset( $entity['claims'][$propertyId] ) ) { | |
| 182 | - // No statements for this property. | |
| 183 | - return $times; | |
| 184 | - } | |
| 185 | - // print_r($entity['claims'][$propertyId]);exit(); | |
| 186 | -		foreach ( $entity['claims'][$propertyId] as $claim ) { | |
| 187 | - // print_r($claim); | |
| 188 | - $times[] = new Time( $claim, $this->lang, $this->cache ); | |
| 15 | + /** @var string|bool */ | |
| 16 | + const INSTANCE_OF = false; | |
| 17 | + | |
| 18 | + const PROP_INSTANCE_OF = 'P31'; | |
| 19 | + const PROP_TITLE = 'P1476'; | |
| 20 | + const PROP_IMAGE = 'P18'; | |
| 21 | + const PROP_AUTHOR = 'P50'; | |
| 22 | + | |
| 23 | + /** @var string[] List of Q-numbers of registered classes. */ | |
| 24 | + protected static $registeredClasses = []; | |
| 25 | + | |
| 26 | + /** @var string */ | |
| 27 | + protected $id; | |
| 28 | + | |
| 29 | + /** @var MediawikiApi */ | |
| 30 | + protected $wdApi; | |
| 31 | + | |
| 32 | + /** @var string */ | |
| 33 | + protected $lang; | |
| 34 | + | |
| 35 | + /** @var CacheItemPoolInterface */ | |
| 36 | + protected $cache; | |
| 37 | + | |
| 38 | + /** @var string The base URL of Wikidata, with trailing slash. */ | |
| 39 | + protected $wikidataUrlBase = 'https://www.wikidata.org/wiki/'; | |
| 40 | + | |
| 41 | +    private function __construct( $id, $lang, CacheItemPoolInterface $cache ) { | |
| 42 | +        if ( !is_string( $id ) || preg_match( '/[QP][0-9]*/i', $id ) !== 1 ) { | |
| 43 | + throw new Exception( "Not a valid ID: " . var_export( $id, true ) ); | |
| 44 | + } | |
| 45 | + $this->id = $id; | |
| 46 | + $this->wdApi = new MediawikiApi( 'https://www.wikidata.org/w/api.php' ); | |
| 47 | + $this->entities = []; | |
| 48 | + $this->lang = $lang; | |
| 49 | + $this->cache = $cache; | |
| 50 | + } | |
| 51 | + | |
| 52 | + /** | |
| 53 | + * Create a new Item object with class based on the item's 'instance of' statement. | |
| 54 | + * | |
| 55 | + * @param string $id The item ID (Q-number). | |
| 56 | + * @param string $lang The language code. | |
| 57 | + * @param CacheItemPoolInterface $cache The cache to use. | |
| 58 | + * @return Item | |
| 59 | + */ | |
| 60 | +    public static function factory( $id, $lang, CacheItemPoolInterface $cache ) { | |
| 61 | + $item = new Item( $id, $lang, $cache ); | |
| 62 | +        foreach ( $item->getPropertyOfTypeItem( self::PROP_INSTANCE_OF ) as $instanceOf ) { | |
| 63 | + // Try to find a class matching the registered 'instance of'. | |
| 64 | +            foreach ( static::$registeredClasses as $classId => $className ) { | |
| 65 | + // If this 'instance of' is registered, use it. | |
| 66 | +                if ( $classId === $instanceOf->getItem()->getId() ) { | |
| 67 | + // This won't re-request the metadata, because that's cached. | |
| 68 | + return new $className( $id, $lang, $cache ); | |
| 69 | + } | |
| 70 | + } | |
| 71 | + } | |
| 72 | + | |
| 73 | + // If we're here, just leave it as a basic Item. | |
| 74 | + $item->setCache( $cache ); | |
| 75 | + return $item; | |
| 76 | + } | |
| 77 | + | |
| 78 | + /** | |
| 79 | + * Register this class as a candidate for being created by Item::factory. | |
| 80 | + * Should only be called on subclasses of Item. | |
| 81 | + * @throws Exception if called on Item or the registering class does not have INSTANCE_OF set. | |
| 82 | + */ | |
| 83 | +    public static function register() { | |
| 84 | +        if ( static::class === self::class ) { | |
| 85 | + throw new Exception( __METHOD__ . ' should only be called on subclasses of Item' ); | |
| 86 | + } | |
| 87 | +        if ( !static::INSTANCE_OF ) { | |
| 88 | + throw new Exception( 'Please set INSTANCE_OF for ' . static::class ); | |
| 89 | + } | |
| 90 | + static::$registeredClasses[ static::INSTANCE_OF ] = static::class; | |
| 91 | + } | |
| 92 | + | |
| 93 | + /** | |
| 94 | + * @param CacheItemPoolInterface $cache The cache to use. | |
| 95 | + */ | |
| 96 | +    public function setCache( CacheItemPoolInterface $cache ) { | |
| 97 | + $this->cache = $cache; | |
| 98 | + } | |
| 99 | + | |
| 100 | + /** | |
| 101 | + * Get the ID (Q-number) of this item. | |
| 102 | + * @return string|bool The ID or false if it couldn't be determined. | |
| 103 | + */ | |
| 104 | +    public function getId() { | |
| 105 | + $entity = $this->getEntity( $this->id ); | |
| 106 | + return isset( $entity['id'] ) ? $entity['id'] : false; | |
| 107 | + } | |
| 108 | + | |
| 109 | + /** | |
| 110 | + * Get this item's label. | |
| 111 | + * @return string | |
| 112 | + */ | |
| 113 | +    public function getLabel() { | |
| 114 | + $entity = $this->getEntity( $this->id ); | |
| 115 | +        if ( !empty( $entity['labels'][ $this->lang ]['value'] ) ) { | |
| 116 | + // Use the label if there is one. | |
| 117 | + return $entity['labels'][ $this->lang ]['value']; | |
| 118 | + } | |
| 119 | + // Or just use the ID. | |
| 120 | + return $entity['id']; | |
| 121 | + } | |
| 122 | + | |
| 123 | + /** | |
| 124 | + * @return string The Wikidata.org URL for this item. | |
| 125 | + */ | |
| 126 | +    public function getWikidataUrl() { | |
| 127 | + return $this->wikidataUrlBase . $this->id; | |
| 128 | + } | |
| 129 | + | |
| 130 | + /** | |
| 131 | + * Wikiprojects list their properties like this: | |
| 132 | + * | |
| 133 | +     *     {{List of properties/Header}} | |
| 134 | +     *     {{List of properties/Row|id=31|example-subject=Q923767|example-object=Q3331189}} | |
| 135 | + * </table> | |
| 136 | + * | |
| 137 | + * @param string $wikiProject The name of the WikiProject (must exist as a Wikidata page e.g. | |
| 138 | + * [[Wikidata:$wikiProject]]). | |
| 139 | + * @param string $type | |
| 140 | + * @return array | |
| 141 | + */ | |
| 142 | +    public function getStandardProperties( $wikiProject = 'WikiProject_Books', $type = 'work' ) { | |
| 143 | +        if ( $type !== 'work' ) { | |
| 144 | + $type = 'edition'; | |
| 145 | + } | |
| 146 | + $cacheKey = $type . '_item_property_IDs'; | |
| 147 | +        if ( $this->cache->hasItem( $cacheKey ) ) { | |
| 148 | + $propIds = $this->cache->getItem( $cacheKey )->get(); | |
| 149 | +        } else { | |
| 150 | + $domCrawler = new Crawler(); | |
| 151 | + $wikiProjectUrl = 'https://www.wikidata.org/wiki/Wikidata:' . $wikiProject; | |
| 152 | + $domCrawler->addHtmlContent( file_get_contents( $wikiProjectUrl ) ); | |
| 153 | + $propAncors = "//h3/span[@id='" . ucfirst( $type ) . "_item_properties']" | |
| 154 | + . "/../following-sibling::table[1]//td[2]/a"; | |
| 155 | + $propCells = $domCrawler->filterXPath( $propAncors ); | |
| 156 | + $propIds = []; | |
| 157 | +            $propCells->each( function ( Crawler $node, $i ) use ( &$propIds ) { | |
| 158 | + $propId = $node->text(); | |
| 159 | + $propIds[] = $propId; | |
| 160 | + } ); | |
| 161 | + $cacheItem = $this->cache->getItem( $cacheKey ) | |
| 162 | + ->expiresAfter( new DateInterval( 'PT1H' ) ) | |
| 163 | + ->set( $propIds ); | |
| 164 | + $this->cache->save( $cacheItem ); | |
| 165 | + } | |
| 166 | + $workProperties = []; | |
| 167 | +        foreach ( $propIds as $propId ) { | |
| 168 | + $workProperties[] = self::factory( $propId, $this->lang, $this->cache ); | |
| 169 | + } | |
| 170 | + | |
| 171 | + return $workProperties; | |
| 172 | + } | |
| 173 | + | |
| 174 | + /** | |
| 175 | + * @param string $propertyId | |
| 176 | + * @return bool|Time[] | |
| 177 | + */ | |
| 178 | +    public function getPropertyOfTypeTime( $propertyId ) { | |
| 179 | + $times = []; | |
| 180 | + $entity = $this->getEntity(); | |
| 181 | +        if ( !isset( $entity['claims'][$propertyId] ) ) { | |
| 182 | + // No statements for this property. | |
| 183 | + return $times; | |
| 184 | + } | |
| 185 | + // print_r($entity['claims'][$propertyId]);exit(); | |
| 186 | +        foreach ( $entity['claims'][$propertyId] as $claim ) { | |
| 187 | + // print_r($claim); | |
| 188 | + $times[] = new Time( $claim, $this->lang, $this->cache ); | |
| 189 | 189 | // | 
| 190 | 190 | // $timeValue = $claim['datavalue']['value']['time']; | 
| 191 | 191 | // // Ugly workaround for imprecise dates. :-( | 
| @@ -195,296 +195,296 @@ discard block | ||
| 195 | 195 | // } | 
| 196 | 196 | // $time = strtotime($timeValue); | 
| 197 | 197 | // return date($dateFormat, $time); | 
| 198 | - // } | |
| 199 | - } | |
| 200 | - return $times; | |
| 201 | - } | |
| 202 | - | |
| 203 | - /** | |
| 204 | - * Get the Item that is referred to by the specified item's property. | |
| 205 | - * | |
| 206 | - * @param string $propertyId | |
| 207 | - * | |
| 208 | - * @return \Samwilson\SimpleWikidata\Properties\Item[] | |
| 209 | - */ | |
| 210 | -	public function getPropertyOfTypeItem( $propertyId ) { | |
| 211 | - $entity = $this->getEntity( $this->id ); | |
| 212 | -		if ( !isset( $entity['claims'][$propertyId] ) ) { | |
| 213 | - return []; | |
| 214 | - } | |
| 215 | - $items = []; | |
| 216 | -		foreach ( $entity['claims'][$propertyId] as $claim ) { | |
| 217 | - $items[] = new Properties\Item( $claim, $this->lang, $this->cache ); | |
| 218 | - } | |
| 219 | - | |
| 220 | - return $items; | |
| 221 | - } | |
| 222 | - | |
| 223 | - /** | |
| 224 | - * Set a claim to the given Item. | |
| 225 | - * @param string $property Property ID, with 'P'. | |
| 226 | - * @param string $itemId Item ID with 'Q'. | |
| 227 | - */ | |
| 228 | -	public function setPropertyOfTypeItem( $property, $itemId ) { | |
| 229 | - $itemIdNumeric = substr( $itemId, 1 ); | |
| 230 | - | |
| 231 | - // First see if this property already exists, and that it is different from what's being set. | |
| 232 | - $entity = $this->getEntity( $this->id ); | |
| 233 | -		if ( !empty( $entity['claims'][$property] ) ) { | |
| 234 | - // Get the first claim, and update it if necessary. | |
| 235 | - $claim = array_shift( $entity['claims'][$property] ); | |
| 236 | -			if ( $claim['mainsnak']['datavalue']['value']['id'] == $itemId ) { | |
| 237 | - // Already is the required value, no need to change. | |
| 238 | - return; | |
| 239 | - } | |
| 240 | - $claim['mainsnak']['datavalue']['value']['id'] = $itemId; | |
| 241 | - $claim['mainsnak']['datavalue']['value']['numeric-id'] = $itemIdNumeric; | |
| 242 | - $apiParams = [ | |
| 243 | - 'action' => 'wbsetclaim', | |
| 244 | - 'claim' => json_encode( $claim ), | |
| 245 | - ]; | |
| 246 | - } | |
| 247 | - | |
| 248 | - // If no claim was found (and modified) above, create a new claim. | |
| 249 | -		if ( !isset( $apiParams ) ) { | |
| 250 | - $apiParams = [ | |
| 251 | - 'action' => 'wbcreateclaim', | |
| 252 | - 'entity' => $this->getId(), | |
| 253 | - 'property' => $property, | |
| 254 | - 'snaktype' => 'value', | |
| 255 | - 'value' => json_encode( [ 'entity-type' => 'item', 'numeric-id' => $itemIdNumeric ] ), | |
| 256 | - ]; | |
| 257 | - } | |
| 258 | - | |
| 259 | - // @TODO Save the property. | |
| 260 | - | |
| 261 | - // Clear the cache. | |
| 262 | - $this->cache->deleteItem( $this->getEntityCacheKey( $this->id ) ); | |
| 263 | - } | |
| 264 | - | |
| 265 | - /** | |
| 266 | - * @param string $entityId | |
| 267 | - * @param string $propertyId | |
| 268 | - * @return array|bool | |
| 269 | - */ | |
| 270 | -	public function getPropertyOfTypeUrl( $entityId, $propertyId ) { | |
| 271 | - $entity = $this->getEntity( $entityId ); | |
| 272 | -		if ( !isset( $entity['claims'][$propertyId] ) ) { | |
| 273 | - return false; | |
| 274 | - } | |
| 275 | - $urls = []; | |
| 276 | -		foreach ( $entity['claims'][$propertyId] as $claim ) { | |
| 277 | - $urls[] = $claim['mainsnak']['datavalue']['value']; | |
| 278 | - } | |
| 279 | - | |
| 280 | - return $urls; | |
| 281 | - } | |
| 282 | - | |
| 283 | - /** | |
| 284 | - * @param string $entityId | |
| 285 | - * @param string $propertyId | |
| 286 | - * @return array|bool | |
| 287 | - */ | |
| 288 | -	public function getPropertyOfTypeExternalIdentifier( $entityId, $propertyId ) { | |
| 289 | - $entity = $this->getEntity( $entityId ); | |
| 290 | -		if ( !isset( $entity['claims'][$propertyId] ) ) { | |
| 291 | - return false; | |
| 292 | - } | |
| 293 | - $idents = []; | |
| 294 | -		foreach ( $entity['claims'][$propertyId] as $claim ) { | |
| 295 | - $qualifiers = []; | |
| 296 | -			if ( !isset( $claim['qualifiers'] ) ) { | |
| 297 | - continue; | |
| 298 | - } | |
| 299 | -			foreach ( $claim['qualifiers'] as $qualsInfo ) { | |
| 300 | -				foreach ( $qualsInfo as $qualInfo ) { | |
| 301 | - $qualProp = self::factory( $qualInfo['property'], $this->lang, $this->cache ); | |
| 302 | - $propLabel = $qualProp->getLabel(); | |
| 303 | -					if ( !isset( $qualifiers[$propLabel] ) ) { | |
| 304 | - $qualifiers[$propLabel] = []; | |
| 305 | - } | |
| 306 | - $qualifiers[$propLabel][] = $qualInfo['datavalue']['value']; | |
| 307 | - } | |
| 308 | - } | |
| 309 | - $idents[] = [ | |
| 310 | - 'qualifiers' => $qualifiers, | |
| 311 | - 'value' => $claim['mainsnak']['datavalue']['value'], | |
| 312 | - ]; | |
| 313 | - } | |
| 314 | - | |
| 315 | - return $idents; | |
| 316 | - } | |
| 317 | - | |
| 318 | - /** | |
| 319 | - * Get a single-valued text property. | |
| 320 | - * @param string $property One of the PROP_* constants. | |
| 321 | - * @return string|bool The value, or false if it can't be found. | |
| 322 | - */ | |
| 323 | -	public function getPropertyOfTypeText( $property ) { | |
| 324 | - $entity = $this->getEntity( $this->id ); | |
| 325 | -		if ( isset( $entity['claims'][$property] ) ) { | |
| 326 | - // Use the first title. | |
| 327 | -			foreach ( $entity['claims'][$property] as $t ) { | |
| 328 | -				if ( !isset( $t['mainsnak']['datavalue']['value']['language'] ) ) { | |
| 329 | - var_dump( $t['mainsnak']['datavalue']['value'] ); | |
| 330 | - exit(); | |
| 331 | - } | |
| 332 | - if ( $t['mainsnak']['datavalue']['value']['language'] == $this->lang | |
| 333 | - && !empty( $t['mainsnak']['datavalue']['value']['text'] ) | |
| 334 | -				) { | |
| 335 | - return $t['mainsnak']['datavalue']['value']['text']; | |
| 336 | - } | |
| 337 | - } | |
| 338 | - } | |
| 339 | - return false; | |
| 340 | - } | |
| 341 | - | |
| 342 | - /** | |
| 343 | - * Literal data field for a quantity that relates to some kind of well-defined unit. | |
| 344 | - * The actual unit goes in the data values that is entered. | |
| 345 | - * - amount – implicit part of the string (mapping of unit prefix is unclear) | |
| 346 | - * - unit – implicit part of the string that defaults to "1" (mapping to standardizing | |
| 347 | - * body is unclear) | |
| 348 | - * - upperbound - quantity's upper bound | |
| 349 | - * - lowerbound - quantity's lower bound | |
| 350 | - * @param string $property | |
| 351 | - * @return mixed[]|bool If it's not false it's an array with 'amount', 'unit', etc. | |
| 352 | - */ | |
| 353 | -	public function getPropertyOfTypeQuantity( $property ) { | |
| 354 | - $quantities = []; | |
| 355 | - $entity = $this->getEntity( $this->id ); | |
| 356 | -		if ( !isset( $entity['claims'][$property] ) ) { | |
| 357 | - return false; | |
| 358 | - } | |
| 359 | -		foreach ( $entity['claims'][$property] as $t ) { | |
| 360 | - $quantity = $t['mainsnak']['datavalue']['value']; | |
| 361 | - $unitId = substr( $quantity['unit'], strlen( $this->wikidataUrlBase ) + 1 ); | |
| 362 | - $quantity['unit'] = self::factory( $unitId, $this->lang, $this->cache ); | |
| 363 | - $quantities[] = $quantity; | |
| 364 | - } | |
| 365 | - return $quantities; | |
| 366 | - } | |
| 367 | - | |
| 368 | - /** | |
| 369 | - * Set a single-valued text property. | |
| 370 | - * @param string $property One of the PROP_* constants. | |
| 371 | - * @param string $value The value. | |
| 372 | - */ | |
| 373 | -	public function setPropertyOfTypeText( $property, $value ) { | |
| 374 | - // First see if this property already exists, and that it is different from what's being set. | |
| 375 | - $entity = $this->getEntity( $this->id ); | |
| 376 | -		if ( !empty( $entity['claims'][$property] ) ) { | |
| 377 | - // Find this language's claim (if there is one). | |
| 378 | -			foreach ( $entity['claims'][$property] as $claim ) { | |
| 379 | -				if ( $claim['mainsnak']['datavalue']['value']['language'] == $this->lang ) { | |
| 380 | - // Modify this claim's text value. | |
| 381 | - $titleClaim = $claim; | |
| 382 | - $titleClaim['mainsnak']['datavalue']['value']['text'] = $value; | |
| 383 | - $setTitleParams = [ | |
| 384 | - 'action' => 'wbsetclaim', | |
| 385 | - 'claim' => \GuzzleHttp\json_encode( $titleClaim ), | |
| 386 | - ]; | |
| 387 | - continue; | |
| 388 | - } | |
| 389 | - } | |
| 390 | - } | |
| 391 | - | |
| 392 | - // If no claim was found (and modified) above, create a new claim. | |
| 393 | -		if ( !isset( $setTitleParams ) ) { | |
| 394 | - $setTitleParams = [ | |
| 395 | - 'action' => 'wbcreateclaim', | |
| 396 | - 'entity' => $this->getId(), | |
| 397 | - 'property' => $property, | |
| 398 | - 'snaktype' => 'value', | |
| 399 | - 'value' => \GuzzleHttp\json_encode( [ 'text' => $value, 'language' => $this->lang ] ), | |
| 400 | - ]; | |
| 401 | - } | |
| 402 | - | |
| 403 | - // Save the property. | |
| 404 | - $wdWpOauth = new WdWpOauth(); | |
| 405 | - $wdWpOauth->makeCall( $setTitleParams, true ); | |
| 406 | - | |
| 407 | - // Clear the cache. | |
| 408 | - $this->cache->deleteItem( $this->getEntityCacheKey( $this->id ) ); | |
| 409 | - } | |
| 410 | - | |
| 411 | - /** | |
| 412 | - * Does this item exist? | |
| 413 | - * @return bool | |
| 414 | - */ | |
| 415 | -	public function exists() { | |
| 416 | - return $this->getId() !== false; | |
| 417 | - } | |
| 418 | - | |
| 419 | - /** | |
| 420 | - * @return array With 'html' and 'title' keys. | |
| 421 | - */ | |
| 422 | -	public function getWikipediaIntro() { | |
| 423 | - $cacheKey = 'wikipedia-intro-' . $this->id . $this->lang; | |
| 424 | -		if ( $this->cache->hasItem( $cacheKey ) ) { | |
| 425 | - return $this->cache->getItem( $cacheKey )->get(); | |
| 426 | - } | |
| 427 | - $entity = $this->getEntity( $this->id ); | |
| 428 | -		if ( !isset( $entity['sitelinks'] ) ) { | |
| 429 | - return []; | |
| 430 | - } | |
| 431 | -		foreach ( $entity['sitelinks'] as $sitelink ) { | |
| 432 | -			if ( $sitelink['site'] == $this->lang . 'wiki' ) { | |
| 433 | - $api = new MediawikiApi( 'https://' . $this->lang . '.wikipedia.org/w/api.php' ); | |
| 434 | - $req = new SimpleRequest( 'query', [ | |
| 435 | - 'prop' => 'extracts', | |
| 436 | - 'exintro' => true, | |
| 437 | - 'titles' => $sitelink['title'], | |
| 438 | - ] ); | |
| 439 | - $response = $api->getRequest( $req ); | |
| 440 | - $page = array_shift( $response['query']['pages'] ); | |
| 441 | - $out = [ | |
| 442 | - 'title' => $page['title'], | |
| 443 | - 'html' => $page['extract'], | |
| 444 | - ]; | |
| 445 | - $cacheItem = $this->cache->getItem( $cacheKey ) | |
| 446 | - ->expiresAfter( new DateInterval( 'P1D' ) ) | |
| 447 | - ->set( $out ); | |
| 448 | - $this->cache->save( $cacheItem ); | |
| 449 | - | |
| 450 | - return $out; | |
| 451 | - } | |
| 452 | - } | |
| 453 | - | |
| 454 | - return []; | |
| 455 | - } | |
| 456 | - | |
| 457 | - /** | |
| 458 | - * Get the raw entity data from the 'wbgetentities' API call. | |
| 459 | - * @param string|null $id The Q-number. | |
| 460 | - * @param bool $ignoreCache | |
| 461 | - * @return array|bool | |
| 462 | - */ | |
| 463 | -	public function getEntity( $id = null, $ignoreCache = false ) { | |
| 464 | - $idActual = $id ?: $this->id; | |
| 465 | - $cacheKey = $this->getEntityCacheKey( $idActual ); | |
| 466 | -		if ( !$ignoreCache && $this->cache->hasItem( $cacheKey ) ) { | |
| 467 | - return $this->cache->getItem( $cacheKey )->get(); | |
| 468 | - } | |
| 469 | - $metadataRequest = new SimpleRequest( 'wbgetentities', [ 'ids' => $idActual ] ); | |
| 470 | - $itemResult = $this->wdApi->getRequest( $metadataRequest ); | |
| 471 | -		if ( !isset( $itemResult['success'] ) || !isset( $itemResult['entities'][$id] ) ) { | |
| 472 | - return false; | |
| 473 | - } | |
| 474 | - $metadata = $itemResult['entities'][$idActual]; | |
| 475 | - $cacheItem = $this->cache->getItem( $cacheKey ) | |
| 476 | - ->expiresAfter( new DateInterval( 'PT10M' ) ) | |
| 477 | - ->set( $metadata ); | |
| 478 | - $this->cache->save( $cacheItem ); | |
| 479 | - return $metadata; | |
| 480 | - } | |
| 481 | - | |
| 482 | - /** | |
| 483 | - * @param string $id | |
| 484 | - * | |
| 485 | - * @return string | |
| 486 | - */ | |
| 487 | -	protected function getEntityCacheKey( $id ) { | |
| 488 | - return 'entities' . $id; | |
| 489 | - } | |
| 198 | + // } | |
| 199 | + } | |
| 200 | + return $times; | |
| 201 | + } | |
| 202 | + | |
| 203 | + /** | |
| 204 | + * Get the Item that is referred to by the specified item's property. | |
| 205 | + * | |
| 206 | + * @param string $propertyId | |
| 207 | + * | |
| 208 | + * @return \Samwilson\SimpleWikidata\Properties\Item[] | |
| 209 | + */ | |
| 210 | +    public function getPropertyOfTypeItem( $propertyId ) { | |
| 211 | + $entity = $this->getEntity( $this->id ); | |
| 212 | +        if ( !isset( $entity['claims'][$propertyId] ) ) { | |
| 213 | + return []; | |
| 214 | + } | |
| 215 | + $items = []; | |
| 216 | +        foreach ( $entity['claims'][$propertyId] as $claim ) { | |
| 217 | + $items[] = new Properties\Item( $claim, $this->lang, $this->cache ); | |
| 218 | + } | |
| 219 | + | |
| 220 | + return $items; | |
| 221 | + } | |
| 222 | + | |
| 223 | + /** | |
| 224 | + * Set a claim to the given Item. | |
| 225 | + * @param string $property Property ID, with 'P'. | |
| 226 | + * @param string $itemId Item ID with 'Q'. | |
| 227 | + */ | |
| 228 | +    public function setPropertyOfTypeItem( $property, $itemId ) { | |
| 229 | + $itemIdNumeric = substr( $itemId, 1 ); | |
| 230 | + | |
| 231 | + // First see if this property already exists, and that it is different from what's being set. | |
| 232 | + $entity = $this->getEntity( $this->id ); | |
| 233 | +        if ( !empty( $entity['claims'][$property] ) ) { | |
| 234 | + // Get the first claim, and update it if necessary. | |
| 235 | + $claim = array_shift( $entity['claims'][$property] ); | |
| 236 | +            if ( $claim['mainsnak']['datavalue']['value']['id'] == $itemId ) { | |
| 237 | + // Already is the required value, no need to change. | |
| 238 | + return; | |
| 239 | + } | |
| 240 | + $claim['mainsnak']['datavalue']['value']['id'] = $itemId; | |
| 241 | + $claim['mainsnak']['datavalue']['value']['numeric-id'] = $itemIdNumeric; | |
| 242 | + $apiParams = [ | |
| 243 | + 'action' => 'wbsetclaim', | |
| 244 | + 'claim' => json_encode( $claim ), | |
| 245 | + ]; | |
| 246 | + } | |
| 247 | + | |
| 248 | + // If no claim was found (and modified) above, create a new claim. | |
| 249 | +        if ( !isset( $apiParams ) ) { | |
| 250 | + $apiParams = [ | |
| 251 | + 'action' => 'wbcreateclaim', | |
| 252 | + 'entity' => $this->getId(), | |
| 253 | + 'property' => $property, | |
| 254 | + 'snaktype' => 'value', | |
| 255 | + 'value' => json_encode( [ 'entity-type' => 'item', 'numeric-id' => $itemIdNumeric ] ), | |
| 256 | + ]; | |
| 257 | + } | |
| 258 | + | |
| 259 | + // @TODO Save the property. | |
| 260 | + | |
| 261 | + // Clear the cache. | |
| 262 | + $this->cache->deleteItem( $this->getEntityCacheKey( $this->id ) ); | |
| 263 | + } | |
| 264 | + | |
| 265 | + /** | |
| 266 | + * @param string $entityId | |
| 267 | + * @param string $propertyId | |
| 268 | + * @return array|bool | |
| 269 | + */ | |
| 270 | +    public function getPropertyOfTypeUrl( $entityId, $propertyId ) { | |
| 271 | + $entity = $this->getEntity( $entityId ); | |
| 272 | +        if ( !isset( $entity['claims'][$propertyId] ) ) { | |
| 273 | + return false; | |
| 274 | + } | |
| 275 | + $urls = []; | |
| 276 | +        foreach ( $entity['claims'][$propertyId] as $claim ) { | |
| 277 | + $urls[] = $claim['mainsnak']['datavalue']['value']; | |
| 278 | + } | |
| 279 | + | |
| 280 | + return $urls; | |
| 281 | + } | |
| 282 | + | |
| 283 | + /** | |
| 284 | + * @param string $entityId | |
| 285 | + * @param string $propertyId | |
| 286 | + * @return array|bool | |
| 287 | + */ | |
| 288 | +    public function getPropertyOfTypeExternalIdentifier( $entityId, $propertyId ) { | |
| 289 | + $entity = $this->getEntity( $entityId ); | |
| 290 | +        if ( !isset( $entity['claims'][$propertyId] ) ) { | |
| 291 | + return false; | |
| 292 | + } | |
| 293 | + $idents = []; | |
| 294 | +        foreach ( $entity['claims'][$propertyId] as $claim ) { | |
| 295 | + $qualifiers = []; | |
| 296 | +            if ( !isset( $claim['qualifiers'] ) ) { | |
| 297 | + continue; | |
| 298 | + } | |
| 299 | +            foreach ( $claim['qualifiers'] as $qualsInfo ) { | |
| 300 | +                foreach ( $qualsInfo as $qualInfo ) { | |
| 301 | + $qualProp = self::factory( $qualInfo['property'], $this->lang, $this->cache ); | |
| 302 | + $propLabel = $qualProp->getLabel(); | |
| 303 | +                    if ( !isset( $qualifiers[$propLabel] ) ) { | |
| 304 | + $qualifiers[$propLabel] = []; | |
| 305 | + } | |
| 306 | + $qualifiers[$propLabel][] = $qualInfo['datavalue']['value']; | |
| 307 | + } | |
| 308 | + } | |
| 309 | + $idents[] = [ | |
| 310 | + 'qualifiers' => $qualifiers, | |
| 311 | + 'value' => $claim['mainsnak']['datavalue']['value'], | |
| 312 | + ]; | |
| 313 | + } | |
| 314 | + | |
| 315 | + return $idents; | |
| 316 | + } | |
| 317 | + | |
| 318 | + /** | |
| 319 | + * Get a single-valued text property. | |
| 320 | + * @param string $property One of the PROP_* constants. | |
| 321 | + * @return string|bool The value, or false if it can't be found. | |
| 322 | + */ | |
| 323 | +    public function getPropertyOfTypeText( $property ) { | |
| 324 | + $entity = $this->getEntity( $this->id ); | |
| 325 | +        if ( isset( $entity['claims'][$property] ) ) { | |
| 326 | + // Use the first title. | |
| 327 | +            foreach ( $entity['claims'][$property] as $t ) { | |
| 328 | +                if ( !isset( $t['mainsnak']['datavalue']['value']['language'] ) ) { | |
| 329 | + var_dump( $t['mainsnak']['datavalue']['value'] ); | |
| 330 | + exit(); | |
| 331 | + } | |
| 332 | + if ( $t['mainsnak']['datavalue']['value']['language'] == $this->lang | |
| 333 | + && !empty( $t['mainsnak']['datavalue']['value']['text'] ) | |
| 334 | +                ) { | |
| 335 | + return $t['mainsnak']['datavalue']['value']['text']; | |
| 336 | + } | |
| 337 | + } | |
| 338 | + } | |
| 339 | + return false; | |
| 340 | + } | |
| 341 | + | |
| 342 | + /** | |
| 343 | + * Literal data field for a quantity that relates to some kind of well-defined unit. | |
| 344 | + * The actual unit goes in the data values that is entered. | |
| 345 | + * - amount – implicit part of the string (mapping of unit prefix is unclear) | |
| 346 | + * - unit – implicit part of the string that defaults to "1" (mapping to standardizing | |
| 347 | + * body is unclear) | |
| 348 | + * - upperbound - quantity's upper bound | |
| 349 | + * - lowerbound - quantity's lower bound | |
| 350 | + * @param string $property | |
| 351 | + * @return mixed[]|bool If it's not false it's an array with 'amount', 'unit', etc. | |
| 352 | + */ | |
| 353 | +    public function getPropertyOfTypeQuantity( $property ) { | |
| 354 | + $quantities = []; | |
| 355 | + $entity = $this->getEntity( $this->id ); | |
| 356 | +        if ( !isset( $entity['claims'][$property] ) ) { | |
| 357 | + return false; | |
| 358 | + } | |
| 359 | +        foreach ( $entity['claims'][$property] as $t ) { | |
| 360 | + $quantity = $t['mainsnak']['datavalue']['value']; | |
| 361 | + $unitId = substr( $quantity['unit'], strlen( $this->wikidataUrlBase ) + 1 ); | |
| 362 | + $quantity['unit'] = self::factory( $unitId, $this->lang, $this->cache ); | |
| 363 | + $quantities[] = $quantity; | |
| 364 | + } | |
| 365 | + return $quantities; | |
| 366 | + } | |
| 367 | + | |
| 368 | + /** | |
| 369 | + * Set a single-valued text property. | |
| 370 | + * @param string $property One of the PROP_* constants. | |
| 371 | + * @param string $value The value. | |
| 372 | + */ | |
| 373 | +    public function setPropertyOfTypeText( $property, $value ) { | |
| 374 | + // First see if this property already exists, and that it is different from what's being set. | |
| 375 | + $entity = $this->getEntity( $this->id ); | |
| 376 | +        if ( !empty( $entity['claims'][$property] ) ) { | |
| 377 | + // Find this language's claim (if there is one). | |
| 378 | +            foreach ( $entity['claims'][$property] as $claim ) { | |
| 379 | +                if ( $claim['mainsnak']['datavalue']['value']['language'] == $this->lang ) { | |
| 380 | + // Modify this claim's text value. | |
| 381 | + $titleClaim = $claim; | |
| 382 | + $titleClaim['mainsnak']['datavalue']['value']['text'] = $value; | |
| 383 | + $setTitleParams = [ | |
| 384 | + 'action' => 'wbsetclaim', | |
| 385 | + 'claim' => \GuzzleHttp\json_encode( $titleClaim ), | |
| 386 | + ]; | |
| 387 | + continue; | |
| 388 | + } | |
| 389 | + } | |
| 390 | + } | |
| 391 | + | |
| 392 | + // If no claim was found (and modified) above, create a new claim. | |
| 393 | +        if ( !isset( $setTitleParams ) ) { | |
| 394 | + $setTitleParams = [ | |
| 395 | + 'action' => 'wbcreateclaim', | |
| 396 | + 'entity' => $this->getId(), | |
| 397 | + 'property' => $property, | |
| 398 | + 'snaktype' => 'value', | |
| 399 | + 'value' => \GuzzleHttp\json_encode( [ 'text' => $value, 'language' => $this->lang ] ), | |
| 400 | + ]; | |
| 401 | + } | |
| 402 | + | |
| 403 | + // Save the property. | |
| 404 | + $wdWpOauth = new WdWpOauth(); | |
| 405 | + $wdWpOauth->makeCall( $setTitleParams, true ); | |
| 406 | + | |
| 407 | + // Clear the cache. | |
| 408 | + $this->cache->deleteItem( $this->getEntityCacheKey( $this->id ) ); | |
| 409 | + } | |
| 410 | + | |
| 411 | + /** | |
| 412 | + * Does this item exist? | |
| 413 | + * @return bool | |
| 414 | + */ | |
| 415 | +    public function exists() { | |
| 416 | + return $this->getId() !== false; | |
| 417 | + } | |
| 418 | + | |
| 419 | + /** | |
| 420 | + * @return array With 'html' and 'title' keys. | |
| 421 | + */ | |
| 422 | +    public function getWikipediaIntro() { | |
| 423 | + $cacheKey = 'wikipedia-intro-' . $this->id . $this->lang; | |
| 424 | +        if ( $this->cache->hasItem( $cacheKey ) ) { | |
| 425 | + return $this->cache->getItem( $cacheKey )->get(); | |
| 426 | + } | |
| 427 | + $entity = $this->getEntity( $this->id ); | |
| 428 | +        if ( !isset( $entity['sitelinks'] ) ) { | |
| 429 | + return []; | |
| 430 | + } | |
| 431 | +        foreach ( $entity['sitelinks'] as $sitelink ) { | |
| 432 | +            if ( $sitelink['site'] == $this->lang . 'wiki' ) { | |
| 433 | + $api = new MediawikiApi( 'https://' . $this->lang . '.wikipedia.org/w/api.php' ); | |
| 434 | + $req = new SimpleRequest( 'query', [ | |
| 435 | + 'prop' => 'extracts', | |
| 436 | + 'exintro' => true, | |
| 437 | + 'titles' => $sitelink['title'], | |
| 438 | + ] ); | |
| 439 | + $response = $api->getRequest( $req ); | |
| 440 | + $page = array_shift( $response['query']['pages'] ); | |
| 441 | + $out = [ | |
| 442 | + 'title' => $page['title'], | |
| 443 | + 'html' => $page['extract'], | |
| 444 | + ]; | |
| 445 | + $cacheItem = $this->cache->getItem( $cacheKey ) | |
| 446 | + ->expiresAfter( new DateInterval( 'P1D' ) ) | |
| 447 | + ->set( $out ); | |
| 448 | + $this->cache->save( $cacheItem ); | |
| 449 | + | |
| 450 | + return $out; | |
| 451 | + } | |
| 452 | + } | |
| 453 | + | |
| 454 | + return []; | |
| 455 | + } | |
| 456 | + | |
| 457 | + /** | |
| 458 | + * Get the raw entity data from the 'wbgetentities' API call. | |
| 459 | + * @param string|null $id The Q-number. | |
| 460 | + * @param bool $ignoreCache | |
| 461 | + * @return array|bool | |
| 462 | + */ | |
| 463 | +    public function getEntity( $id = null, $ignoreCache = false ) { | |
| 464 | + $idActual = $id ?: $this->id; | |
| 465 | + $cacheKey = $this->getEntityCacheKey( $idActual ); | |
| 466 | +        if ( !$ignoreCache && $this->cache->hasItem( $cacheKey ) ) { | |
| 467 | + return $this->cache->getItem( $cacheKey )->get(); | |
| 468 | + } | |
| 469 | + $metadataRequest = new SimpleRequest( 'wbgetentities', [ 'ids' => $idActual ] ); | |
| 470 | + $itemResult = $this->wdApi->getRequest( $metadataRequest ); | |
| 471 | +        if ( !isset( $itemResult['success'] ) || !isset( $itemResult['entities'][$id] ) ) { | |
| 472 | + return false; | |
| 473 | + } | |
| 474 | + $metadata = $itemResult['entities'][$idActual]; | |
| 475 | + $cacheItem = $this->cache->getItem( $cacheKey ) | |
| 476 | + ->expiresAfter( new DateInterval( 'PT10M' ) ) | |
| 477 | + ->set( $metadata ); | |
| 478 | + $this->cache->save( $cacheItem ); | |
| 479 | + return $metadata; | |
| 480 | + } | |
| 481 | + | |
| 482 | + /** | |
| 483 | + * @param string $id | |
| 484 | + * | |
| 485 | + * @return string | |
| 486 | + */ | |
| 487 | +    protected function getEntityCacheKey( $id ) { | |
| 488 | + return 'entities' . $id; | |
| 489 | + } | |
| 490 | 490 | } | 
| @@ -6,37 +6,37 @@ | ||
| 6 | 6 | |
| 7 | 7 |  abstract class Property { | 
| 8 | 8 | |
| 9 | - /** @var string[] */ | |
| 10 | - protected $claim; | |
| 11 | - | |
| 12 | - /** @var string */ | |
| 13 | - protected $lang; | |
| 14 | - | |
| 15 | - /** @var CacheItemPoolInterface */ | |
| 16 | - protected $cache; | |
| 17 | - | |
| 18 | - /** | |
| 19 | - * @param string $claim The claim data array. | |
| 20 | - * @param string $lang The language code. | |
| 21 | - * @param CacheItemPoolInterface $cache | |
| 22 | - */ | |
| 23 | -	public function __construct( array $claim, $lang, CacheItemPoolInterface $cache ) { | |
| 24 | - $this->claim = $claim; | |
| 25 | - $this->lang = $lang; | |
| 26 | - $this->cache = $cache; | |
| 27 | - } | |
| 28 | - | |
| 29 | - /** | |
| 30 | - * @return Reference[] | |
| 31 | - */ | |
| 32 | -	public function getReferences() { | |
| 33 | - $references = []; | |
| 34 | -		if ( !isset( $this->claim['references'] ) ) { | |
| 35 | - return $references; | |
| 36 | - } | |
| 37 | -		foreach ( $this->claim['references'] as $ref ) { | |
| 38 | - $references[] = new Reference( $ref, $this->lang, $this->cache ); | |
| 39 | - } | |
| 40 | - return $references; | |
| 41 | - } | |
| 9 | + /** @var string[] */ | |
| 10 | + protected $claim; | |
| 11 | + | |
| 12 | + /** @var string */ | |
| 13 | + protected $lang; | |
| 14 | + | |
| 15 | + /** @var CacheItemPoolInterface */ | |
| 16 | + protected $cache; | |
| 17 | + | |
| 18 | + /** | |
| 19 | + * @param string $claim The claim data array. | |
| 20 | + * @param string $lang The language code. | |
| 21 | + * @param CacheItemPoolInterface $cache | |
| 22 | + */ | |
| 23 | +    public function __construct( array $claim, $lang, CacheItemPoolInterface $cache ) { | |
| 24 | + $this->claim = $claim; | |
| 25 | + $this->lang = $lang; | |
| 26 | + $this->cache = $cache; | |
| 27 | + } | |
| 28 | + | |
| 29 | + /** | |
| 30 | + * @return Reference[] | |
| 31 | + */ | |
| 32 | +    public function getReferences() { | |
| 33 | + $references = []; | |
| 34 | +        if ( !isset( $this->claim['references'] ) ) { | |
| 35 | + return $references; | |
| 36 | + } | |
| 37 | +        foreach ( $this->claim['references'] as $ref ) { | |
| 38 | + $references[] = new Reference( $ref, $this->lang, $this->cache ); | |
| 39 | + } | |
| 40 | + return $references; | |
| 41 | + } | |
| 42 | 42 | } | 
| @@ -11,94 +11,94 @@ | ||
| 11 | 11 | */ | 
| 12 | 12 |  class Work extends Item { | 
| 13 | 13 | |
| 14 | - const ITEM_WORK = 'Q386724'; | |
| 15 | - const PROP_SUBTITLE = 'P1680'; | |
| 16 | - const PROP_GENRE = 'P136'; | |
| 17 | - const PROP_SUBJECT = 'P921'; | |
| 14 | + const ITEM_WORK = 'Q386724'; | |
| 15 | + const PROP_SUBTITLE = 'P1680'; | |
| 16 | + const PROP_GENRE = 'P136'; | |
| 17 | + const PROP_SUBJECT = 'P921'; | |
| 18 | 18 | |
| 19 | - /** | |
| 20 | - * @param string $lang ISO639 language code. | |
| 21 | - * @param CacheItemPoolInterface $cache The cache. | |
| 22 | - * @return array|Item[] | |
| 23 | - */ | |
| 24 | -	public static function getBookTypes( $lang = 'en', $cache ) { | |
| 25 | -		$sparql = "SELECT ?item WHERE { | |
| 19 | + /** | |
| 20 | + * @param string $lang ISO639 language code. | |
| 21 | + * @param CacheItemPoolInterface $cache The cache. | |
| 22 | + * @return array|Item[] | |
| 23 | + */ | |
| 24 | +    public static function getBookTypes( $lang = 'en', $cache ) { | |
| 25 | +        $sparql = "SELECT ?item WHERE { | |
| 26 | 26 | ?item wdt:P279 wd:Q571 . | 
| 27 | 27 | ?item rdfs:label ?label . | 
| 28 | 28 | FILTER(LANG(?label) = '$lang') . | 
| 29 | 29 | } ORDER BY ?label "; | 
| 30 | - $query = new Query( $sparql, $lang ); | |
| 31 | - $query->setCache( $cache ); | |
| 32 | - $bookType = Item::factory( self::ITEM_WORK, $lang, $cache ); | |
| 33 | - return [ $bookType ] + $query->getItems(); | |
| 34 | - } | |
| 30 | + $query = new Query( $sparql, $lang ); | |
| 31 | + $query->setCache( $cache ); | |
| 32 | + $bookType = Item::factory( self::ITEM_WORK, $lang, $cache ); | |
| 33 | + return [ $bookType ] + $query->getItems(); | |
| 34 | + } | |
| 35 | 35 | |
| 36 | - /** | |
| 37 | - * @return bool|string | |
| 38 | - */ | |
| 39 | -	public function getSubtitle() { | |
| 40 | - return $this->getPropertyOfTypeText( self::PROP_SUBTITLE ); | |
| 41 | - } | |
| 36 | + /** | |
| 37 | + * @return bool|string | |
| 38 | + */ | |
| 39 | +    public function getSubtitle() { | |
| 40 | + return $this->getPropertyOfTypeText( self::PROP_SUBTITLE ); | |
| 41 | + } | |
| 42 | 42 | |
| 43 | - /** | |
| 44 | - * @param string $subtitle The new subtitle. | |
| 45 | - */ | |
| 46 | -	public function setSubtitle( $subtitle ) { | |
| 47 | - $this->setPropertyOfTypeText( self::PROP_SUBTITLE, $subtitle ); | |
| 48 | - } | |
| 43 | + /** | |
| 44 | + * @param string $subtitle The new subtitle. | |
| 45 | + */ | |
| 46 | +    public function setSubtitle( $subtitle ) { | |
| 47 | + $this->setPropertyOfTypeText( self::PROP_SUBTITLE, $subtitle ); | |
| 48 | + } | |
| 49 | 49 | |
| 50 | - /** | |
| 51 | - * @param string $property A property identifier. | |
| 52 | - * @return array | |
| 53 | - */ | |
| 54 | -	public function getPropertyOfTypeItems( $property ) { | |
| 55 | - $entity = $this->getEntity( $this->id ); | |
| 56 | -		if ( !isset( $entity['claims'][ $property ] ) ) { | |
| 57 | - return []; | |
| 58 | - } | |
| 59 | - $items = []; | |
| 60 | -		foreach ( $entity['claims'][ $property ] as $authorClaim ) { | |
| 61 | - $item_id = $authorClaim['mainsnak']['datavalue']['value']['id']; | |
| 62 | - $items[] = Item::factory( $item_id, $this->lang, $this->cache ); | |
| 63 | - } | |
| 50 | + /** | |
| 51 | + * @param string $property A property identifier. | |
| 52 | + * @return array | |
| 53 | + */ | |
| 54 | +    public function getPropertyOfTypeItems( $property ) { | |
| 55 | + $entity = $this->getEntity( $this->id ); | |
| 56 | +        if ( !isset( $entity['claims'][ $property ] ) ) { | |
| 57 | + return []; | |
| 58 | + } | |
| 59 | + $items = []; | |
| 60 | +        foreach ( $entity['claims'][ $property ] as $authorClaim ) { | |
| 61 | + $item_id = $authorClaim['mainsnak']['datavalue']['value']['id']; | |
| 62 | + $items[] = Item::factory( $item_id, $this->lang, $this->cache ); | |
| 63 | + } | |
| 64 | 64 | |
| 65 | - return $items; | |
| 66 | - } | |
| 65 | + return $items; | |
| 66 | + } | |
| 67 | 67 | |
| 68 | - /** | |
| 69 | - * @return array | |
| 70 | - */ | |
| 71 | -	public function getAuthors() { | |
| 72 | - return $this->getPropertyOfTypeItems( self::PROP_AUTHOR ); | |
| 73 | - } | |
| 68 | + /** | |
| 69 | + * @return array | |
| 70 | + */ | |
| 71 | +    public function getAuthors() { | |
| 72 | + return $this->getPropertyOfTypeItems( self::PROP_AUTHOR ); | |
| 73 | + } | |
| 74 | 74 | |
| 75 | - /** | |
| 76 | - * @return Item[] | |
| 77 | - */ | |
| 78 | -	public function getSubjects() { | |
| 79 | - return $this->getPropertyOfTypeItems( self::PROP_SUBJECT ); | |
| 80 | - } | |
| 75 | + /** | |
| 76 | + * @return Item[] | |
| 77 | + */ | |
| 78 | +    public function getSubjects() { | |
| 79 | + return $this->getPropertyOfTypeItems( self::PROP_SUBJECT ); | |
| 80 | + } | |
| 81 | 81 | |
| 82 | - /** | |
| 83 | - * @return Item[] | |
| 84 | - */ | |
| 85 | -	public function getEditions() { | |
| 86 | -		$sparql = "SELECT ?item WHERE {" | |
| 87 | - . " ?item wdt:" . Edition::PROP_EDITION_OR_TRANSLATION_OF . " wd:" . $this->getId() | |
| 88 | - . "}"; | |
| 89 | - $query = new Query( $sparql, $this->lang, $this->cache ); | |
| 90 | - $editions = $query->getItems(); | |
| 91 | -		usort( $editions, function ( Item $a, Item $b ) { | |
| 92 | -			if ( $a instanceof Edition && $b instanceof Edition ) { | |
| 93 | - return $a->getPublicationYear() - $b->getPublicationYear(); | |
| 94 | - } | |
| 95 | - return 0; | |
| 96 | - } ); | |
| 82 | + /** | |
| 83 | + * @return Item[] | |
| 84 | + */ | |
| 85 | +    public function getEditions() { | |
| 86 | +        $sparql = "SELECT ?item WHERE {" | |
| 87 | + . " ?item wdt:" . Edition::PROP_EDITION_OR_TRANSLATION_OF . " wd:" . $this->getId() | |
| 88 | + . "}"; | |
| 89 | + $query = new Query( $sparql, $this->lang, $this->cache ); | |
| 90 | + $editions = $query->getItems(); | |
| 91 | +        usort( $editions, function ( Item $a, Item $b ) { | |
| 92 | +            if ( $a instanceof Edition && $b instanceof Edition ) { | |
| 93 | + return $a->getPublicationYear() - $b->getPublicationYear(); | |
| 94 | + } | |
| 95 | + return 0; | |
| 96 | + } ); | |
| 97 | 97 | |
| 98 | - return $editions; | |
| 99 | - } | |
| 98 | + return $editions; | |
| 99 | + } | |
| 100 | 100 | |
| 101 | -	public function newEdition() { | |
| 102 | - } | |
| 101 | +    public function newEdition() { | |
| 102 | + } | |
| 103 | 103 | |
| 104 | 104 | } |