From bf5d9963ca16194bc0f7dfb80a0d685d776eab8f Mon Sep 17 00:00:00 2001 From: Madman-81 Date: Wed, 8 Dec 2021 15:02:31 +0100 Subject: [PATCH 1/6] Create new auto inherit structure for context attributes ($structure). Attributes in the $structure property are now automatically merged with all parent classes --- src/ContextTypes/AbstractContext.php | 21 ++++++--------------- src/ContextTypes/Article.php | 13 +------------ src/ContextTypes/Audiobook.php | 12 +----------- src/ContextTypes/BlogPosting.php | 2 +- src/ContextTypes/Book.php | 12 +----------- src/ContextTypes/BookFormatType.php | 13 +------------ src/ContextTypes/Comment.php | 12 +----------- src/ContextTypes/Corporation.php | 14 +------------- src/ContextTypes/CreativeWork.php | 13 +------------ src/ContextTypes/Enumeration.php | 12 +----------- src/ContextTypes/Event.php | 13 +------------ src/ContextTypes/MediaObject.php | 12 +----------- src/ContextTypes/Organization.php | 13 +------------ src/ContextTypes/Person.php | 11 +---------- src/ContextTypes/Place.php | 10 +--------- src/ContextTypes/Sculpture.php | 14 +------------- src/ContextTypes/Thing.php | 11 ----------- 17 files changed, 21 insertions(+), 187 deletions(-) diff --git a/src/ContextTypes/AbstractContext.php b/src/ContextTypes/AbstractContext.php index 108a7d5..9a9bdfc 100644 --- a/src/ContextTypes/AbstractContext.php +++ b/src/ContextTypes/AbstractContext.php @@ -31,20 +31,6 @@ abstract class AbstractContext implements ContextTypeInterface 'name' => '', ]; - /** - * Property structure - * - * @var array - */ - protected $extendStructure = []; - - /** - * Property structure, will be merged up for objects extending Thing - * - * @var array - */ - private $extendedStructure = []; - /** * Create a new context type instance * @@ -56,6 +42,11 @@ public function __construct(array $attributes = []) $path = explode('\\', get_class($this)); $this->type = end($path); + $class = get_called_class(); + while ($class = get_parent_class($class)) { + $this->structure += get_class_vars($class)['structure']; + } + // Set attributes $this->fill($attributes); } @@ -89,7 +80,7 @@ public function fill(array $attributes) '@context' => 'http://schema.org', '@type' => $this->type, 'sameAs' => null - ], $this->structure, $this->extendStructure); + ], $this->structure); // Set properties from attributes foreach ($properties as $key => $property) { diff --git a/src/ContextTypes/Article.php b/src/ContextTypes/Article.php index fc04d55..d620b73 100644 --- a/src/ContextTypes/Article.php +++ b/src/ContextTypes/Article.php @@ -12,7 +12,7 @@ class Article extends CreativeWork * * @var array */ - private $extendedStructure = [ + protected $structure = [ 'articleBody' => null, 'articleSection' => null, 'pageEnd' => null, @@ -22,17 +22,6 @@ class Article extends CreativeWork 'mainEntityOfPage' => WebPage::class, ]; - /** - * @param array $attributes - * @param array $extendedStructure - */ - public function __construct(array $attributes, array $extendedStructure = []) - { - parent::__construct( - $attributes, array_merge($this->structure, $this->extendedStructure, $extendedStructure) - ); - } - /** * {@inheritDoc} */ diff --git a/src/ContextTypes/Audiobook.php b/src/ContextTypes/Audiobook.php index 0337410..55509b7 100644 --- a/src/ContextTypes/Audiobook.php +++ b/src/ContextTypes/Audiobook.php @@ -12,21 +12,11 @@ class Audiobook extends Book * * @var array */ - protected $extendedStructure = [ + protected $structure = [ 'caption' => MediaObject::class, 'transcript' => null, 'duration' => Duration::class, 'readBy' => Person::class, ]; - /** - * @param array $attributes - * @param array $extendedStructure - */ - public function __construct(array $attributes, array $extendedStructure = []) - { - parent::__construct( - $attributes, array_merge($this->structure, $this->extendedStructure, $extendedStructure) - ); - } } \ No newline at end of file diff --git a/src/ContextTypes/BlogPosting.php b/src/ContextTypes/BlogPosting.php index 2413586..8e6f435 100644 --- a/src/ContextTypes/BlogPosting.php +++ b/src/ContextTypes/BlogPosting.php @@ -9,7 +9,7 @@ class BlogPosting extends Article * * @var array */ - protected $extendStructure = [ + protected $structure = [ 'sharedContent' => CreativeWork::class, ]; } \ No newline at end of file diff --git a/src/ContextTypes/Book.php b/src/ContextTypes/Book.php index 19d4d7b..356075b 100644 --- a/src/ContextTypes/Book.php +++ b/src/ContextTypes/Book.php @@ -15,7 +15,7 @@ class Book extends CreativeWork * * @var array */ - protected $extendedStructure = [ + protected $structure = [ 'abridged' => null, 'bookEdition' => null, 'bookFormat' => BookFormatType::class, @@ -24,14 +24,4 @@ class Book extends CreativeWork 'numberOfPages' => null, ]; - /** - * @param array $attributes - * @param array $extendedStructure - */ - public function __construct(array $attributes, array $extendedStructure = []) - { - parent::__construct( - $attributes, array_merge($this->structure, $this->extendedStructure, $extendedStructure) - ); - } } \ No newline at end of file diff --git a/src/ContextTypes/BookFormatType.php b/src/ContextTypes/BookFormatType.php index 7e2c957..5a653d7 100644 --- a/src/ContextTypes/BookFormatType.php +++ b/src/ContextTypes/BookFormatType.php @@ -52,16 +52,5 @@ class BookFormatType extends Enumeration * * @var array */ - protected $extendedStructure = []; - - /** - * @param array $attributes - * @param array $extendedStructure - */ - public function __construct(array $attributes, array $extendedStructure = []) - { - parent::__construct( - $attributes, array_merge($this->structure, $this->extendedStructure, $extendedStructure) - ); - } + protected $structure = []; } \ No newline at end of file diff --git a/src/ContextTypes/Comment.php b/src/ContextTypes/Comment.php index 0c3a32e..0a7703c 100644 --- a/src/ContextTypes/Comment.php +++ b/src/ContextTypes/Comment.php @@ -12,19 +12,9 @@ class Comment extends CreativeWork * * @var array */ - private $extendedStructure = [ + protected $structure = [ 'downvoteCount' => null, 'upvoteCount' => null, ]; - /** - * @param array $attributes - * @param array $extendedStructure - */ - public function __construct(array $attributes, array $extendedStructure = []) - { - parent::__construct( - $attributes, array_merge($this->structure, $this->extendedStructure, $extendedStructure) - ); - } } diff --git a/src/ContextTypes/Corporation.php b/src/ContextTypes/Corporation.php index 98ec2f4..fc196b0 100755 --- a/src/ContextTypes/Corporation.php +++ b/src/ContextTypes/Corporation.php @@ -9,20 +9,8 @@ class Corporation extends Organization * * @var array */ - private $extendedStructure = [ + protected $structure = [ 'tickerSymbol' => null, ]; - /** - * Corporation constructor. Merges extendedStructure up - * - * @param array $attributes - * @param array $extendedStructure - */ - public function __construct(array $attributes, array $extendedStructure = []) - { - parent::__construct( - $attributes, array_merge($this->structure, $this->extendedStructure, $extendedStructure) - ); - } } \ No newline at end of file diff --git a/src/ContextTypes/CreativeWork.php b/src/ContextTypes/CreativeWork.php index 5cdda45..ca23857 100644 --- a/src/ContextTypes/CreativeWork.php +++ b/src/ContextTypes/CreativeWork.php @@ -12,7 +12,7 @@ class CreativeWork extends Thing * * @var array */ - private $extendedStructure = [ + protected $structure = [ 'about' => Thing::class, 'aggregateRating' => AggregateRating::class, 'alternativeHeadline' => null, @@ -35,17 +35,6 @@ class CreativeWork extends Thing 'video' => VideoObject::class, ]; - /** - * @param array $attributes - * @param array $extendedStructure - */ - public function __construct(array $attributes, array $extendedStructure = []) - { - parent::__construct( - $attributes, array_merge($this->structure, $this->extendedStructure, $extendedStructure) - ); - } - /** * Set the article body attribute. * diff --git a/src/ContextTypes/Enumeration.php b/src/ContextTypes/Enumeration.php index 695528b..e8cfa85 100644 --- a/src/ContextTypes/Enumeration.php +++ b/src/ContextTypes/Enumeration.php @@ -14,18 +14,8 @@ class Enumeration extends Thing * * @var array */ - protected $extendedStructure = [ + protected $structure = [ 'supersededBy' => Enumeration::class, ]; - /** - * @param array $attributes - * @param array $extendedStructure - */ - public function __construct(array $attributes, array $extendedStructure = []) - { - parent::__construct( - $attributes, array_merge($this->structure, $this->extendedStructure, $extendedStructure) - ); - } } \ No newline at end of file diff --git a/src/ContextTypes/Event.php b/src/ContextTypes/Event.php index a9f2790..36af686 100644 --- a/src/ContextTypes/Event.php +++ b/src/ContextTypes/Event.php @@ -9,7 +9,7 @@ class Event extends Thing * * @var array */ - protected $extendedStructure = [ + protected $structure = [ 'name' => null, 'startDate' => null, 'endDate' => null, @@ -18,17 +18,6 @@ class Event extends Thing 'location' => Place::class, ]; - /** - * @param array $attributes - * @param array $extendedStructure - */ - public function __construct(array $attributes, array $extendedStructure = []) - { - parent::__construct( - $attributes, array_merge($this->structure, $this->extendedStructure, $extendedStructure) - ); - } - /** * Set offers attributes. * diff --git a/src/ContextTypes/MediaObject.php b/src/ContextTypes/MediaObject.php index 9320dca..2bbecde 100644 --- a/src/ContextTypes/MediaObject.php +++ b/src/ContextTypes/MediaObject.php @@ -20,7 +20,7 @@ class MediaObject extends CreativeWork * * @var array */ - protected $extendedStructure = [ + protected $structure = [ 'associatedArticle' => NewsArticle::class, 'bitrate' => null, 'contentSize' => null, @@ -40,14 +40,4 @@ class MediaObject extends CreativeWork 'width' => QuantitativeValue::class, ]; - /** - * @param array $attributes - * @param array $extendedStructure - */ - public function __construct(array $attributes, array $extendedStructure = []) - { - parent::__construct( - $attributes, array_merge($this->structure, $this->extendedStructure, $extendedStructure) - ); - } } \ No newline at end of file diff --git a/src/ContextTypes/Organization.php b/src/ContextTypes/Organization.php index b058f77..1490aac 100644 --- a/src/ContextTypes/Organization.php +++ b/src/ContextTypes/Organization.php @@ -9,7 +9,7 @@ class Organization extends Thing * * @var array */ - private $extendedStructure = [ + protected $structure = [ 'address' => PostalAddress::class, 'logo' => ImageObject::class, 'contactPoint' => ContactPoint::class, @@ -17,17 +17,6 @@ class Organization extends Thing 'hasPOS' => Place::class, ]; - /** - * @param array $attributes - * @param array $extendedStructure - */ - public function __construct(array $attributes, array $extendedStructure = []) - { - parent::__construct( - $attributes, array_merge($this->structure, $this->extendedStructure, $extendedStructure) - ); - } - /** * Set the contactPoints * diff --git a/src/ContextTypes/Person.php b/src/ContextTypes/Person.php index 0c5ce87..4cc2def 100644 --- a/src/ContextTypes/Person.php +++ b/src/ContextTypes/Person.php @@ -12,7 +12,7 @@ class Person extends Thing * * @var array */ - protected $extendedStructure = [ + protected $structure = [ 'additionalName' => null, 'address' => null, // PostalAddress or Text 'affiliation' => null, @@ -39,15 +39,6 @@ class Person extends Thing 'workLocation' => Place::class, ]; - /** - * @param array $attributes - * @param array $extendedStructure - */ - public function __construct(array $attributes, array $extendedStructure = []) - { - parent::__construct($attributes, array_merge($this->structure, $this->extendedStructure, $extendedStructure)); - } - /** * Set the address * diff --git a/src/ContextTypes/Place.php b/src/ContextTypes/Place.php index 819f7fa..4a10d21 100644 --- a/src/ContextTypes/Place.php +++ b/src/ContextTypes/Place.php @@ -9,18 +9,10 @@ class Place extends Thing * * @var array */ - protected $extendedStructure = [ + protected $structure = [ 'address' => PostalAddress::class, 'review' => Review::class, 'aggregateRating' => AggregateRating::class, ]; - /** - * @param array $attributes - * @param array $extendedStructure - */ - public function __construct(array $attributes, array $extendedStructure = []) - { - parent::__construct($attributes, array_merge($this->structure, $this->extendedStructure, $extendedStructure)); - } } diff --git a/src/ContextTypes/Sculpture.php b/src/ContextTypes/Sculpture.php index 21f8b0d..359e7fe 100644 --- a/src/ContextTypes/Sculpture.php +++ b/src/ContextTypes/Sculpture.php @@ -9,18 +9,6 @@ class Sculpture extends CreativeWork * * @var array */ - private $extendedStructure = []; + protected $structure = []; - /** - * Constructor. Merges extendedStructure up - * - * @param array $attributes - * @param array $extendedStructure - */ - public function __construct(array $attributes, array $extendedStructure = []) - { - parent::__construct( - $attributes, array_merge($this->structure, $this->extendedStructure, $extendedStructure) - ); - } } diff --git a/src/ContextTypes/Thing.php b/src/ContextTypes/Thing.php index 78eea3c..f5172fe 100644 --- a/src/ContextTypes/Thing.php +++ b/src/ContextTypes/Thing.php @@ -22,17 +22,6 @@ class Thing extends AbstractContext 'url' => null, ]; - /** - * @param array $attributes - * @param array $extendedStructure - */ - public function __construct(array $attributes, array $extendedStructure = []) - { - $this->structure = array_merge($this->structure, $extendedStructure); - - parent::__construct($attributes); - } - /** * Set type attribute. * From 55be0c7597ae1fab1be8e166a8efcde6a0b9a660 Mon Sep 17 00:00:00 2001 From: Madman-81 Date: Wed, 8 Dec 2021 16:39:14 +0100 Subject: [PATCH 2/6] * The setProperty() function has been renamed to makeProperty() and the actual setting of properties is now down inside the fill() function. This makes for easier unit testing in the future. * The makeProperty() is also able to handle nested contexts better. - If the $value contains @type, it will create a contact based on that type - $property can now contain an array of classes defining what types of nexted context may be used for that attribute of the main context - If $value hold and array of contexts, it will automatically make contexts for those. This was done in several context with a setter, these are now all obsolete and therefore removed * The Music related contexts have be reorganised and the mutual attributes have been moved to MusicAbstractContext --- src/ContextTypes/AbstractContext.php | 68 +++++++++++++++++++---- src/ContextTypes/CreativeWork.php | 53 ------------------ src/ContextTypes/Event.php | 25 +-------- src/ContextTypes/MusicAbstractContext.php | 68 ++++------------------- src/ContextTypes/MusicAlbum.php | 9 +-- src/ContextTypes/MusicGroup.php | 7 +-- src/ContextTypes/MusicPlaylist.php | 5 +- src/ContextTypes/MusicRecording.php | 48 +--------------- src/ContextTypes/Organization.php | 45 --------------- src/ContextTypes/Product.php | 25 --------- src/ContextTypes/Recipe.php | 17 ------ 11 files changed, 77 insertions(+), 293 deletions(-) diff --git a/src/ContextTypes/AbstractContext.php b/src/ContextTypes/AbstractContext.php index 9a9bdfc..2af5ef9 100644 --- a/src/ContextTypes/AbstractContext.php +++ b/src/ContextTypes/AbstractContext.php @@ -28,7 +28,7 @@ abstract class AbstractContext implements ContextTypeInterface * @var array */ protected $structure = [ - 'name' => '', + 'name' => null, ]; /** @@ -84,8 +84,8 @@ public function fill(array $attributes) // Set properties from attributes foreach ($properties as $key => $property) { - $this->setProperty( - $key, $property, $this->getArrValue($attributes, $key, '') + $this->properties[$key] = $this->makeProperty( + $key, $property, $this->getArrValue($attributes, $key,'') ); } @@ -139,41 +139,55 @@ public function getProperty(string $key, $default = null) * * @return mixed */ - protected function setProperty(string $key, $property, $value = null) + protected function makeProperty(string $key, $property, $value = null) { // Can't be changed if ($key[0] === '@') { - return $this->properties[$key] = $property; + return $property; } // If the attribute has a get mutator, we will call that // then return what it returns as the value. if ($this->hasGetMutator($key)) { - return $this->properties[$key] = $this->mutateAttribute($key, $value); + return $this->mutateAttribute($key, $value); } // Format date and time to UTC if ($value instanceof DateTime) { - return $this->properties[$key] = $value->format('Y-m-d\TH:i:s'); + return $value->format('Y-m-d\TH:i:s'); } // Set nested context if ($value instanceof Context) { - return $this->properties[$key] = $this->filterNestedContext($value->getProperties()); + return $this->filterNestedContext($value->getProperties()); + } + + if (is_array($value) && $this->hasValidContext($value, $property)) { + return $this->makeContext($value); } // Set nested context from class - if ($property && class_exists($property)) { - return $this->properties[$key] = $this->getNestedContext($property, $value); + if (is_array($value) && is_string($property) && class_exists($property)) { + // Check if it is an array with one dimension + if (is_array(reset($value)) === false) { + $nested_context = $this->getNestedContext($property, $value); + } else { + // Process multi dimensional array + $nested_context = array_map(function ($item) use ($property) { + return $this->getNestedContext($property, $item); + }, $value); + } + + return $nested_context; } // Map properties to object if ($property !== null && is_array($property) && is_array($value)) { - return $this->properties[$key] = $this->mapProperty($property, $value); + return $this->mapProperty($property, $value); } // Set value - return $this->properties[$key] = $value; + return $value; } /** @@ -334,4 +348,34 @@ protected function getArrValue(array $array, string $key, $default = null) ? $array[$key] : $default; } + + /** + * Check if the values array has a key '@type' and if that contains an existing context + * + * @param array $value + * @param string|array $property + * + * @retrun bool + */ + protected function hasValidContext(array $value, $property) + { + if (array_key_exists('@type', $value)) { + $class_name = __NAMESPACE__ .'\\'. $value['@type']; + + if (!is_array($property)) { + $property = [$property]; + } + + return (in_array($class_name, $property) && class_exists($class_name)); + } + + return false; + } + + protected function makeContext(array $value) + { + $property = __NAMESPACE__ .'\\'. $value['@type']; + + return $this->getNestedContext($property, $value); + } } diff --git a/src/ContextTypes/CreativeWork.php b/src/ContextTypes/CreativeWork.php index ca23857..840c2f9 100644 --- a/src/ContextTypes/CreativeWork.php +++ b/src/ContextTypes/CreativeWork.php @@ -47,57 +47,4 @@ protected function setTextAttribute(string $text): string return $this->truncate($text, 260); } - /** - * Set the authors - * - * @param mixed $items - * - * @return array - */ - protected function setAuthorAttribute($items) - { - if (is_array($items) === false) { - return $items; - } - - return array_map(function ($item) { - return $this->getNestedContext(Person::class, $item); - }, $items); - } - - /** - * Set the comments - * - * @param mixed $items - * - * @return array - */ - protected function setCommentAttribute($items) - { - if (is_array($items) === false) { - return $items; - } - - return array_map(function ($item) { - return $this->getNestedContext(Comment::class, $item); - }, $items); - } - - /** - * Set the reviews - * - * @param mixed $items - * - * @return array - */ - protected function setReviewAttribute($items) - { - if (is_array($items) === false) { - return $items; - } - - return array_map(function ($item) { - return $this->getNestedContext(Review::class, $item); - }, $items); - } } diff --git a/src/ContextTypes/Event.php b/src/ContextTypes/Event.php index 36af686..ea60ebb 100644 --- a/src/ContextTypes/Event.php +++ b/src/ContextTypes/Event.php @@ -14,31 +14,8 @@ class Event extends Thing 'startDate' => null, 'endDate' => null, 'url' => null, - 'offers' => [], + 'offers' => Offer::class, 'location' => Place::class, ]; - /** - * Set offers attributes. - * - * @param mixed $items - * - * @return array - */ - protected function setOffersAttribute($items) - { - if (is_array($items) === false) { - return $items; - } - - // Check if it is an array with one dimension - if (is_array(reset($items)) === false) { - return $this->getNestedContext(Offer::class, $items); - } - - // Process multi dimensional array - return array_map(function ($item) { - return $this->getNestedContext(Offer::class, $item); - }, $items); - } } diff --git a/src/ContextTypes/MusicAbstractContext.php b/src/ContextTypes/MusicAbstractContext.php index 8e22cfc..4436e09 100644 --- a/src/ContextTypes/MusicAbstractContext.php +++ b/src/ContextTypes/MusicAbstractContext.php @@ -4,6 +4,17 @@ abstract class MusicAbstractContext extends AbstractContext { + /** + * Property structure + * + * @var array + */ + protected $structure = [ + '@id' => null, + 'url' => null, + 'name' => null, + ]; + /** * Set the canonical URL of the article page. * @@ -35,61 +46,4 @@ protected function setGenreAttribute($items) return implode(', ', $items); } - /** - * Set artist attribute - * - * @param mixed $items - * - * @return array - */ - protected function setByArtistAttribute($items) - { - if (is_array($items) === false) { - return $items; - } - - //Check if not multidimensional array (for backward compatibility) - if ((count($items) == count($items, COUNT_RECURSIVE))) { - return $this->getNestedContext(MusicGroup::class, $items); - } - - //multiple artists - return array_map(function ($item) { - return $this->getNestedContext(MusicGroup::class, $item); - }, $items); - } - - /** - * Set the tracks for a music group - * - * @param mixed $items - * - * @return array - */ - protected function setTrackAttribute($items) - { - if (is_array($items) === false) { - return $items; - } - - return array_map(function ($item) { - return $this->getNestedContext(MusicRecording::class, $item); - }, $items); - } - - /** - * Set image attribute - * - * @param mixed $item - * - * @return array - */ - protected function setImageAttribute($item) - { - if (is_array($item) === false) { - return $item; - } - - return $this->getNestedContext(ImageObject::class, $item); - } } diff --git a/src/ContextTypes/MusicAlbum.php b/src/ContextTypes/MusicAlbum.php index 7b5f6c0..89ab1ba 100644 --- a/src/ContextTypes/MusicAlbum.php +++ b/src/ContextTypes/MusicAlbum.php @@ -10,14 +10,11 @@ class MusicAlbum extends MusicAbstractContext * @var array */ protected $structure = [ - '@id' => null, - 'url' => null, - 'name' => null, 'description' => null, 'numTracks' => null, - 'byArtist' => null, + 'byArtist' => MusicGroup::class, 'genre' => null, - 'track' => null, - 'image' => null, + 'track' => MusicRecording::class, + 'image' => ImageObject::class, ]; } diff --git a/src/ContextTypes/MusicGroup.php b/src/ContextTypes/MusicGroup.php index eb2047c..c9bbc73 100644 --- a/src/ContextTypes/MusicGroup.php +++ b/src/ContextTypes/MusicGroup.php @@ -10,11 +10,8 @@ class MusicGroup extends MusicAbstractContext * @var array */ protected $structure = [ - '@id' => null, - 'url' => null, - 'name' => null, 'description' => null, - 'track' => null, - 'image' => null, + 'track' => MusicRecording::class, + 'image' => ImageObject::class, ]; } diff --git a/src/ContextTypes/MusicPlaylist.php b/src/ContextTypes/MusicPlaylist.php index cf28d25..866b934 100644 --- a/src/ContextTypes/MusicPlaylist.php +++ b/src/ContextTypes/MusicPlaylist.php @@ -10,10 +10,7 @@ class MusicPlaylist extends MusicAbstractContext * @var array */ protected $structure = [ - '@id' => null, - 'url' => null, - 'name' => null, 'numTracks' => null, - 'track' => null, + 'track' => MusicRecording::class, ]; } diff --git a/src/ContextTypes/MusicRecording.php b/src/ContextTypes/MusicRecording.php index 2f66c21..d53ed7c 100644 --- a/src/ContextTypes/MusicRecording.php +++ b/src/ContextTypes/MusicRecording.php @@ -10,55 +10,13 @@ class MusicRecording extends MusicAbstractContext * @var array */ protected $structure = [ - '@id' => null, - 'url' => null, - 'name' => null, 'duration' => null, 'genre' => null, 'description' => null, - 'byArtist' => null, - 'inAlbum' => null, - 'inPlaylist' => null, + 'byArtist' => MusicGroup::class, + 'inAlbum' => MusicAlbum::class, + 'inPlaylist' => MusicPlaylist::class, 'isrcCode' => null, ]; - /** - * Set in album attribute - * - * @param mixed $items - * - * @return array - */ - protected function setInAlbumAttribute($items) - { - if (is_array($items) === false) { - return $items; - } - - //Check if not multidimensional array (for backward compatibility) - if ((count($items) == count($items, COUNT_RECURSIVE))) { - return $this->getNestedContext(MusicAlbum::class, $items); - } - - //multiple albums - return array_map(function ($item) { - return $this->getNestedContext(MusicAlbum::class, $item); - }, $items); - } - - /** - * Set in playlist attribute - * - * @param mixed $item - * - * @return array - */ - protected function setInPlaylistAttribute($item) - { - if (is_array($item) === false) { - return $item; - } - - return $this->getNestedContext(MusicPlaylist::class, $item); - } } diff --git a/src/ContextTypes/Organization.php b/src/ContextTypes/Organization.php index 1490aac..e67d0c9 100644 --- a/src/ContextTypes/Organization.php +++ b/src/ContextTypes/Organization.php @@ -17,49 +17,4 @@ class Organization extends Thing 'hasPOS' => Place::class, ]; - /** - * Set the contactPoints - * - * @param mixed $items - * - * @return array - */ - protected function setContactPointAttribute($items) - { - if (is_array($items) === false) { - return $items; - } - - // Check if it is an array with one dimension - if (is_array(reset($items)) === false) { - return $this->getNestedContext(ContactPoint::class, $items); - } - - //Process multi dimensional array - return array_map(function ($item) { - return $this->getNestedContext(ContactPoint::class, $item); - }, $items); - } - /** - * Set the hasPOS - * - * @param array $items - * @return array - */ - protected function setHasPOSAttribute($items) - { - if (is_array($items) === false) { - return $items; - } - - // Check if it is an array with one dimension - if (is_array(reset($items)) === false) { - return $this->getNestedContext(Place::class, $items); - } - - // Process multi dimensional array - return array_map(function ($item) { - return $this->getNestedContext(Place::class, $item); - }, $items); - } } diff --git a/src/ContextTypes/Product.php b/src/ContextTypes/Product.php index e0b3b3a..1dc870a 100644 --- a/src/ContextTypes/Product.php +++ b/src/ContextTypes/Product.php @@ -32,29 +32,4 @@ class Product extends AbstractContext 'weight' => QuantitativeValue::class, ]; - /** - * Set isSimilarTo attributes. - * - * @param mixed $values - * - * @return mixed - */ - protected function setIsSimilarToAttribute($values) - { - if (is_array($values)) { - foreach ($values as $key => $value) { - $product = new self($value); - - $properties = $product->getProperties(); - - unset($properties['@context']); - - $properties = array_filter($properties, 'strlen'); - - $values[$key] = $properties; - } - } - - return $values; - } } diff --git a/src/ContextTypes/Recipe.php b/src/ContextTypes/Recipe.php index 73c99c1..698923e 100755 --- a/src/ContextTypes/Recipe.php +++ b/src/ContextTypes/Recipe.php @@ -31,21 +31,4 @@ class Recipe extends AbstractContext 'video' => VideoObject::class, ]; - /** - * Set the reviews - * - * @param mixed $items - * - * @return mixed - */ - protected function setReviewAttribute($items) - { - if (is_array($items) === false) { - return $items; - } - - return array_map(function ($item) { - return $this->getNestedContext(Review::class, $item); - }, $items); - } } From b330bf793271347ff2d8f8a91374243fe0de3666 Mon Sep 17 00:00:00 2001 From: Madman-81 Date: Wed, 8 Dec 2021 20:27:58 +0100 Subject: [PATCH 3/6] Restructure existing contexts and make the match the hierarchy of schema.org --- src/ContextTypes/AggregateRating.php | 8 ++--- src/ContextTypes/Article.php | 1 - src/ContextTypes/AudioObject.php | 20 ++++++++++++ src/ContextTypes/Audiobook.php | 6 ++-- src/ContextTypes/Beach.php | 17 +++------- src/ContextTypes/BlogPosting.php | 9 +++--- src/ContextTypes/BreadcrumbList.php | 27 +++------------- src/ContextTypes/CivicStructure.php | 18 +++++++++++ src/ContextTypes/ContactPoint.php | 5 ++- src/ContextTypes/Corporation.php | 3 ++ src/ContextTypes/Duration.php | 11 +++---- src/ContextTypes/Event.php | 5 +-- src/ContextTypes/GeoCoordinates.php | 5 ++- src/ContextTypes/HowTo.php | 20 ++++++++++++ src/ContextTypes/ImageObject.php | 8 ++--- src/ContextTypes/Invoice.php | 6 ++-- src/ContextTypes/ItemList.php | 37 ++++++++++++++++++++++ src/ContextTypes/ListItem.php | 5 ++- src/ContextTypes/LocalBusiness.php | 19 ++++------- src/ContextTypes/MediaObject.php | 1 + src/ContextTypes/MusicAlbum.php | 3 ++ src/ContextTypes/MusicGroup.php | 3 ++ src/ContextTypes/MusicPlaylist.php | 3 ++ src/ContextTypes/MusicRecording.php | 3 ++ src/ContextTypes/NewsArticle.php | 20 +++--------- src/ContextTypes/NutritionInformation.php | 5 ++- src/ContextTypes/Offer.php | 8 ++--- src/ContextTypes/Order.php | 14 ++++---- src/ContextTypes/Organization.php | 7 ++++ src/ContextTypes/Place.php | 4 +++ src/ContextTypes/PostalAddress.php | 5 ++- src/ContextTypes/PriceSpecification.php | 5 ++- src/ContextTypes/Product.php | 9 +++--- src/ContextTypes/QuantitativeValue.php | 5 ++- src/ContextTypes/Rating.php | 5 ++- src/ContextTypes/Recipe.php | 11 +------ src/ContextTypes/Review.php | 12 +++---- src/ContextTypes/Sculpture.php | 3 ++ src/ContextTypes/SearchBox.php | 3 ++ src/ContextTypes/SocialMediaPosting.php | 18 +++++++++++ src/ContextTypes/Thing.php | 1 - src/ContextTypes/VideoObject.php | 18 +++-------- src/ContextTypes/WebPage.php | 8 +++-- src/ContextTypes/WebSite.php | 20 +++--------- tests/ContextTypes/AggregateRatingTest.php | 6 ++++ tests/ContextTypes/WebSiteTest.php | 25 ++++++++++++--- 46 files changed, 289 insertions(+), 166 deletions(-) create mode 100644 src/ContextTypes/AudioObject.php create mode 100644 src/ContextTypes/CivicStructure.php create mode 100644 src/ContextTypes/HowTo.php create mode 100644 src/ContextTypes/ItemList.php create mode 100644 src/ContextTypes/SocialMediaPosting.php diff --git a/src/ContextTypes/AggregateRating.php b/src/ContextTypes/AggregateRating.php index f40ffdc..cabce07 100644 --- a/src/ContextTypes/AggregateRating.php +++ b/src/ContextTypes/AggregateRating.php @@ -2,7 +2,10 @@ namespace JsonLd\ContextTypes; -class AggregateRating extends AbstractContext +/** + * https://schema.org/AggregateRating + */ +class AggregateRating extends Rating { /** * Property structure @@ -11,9 +14,6 @@ class AggregateRating extends AbstractContext */ protected $structure = [ 'reviewCount' => null, - 'ratingValue' => null, - 'bestRating' => null, - 'worstRating' => null, 'ratingCount' => null, 'itemReviewed' => Thing::class, ]; diff --git a/src/ContextTypes/Article.php b/src/ContextTypes/Article.php index d620b73..3d46487 100644 --- a/src/ContextTypes/Article.php +++ b/src/ContextTypes/Article.php @@ -19,7 +19,6 @@ class Article extends CreativeWork 'pageStart' => null, 'pagination' => null, 'wordCount' => null, - 'mainEntityOfPage' => WebPage::class, ]; /** diff --git a/src/ContextTypes/AudioObject.php b/src/ContextTypes/AudioObject.php new file mode 100644 index 0000000..84089f7 --- /dev/null +++ b/src/ContextTypes/AudioObject.php @@ -0,0 +1,20 @@ + MediaObject::class, + 'transcript' => null, + ]; + +} \ No newline at end of file diff --git a/src/ContextTypes/Audiobook.php b/src/ContextTypes/Audiobook.php index 55509b7..b0d0624 100644 --- a/src/ContextTypes/Audiobook.php +++ b/src/ContextTypes/Audiobook.php @@ -3,9 +3,9 @@ namespace JsonLd\ContextTypes; /** - * https://schema.org/BookFormatType + * https://schema.org/Audiobook */ -class Audiobook extends Book +class Audiobook extends AudioObject { /** * Property structure @@ -13,8 +13,6 @@ class Audiobook extends Book * @var array */ protected $structure = [ - 'caption' => MediaObject::class, - 'transcript' => null, 'duration' => Duration::class, 'readBy' => Person::class, ]; diff --git a/src/ContextTypes/Beach.php b/src/ContextTypes/Beach.php index 81d1ecb..21ba6bc 100644 --- a/src/ContextTypes/Beach.php +++ b/src/ContextTypes/Beach.php @@ -2,22 +2,15 @@ namespace JsonLd\ContextTypes; -class Beach extends AbstractContext +/** + * https://schema.org/Beach + */ +class Beach extends CivicStructure { /** * Property structure * * @var array */ - protected $structure = [ - 'name' => null, - 'openingHours' => null, - 'description' => null, - 'image' => null, - 'url' => null, - 'address' => PostalAddress::class, - 'geo' => GeoCoordinates::class, - 'review' => Review::class, - 'aggregateRating' => AggregateRating::class, - ]; + protected $structure = []; } diff --git a/src/ContextTypes/BlogPosting.php b/src/ContextTypes/BlogPosting.php index 8e6f435..519aab3 100644 --- a/src/ContextTypes/BlogPosting.php +++ b/src/ContextTypes/BlogPosting.php @@ -2,14 +2,15 @@ namespace JsonLd\ContextTypes; -class BlogPosting extends Article +/** + * https://schema.org/BlogPosting + */ +class BlogPosting extends SocialMediaPosting { /** * Property structure * * @var array */ - protected $structure = [ - 'sharedContent' => CreativeWork::class, - ]; + protected $structure = []; } \ No newline at end of file diff --git a/src/ContextTypes/BreadcrumbList.php b/src/ContextTypes/BreadcrumbList.php index 59c1cc8..e4f5cab 100644 --- a/src/ContextTypes/BreadcrumbList.php +++ b/src/ContextTypes/BreadcrumbList.php @@ -2,33 +2,16 @@ namespace JsonLd\ContextTypes; -class BreadcrumbList extends AbstractContext +/** + * https://schema.org/BreadcrumbList + */ +class BreadcrumbList extends ItemList { /** * Property structure * * @var array */ - protected $structure = [ - 'itemListElement' => null, - ]; + protected $structure = []; - /** - * Set the canonical URL of the article page. - * - * @param array $items - * - * @return array - */ - protected function setItemListElementAttribute(array $items): array - { - foreach ($items as $pos => $item) { - $items[$pos] = $this->getNestedContext(ListItem::class, [ - 'position' => $pos + 1, - 'item' => $item - ]); - } - - return $items; - } } \ No newline at end of file diff --git a/src/ContextTypes/CivicStructure.php b/src/ContextTypes/CivicStructure.php new file mode 100644 index 0000000..78e5b8c --- /dev/null +++ b/src/ContextTypes/CivicStructure.php @@ -0,0 +1,18 @@ + null, + ]; +} diff --git a/src/ContextTypes/ContactPoint.php b/src/ContextTypes/ContactPoint.php index bf6274e..3706193 100644 --- a/src/ContextTypes/ContactPoint.php +++ b/src/ContextTypes/ContactPoint.php @@ -2,7 +2,10 @@ namespace JsonLd\ContextTypes; -class ContactPoint extends AbstractContext +/** + * https://schema.org/ContactPoint + */ +class ContactPoint extends Thing { /** * Property structure diff --git a/src/ContextTypes/Corporation.php b/src/ContextTypes/Corporation.php index fc196b0..1919f40 100755 --- a/src/ContextTypes/Corporation.php +++ b/src/ContextTypes/Corporation.php @@ -2,6 +2,9 @@ namespace JsonLd\ContextTypes; +/** + * https://schema.org/Corporation + */ class Corporation extends Organization { /** diff --git a/src/ContextTypes/Duration.php b/src/ContextTypes/Duration.php index b63cab6..7695873 100644 --- a/src/ContextTypes/Duration.php +++ b/src/ContextTypes/Duration.php @@ -2,16 +2,15 @@ namespace JsonLd\ContextTypes; -class Duration extends AbstractContext +/** + * https://schema.org/Duration + */ +class Duration extends Thing { /** * Property structure * * @var array */ - protected $structure = [ - 'additionalType' => null, - 'name' => null, - 'image' => null, - ]; + protected $structure = []; } \ No newline at end of file diff --git a/src/ContextTypes/Event.php b/src/ContextTypes/Event.php index ea60ebb..21497ef 100644 --- a/src/ContextTypes/Event.php +++ b/src/ContextTypes/Event.php @@ -2,6 +2,9 @@ namespace JsonLd\ContextTypes; +/** + * https://schema.org/Event + */ class Event extends Thing { /** @@ -10,10 +13,8 @@ class Event extends Thing * @var array */ protected $structure = [ - 'name' => null, 'startDate' => null, 'endDate' => null, - 'url' => null, 'offers' => Offer::class, 'location' => Place::class, ]; diff --git a/src/ContextTypes/GeoCoordinates.php b/src/ContextTypes/GeoCoordinates.php index 6b0c301..c1936d7 100644 --- a/src/ContextTypes/GeoCoordinates.php +++ b/src/ContextTypes/GeoCoordinates.php @@ -2,7 +2,10 @@ namespace JsonLd\ContextTypes; -class GeoCoordinates extends AbstractContext +/** + * https://schema.org/GeoCoordinates + */ +class GeoCoordinates extends Thing { /** * Property structure diff --git a/src/ContextTypes/HowTo.php b/src/ContextTypes/HowTo.php new file mode 100644 index 0000000..d0fec9a --- /dev/null +++ b/src/ContextTypes/HowTo.php @@ -0,0 +1,20 @@ + null, + 'totalTime' => null, + ]; + +} diff --git a/src/ContextTypes/ImageObject.php b/src/ContextTypes/ImageObject.php index dac4fa3..c0d3877 100644 --- a/src/ContextTypes/ImageObject.php +++ b/src/ContextTypes/ImageObject.php @@ -2,7 +2,10 @@ namespace JsonLd\ContextTypes; -class ImageObject extends AbstractContext +/** + * https://schema.org/ImageObject + */ +class ImageObject extends MediaObject { /** * Property structure @@ -10,9 +13,6 @@ class ImageObject extends AbstractContext * @var array */ protected $structure = [ - 'url' => null, - 'height' => null, - 'width' => null, 'caption' => null, 'thumbnail' => ImageObject::class, ]; diff --git a/src/ContextTypes/Invoice.php b/src/ContextTypes/Invoice.php index 65ddce3..97d1dd7 100644 --- a/src/ContextTypes/Invoice.php +++ b/src/ContextTypes/Invoice.php @@ -2,7 +2,10 @@ namespace JsonLd\ContextTypes; -class Invoice extends AbstractContext +/** + * https://schema.org/Invoice + */ +class Invoice extends Thing { /** * Property structure @@ -14,7 +17,6 @@ class Invoice extends AbstractContext 'provider' => Organization::class, 'paymentDueDate' => null, 'paymentStatus' => null, - 'url' => null, 'referencesOrder' => Order::class ]; } diff --git a/src/ContextTypes/ItemList.php b/src/ContextTypes/ItemList.php new file mode 100644 index 0000000..3d35478 --- /dev/null +++ b/src/ContextTypes/ItemList.php @@ -0,0 +1,37 @@ + null, + ]; + + /** + * Set the canonical URL of the article page. + * + * @param array $items + * + * @return array + */ + protected function setItemListElementAttribute(array $items): array + { + foreach ($items as $pos => $item) { + $items[$pos] = $this->getNestedContext(ListItem::class, [ + 'position' => $pos + 1, + 'item' => $item + ]); + } + + return $items; + } +} \ No newline at end of file diff --git a/src/ContextTypes/ListItem.php b/src/ContextTypes/ListItem.php index a611601..38004dc 100644 --- a/src/ContextTypes/ListItem.php +++ b/src/ContextTypes/ListItem.php @@ -2,7 +2,10 @@ namespace JsonLd\ContextTypes; -class ListItem extends AbstractContext +/** + * https://schema.org/ListItem + */ +class ListItem extends Thing { /** * Property structure diff --git a/src/ContextTypes/LocalBusiness.php b/src/ContextTypes/LocalBusiness.php index 07c573d..b7743ff 100644 --- a/src/ContextTypes/LocalBusiness.php +++ b/src/ContextTypes/LocalBusiness.php @@ -2,7 +2,10 @@ namespace JsonLd\ContextTypes; -class LocalBusiness extends AbstractContext +/** + * https://schema.org/LocalBusiness + */ +class LocalBusiness extends Organization { /** * Property structure @@ -10,20 +13,10 @@ class LocalBusiness extends AbstractContext * @var array */ protected $structure = [ - 'name' => null, - 'description' => null, - 'image' => null, - 'telephone' => null, - 'email' => null, 'openingHours' => null, - 'address' => PostalAddress::class, - 'geo' => GeoCoordinates::class, - 'review' => Review::class, - 'aggregateRating' => AggregateRating::class, - 'url' => null, 'priceRange' => null, - 'areaServed' => null, - 'hasMap' => null, + 'geo' => GeoCoordinates::class, //Property of Place + 'hasMap' => null, //Property of Place ]; /** diff --git a/src/ContextTypes/MediaObject.php b/src/ContextTypes/MediaObject.php index 2bbecde..762e69b 100644 --- a/src/ContextTypes/MediaObject.php +++ b/src/ContextTypes/MediaObject.php @@ -36,6 +36,7 @@ class MediaObject extends CreativeWork 'regionsAllowed' => Place::class, 'requiresSubscription' => null, 'startTime' => DateTime::class, + 'thumbnailUrl' => null, 'uploadDate' => DateTime::class, 'width' => QuantitativeValue::class, ]; diff --git a/src/ContextTypes/MusicAlbum.php b/src/ContextTypes/MusicAlbum.php index 89ab1ba..dacedf8 100644 --- a/src/ContextTypes/MusicAlbum.php +++ b/src/ContextTypes/MusicAlbum.php @@ -2,6 +2,9 @@ namespace JsonLd\ContextTypes; +/** + * https://schema.org/MusicAlbum + */ class MusicAlbum extends MusicAbstractContext { /** diff --git a/src/ContextTypes/MusicGroup.php b/src/ContextTypes/MusicGroup.php index c9bbc73..144b2e4 100644 --- a/src/ContextTypes/MusicGroup.php +++ b/src/ContextTypes/MusicGroup.php @@ -2,6 +2,9 @@ namespace JsonLd\ContextTypes; +/** + * https://schema.org/MusicGroup + */ class MusicGroup extends MusicAbstractContext { /** diff --git a/src/ContextTypes/MusicPlaylist.php b/src/ContextTypes/MusicPlaylist.php index 866b934..8433140 100644 --- a/src/ContextTypes/MusicPlaylist.php +++ b/src/ContextTypes/MusicPlaylist.php @@ -2,6 +2,9 @@ namespace JsonLd\ContextTypes; +/** + * https://schema.org/MusicPlaylist + */ class MusicPlaylist extends MusicAbstractContext { /** diff --git a/src/ContextTypes/MusicRecording.php b/src/ContextTypes/MusicRecording.php index d53ed7c..6854eed 100644 --- a/src/ContextTypes/MusicRecording.php +++ b/src/ContextTypes/MusicRecording.php @@ -2,6 +2,9 @@ namespace JsonLd\ContextTypes; +/** + * https://schema.org/MusicRecording + */ class MusicRecording extends MusicAbstractContext { /** diff --git a/src/ContextTypes/NewsArticle.php b/src/ContextTypes/NewsArticle.php index dd5690b..4fbd6a9 100644 --- a/src/ContextTypes/NewsArticle.php +++ b/src/ContextTypes/NewsArticle.php @@ -2,27 +2,17 @@ namespace JsonLd\ContextTypes; -class NewsArticle extends AbstractContext +/** + * https://schema.org/NewsArticle + */ +class NewsArticle extends Article { /** * Property structure * * @var array */ - protected $structure = [ - 'headline' => null, - 'description' => null, - 'url' => null, - 'mainEntityOfPage' => WebPage::class, - 'image' => ImageObject::class, - 'video' => VideoObject::class, - 'dateCreated' => null, - 'dateModified' => null, - 'datePublished' => null, - 'author' => Person::class, - 'publisher' => Organization::class, - 'articleBody' => null, - ]; + protected $structure = []; /** * Set the description attribute. diff --git a/src/ContextTypes/NutritionInformation.php b/src/ContextTypes/NutritionInformation.php index bd21a37..b6b3bb9 100755 --- a/src/ContextTypes/NutritionInformation.php +++ b/src/ContextTypes/NutritionInformation.php @@ -2,7 +2,10 @@ namespace JsonLd\ContextTypes; -class NutritionInformation extends AbstractContext +/** + * https://schema.org/NutritionInformation + */ +class NutritionInformation extends Thing { /** * Property structure diff --git a/src/ContextTypes/Offer.php b/src/ContextTypes/Offer.php index 38ea9c3..e42f120 100644 --- a/src/ContextTypes/Offer.php +++ b/src/ContextTypes/Offer.php @@ -2,6 +2,9 @@ namespace JsonLd\ContextTypes; +/** + * https://schema.org/Offer + */ class Offer extends Thing { /** @@ -10,14 +13,10 @@ class Offer extends Thing * @var array */ protected $structure = [ - 'name' => '', 'itemOffered' => Product::class, 'price' => null, - 'lowPrice' => null, - 'highPrice' => null, 'priceCurrency' => null, 'priceValidUntil' => null, - 'url' => null, 'itemCondition' => null, 'availability' => null, 'eligibleQuantity' => QuantitativeValue::class, @@ -25,4 +24,5 @@ class Offer extends Thing 'validFrom' => null, 'seller' => Organization::class, ]; + } diff --git a/src/ContextTypes/Order.php b/src/ContextTypes/Order.php index 98def4c..71647f0 100644 --- a/src/ContextTypes/Order.php +++ b/src/ContextTypes/Order.php @@ -2,7 +2,10 @@ namespace JsonLd\ContextTypes; -class Order extends AbstractContext +/** + * https://schema.org/Order + */ +class Order extends Thing { /** * Property structure @@ -10,13 +13,12 @@ class Order extends AbstractContext * @var array */ protected $structure = [ - 'merchant' => Organization::class, + 'merchant' => Organization::class, //Not an official attribute 'orderNumber' => null, 'orderStatus' => null, - 'priceCurrency' => null, - 'price' => null, + 'priceCurrency' => null, //Not an official attribute + 'price' => null, //Not an official attribute 'acceptedOffer' => Offer::class, - 'url' => null, - 'priceSpecification.name' => null + 'priceSpecification.name' => null //Not an official attribute ]; } diff --git a/src/ContextTypes/Organization.php b/src/ContextTypes/Organization.php index e67d0c9..0b9786d 100644 --- a/src/ContextTypes/Organization.php +++ b/src/ContextTypes/Organization.php @@ -2,6 +2,9 @@ namespace JsonLd\ContextTypes; +/** + * https://schema.org/Organization + */ class Organization extends Thing { /** @@ -15,6 +18,10 @@ class Organization extends Thing 'contactPoint' => ContactPoint::class, 'email' => null, 'hasPOS' => Place::class, + 'telephone' => null, + 'review' => Review::class, + 'aggregateRating' => AggregateRating::class, + 'areaServed' => null, ]; } diff --git a/src/ContextTypes/Place.php b/src/ContextTypes/Place.php index 4a10d21..53a0fff 100644 --- a/src/ContextTypes/Place.php +++ b/src/ContextTypes/Place.php @@ -2,6 +2,9 @@ namespace JsonLd\ContextTypes; +/** + * https://schema.org/Place + */ class Place extends Thing { /** @@ -13,6 +16,7 @@ class Place extends Thing 'address' => PostalAddress::class, 'review' => Review::class, 'aggregateRating' => AggregateRating::class, + 'geo' => GeoCoordinates::class, ]; } diff --git a/src/ContextTypes/PostalAddress.php b/src/ContextTypes/PostalAddress.php index e9a53d4..0c47282 100644 --- a/src/ContextTypes/PostalAddress.php +++ b/src/ContextTypes/PostalAddress.php @@ -2,7 +2,10 @@ namespace JsonLd\ContextTypes; -class PostalAddress extends AbstractContext +/** + * https://schema.org/PostalAddress + */ +class PostalAddress extends ContactPoint { /** * Property structure diff --git a/src/ContextTypes/PriceSpecification.php b/src/ContextTypes/PriceSpecification.php index 30f2ce3..a806774 100644 --- a/src/ContextTypes/PriceSpecification.php +++ b/src/ContextTypes/PriceSpecification.php @@ -2,7 +2,10 @@ namespace JsonLd\ContextTypes; -class PriceSpecification extends AbstractContext +/** + * https://schema.org/PriceSpecification + */ +class PriceSpecification extends Thing { /** * Property structure diff --git a/src/ContextTypes/Product.php b/src/ContextTypes/Product.php index 1dc870a..21c50b7 100644 --- a/src/ContextTypes/Product.php +++ b/src/ContextTypes/Product.php @@ -2,7 +2,10 @@ namespace JsonLd\ContextTypes; -class Product extends AbstractContext +/** + * https://schema.org/Product + */ +class Product extends Thing { /** * Property structure @@ -10,13 +13,9 @@ class Product extends AbstractContext * @var array */ protected $structure = [ - 'name' => null, - 'description' => null, 'brand' => null, - 'image' => null, 'sku' => null, 'productID' => null, - 'url' => null, 'review' => Review::class, 'aggregateRating' => AggregateRating::class, 'offers' => Offer::class, diff --git a/src/ContextTypes/QuantitativeValue.php b/src/ContextTypes/QuantitativeValue.php index 06fb8ff..ba68fdb 100644 --- a/src/ContextTypes/QuantitativeValue.php +++ b/src/ContextTypes/QuantitativeValue.php @@ -2,7 +2,10 @@ namespace JsonLd\ContextTypes; -class QuantitativeValue extends AbstractContext +/** + * https://schema.org/QuantitativeValue + */ +class QuantitativeValue extends Thing { /** * Property structure diff --git a/src/ContextTypes/Rating.php b/src/ContextTypes/Rating.php index 351418c..659600b 100644 --- a/src/ContextTypes/Rating.php +++ b/src/ContextTypes/Rating.php @@ -2,7 +2,10 @@ namespace JsonLd\ContextTypes; -class Rating extends AbstractContext +/** + * https://schema.org/Rating + */ +class Rating extends Thing { /** * Property structure diff --git a/src/ContextTypes/Recipe.php b/src/ContextTypes/Recipe.php index 698923e..d112411 100755 --- a/src/ContextTypes/Recipe.php +++ b/src/ContextTypes/Recipe.php @@ -5,7 +5,7 @@ /** * https://schema.org/Recipe */ -class Recipe extends AbstractContext +class Recipe extends HowTo { /** * Property structure @@ -13,22 +13,13 @@ class Recipe extends AbstractContext * @var array */ protected $structure = [ - 'name' => null, - 'prepTime' => null, 'cookTime' => null, - 'totalTime' => null, - 'image' => null, 'recipeCategory' => null, - 'description' => null, 'recipeIngredient' => null, 'recipeInstructions' => null, 'recipeYield' => null, 'recipeCuisine' => null, - 'author' => Person::class, 'nutrition' => NutritionInformation::class, - 'aggregateRating' => AggregateRating::class, - 'review' => Review::class, - 'video' => VideoObject::class, ]; } diff --git a/src/ContextTypes/Review.php b/src/ContextTypes/Review.php index 5a3b272..76a8c36 100644 --- a/src/ContextTypes/Review.php +++ b/src/ContextTypes/Review.php @@ -2,7 +2,10 @@ namespace JsonLd\ContextTypes; -class Review extends AbstractContext +/** + * https://schema.org/Review + */ +class Review extends CreativeWork { /** * Property structure @@ -12,12 +15,7 @@ class Review extends AbstractContext protected $structure = [ 'itemReviewed' => Thing::class, 'reviewRating' => Rating::class, - 'aggregateRating' => AggregateRating::class, - 'name' => null, - 'author' => Person::class, 'reviewBody' => null, - 'publisher' => Organization::class, - 'duration' => Duration::class, - 'datePublished' => null, + 'duration' => Duration::class, //Not an official attribute ]; } \ No newline at end of file diff --git a/src/ContextTypes/Sculpture.php b/src/ContextTypes/Sculpture.php index 359e7fe..4c0cda1 100644 --- a/src/ContextTypes/Sculpture.php +++ b/src/ContextTypes/Sculpture.php @@ -2,6 +2,9 @@ namespace JsonLd\ContextTypes; +/** + * https://schema.org/Sculpture + */ class Sculpture extends CreativeWork { /** diff --git a/src/ContextTypes/SearchBox.php b/src/ContextTypes/SearchBox.php index 6dae63b..bf016a2 100644 --- a/src/ContextTypes/SearchBox.php +++ b/src/ContextTypes/SearchBox.php @@ -2,6 +2,9 @@ namespace JsonLd\ContextTypes; +/** + * Not an offical context according to schema.org + */ class SearchBox extends AbstractContext { /** diff --git a/src/ContextTypes/SocialMediaPosting.php b/src/ContextTypes/SocialMediaPosting.php new file mode 100644 index 0000000..c6c68de --- /dev/null +++ b/src/ContextTypes/SocialMediaPosting.php @@ -0,0 +1,18 @@ + CreativeWork::class, + ]; +} \ No newline at end of file diff --git a/src/ContextTypes/Thing.php b/src/ContextTypes/Thing.php index f5172fe..ac9827b 100644 --- a/src/ContextTypes/Thing.php +++ b/src/ContextTypes/Thing.php @@ -17,7 +17,6 @@ class Thing extends AbstractContext 'description' => null, 'image' => ImageObject::class, 'mainEntityOfPage' => WebPage::class, - 'name' => null, 'sameAs' => null, 'url' => null, ]; diff --git a/src/ContextTypes/VideoObject.php b/src/ContextTypes/VideoObject.php index f9fa118..714a28c 100644 --- a/src/ContextTypes/VideoObject.php +++ b/src/ContextTypes/VideoObject.php @@ -2,7 +2,10 @@ namespace JsonLd\ContextTypes; -class VideoObject extends AbstractContext +/** + * https://schema.org/VideoObject + */ +class VideoObject extends MediaObject { /** * Property structure @@ -12,20 +15,7 @@ class VideoObject extends AbstractContext protected $structure = [ 'actor' => Person::class, 'director' => Person::class, - 'associatedArticle' => NewsArticle::class, - 'bitrate' => null, - 'contentSize' => null, - 'contentUrl' => null, - 'duration' => null, - 'embedUrl' => null, - 'url' => null, - 'height' => null, - 'width' => null, - 'uploadDate' => null, 'caption' => null, 'thumbnail' => ImageObject::class, - 'description' => null, - 'thumbnailUrl' => null, - 'name' => null, ]; } diff --git a/src/ContextTypes/WebPage.php b/src/ContextTypes/WebPage.php index 47f6484..11c824d 100644 --- a/src/ContextTypes/WebPage.php +++ b/src/ContextTypes/WebPage.php @@ -2,7 +2,10 @@ namespace JsonLd\ContextTypes; -class WebPage extends AbstractContext +/** + * https://schema.org/WebPage + */ +class WebPage extends CreativeWork { /** * Property structure @@ -10,8 +13,7 @@ class WebPage extends AbstractContext * @var array */ protected $structure = [ - '@id' => null, - 'url' => null, + '@id' => null, //Not an official attribute ]; /** diff --git a/src/ContextTypes/WebSite.php b/src/ContextTypes/WebSite.php index 64e05eb..68971e4 100644 --- a/src/ContextTypes/WebSite.php +++ b/src/ContextTypes/WebSite.php @@ -2,25 +2,15 @@ namespace JsonLd\ContextTypes; -class WebSite extends AbstractContext +/** + * https://schema.org/WebSite + */ +class WebSite extends CreativeWork { /** * Property structure * * @var array */ - protected $structure = [ - 'about' => null, - 'headline' => null, - 'image' => null, - 'name' => null, - 'url' => null, - 'publisher' => Organization::class, - 'keywords' => null, - 'inLanguage' => null, - 'dateCreated' => null, - 'dateModified' => null, - 'datePublished' => null, - 'sameAs' => null, - ]; + protected $structure = []; } \ No newline at end of file diff --git a/tests/ContextTypes/AggregateRatingTest.php b/tests/ContextTypes/AggregateRatingTest.php index ce93264..3bfd144 100644 --- a/tests/ContextTypes/AggregateRatingTest.php +++ b/tests/ContextTypes/AggregateRatingTest.php @@ -31,6 +31,12 @@ public function shouldGetProperties() $this->assertEquals(array_merge([ '@context' => 'http://schema.org', '@type' => 'AggregateRating', + 'name' => '', + 'alternateName' => '', + 'description' => '', + 'image' => '', + 'mainEntityOfPage' => '', + 'url' => '', ], $this->attributes), $context->getProperties()); } } diff --git a/tests/ContextTypes/WebSiteTest.php b/tests/ContextTypes/WebSiteTest.php index 37eca6a..0bbbcce 100644 --- a/tests/ContextTypes/WebSiteTest.php +++ b/tests/ContextTypes/WebSiteTest.php @@ -38,12 +38,29 @@ public function shouldGetProperties() { $context = $this->make(); - $attributesPlus = $this->attributes; - $attributesPlus['@context'] = 'http://schema.org'; - $attributesPlus["@type"] = 'WebSite'; + $attributesPlus = array_merge([ + '@context' => 'http://schema.org', + '@type' => 'WebSite', + 'aggregateRating' => '', + 'alternativeHeadline' => '', + 'author' => '', + 'comment' => '', + 'commentCount' => '', + 'creator' => '', + 'learningResourceType' => '', + 'mainEntity' => '', + 'review' => '', + 'text' => '', + 'thumbnailUrl' => '', + 'video' => '', + 'alternateName' => '', + 'description' => '', + 'mainEntityOfPage' => '', + ], $this->attributes); + $attributesPlus["publisher"]["@type"] = 'Organization'; - $this->assertEquals($context->getProperties(), $attributesPlus); + $this->assertEquals($attributesPlus, $context->getProperties()); } /** From ec0f7c0310b2813787dcf4d4a57898264fb88744 Mon Sep 17 00:00:00 2001 From: Madman-81 Date: Wed, 8 Dec 2021 21:35:49 +0100 Subject: [PATCH 4/6] Add PHPUnit config for code coverage --- phpunit.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/phpunit.xml b/phpunit.xml index 37d6408..3ee773e 100755 --- a/phpunit.xml +++ b/phpunit.xml @@ -15,4 +15,9 @@ ./tests + + + ./src + + \ No newline at end of file From b4445edd580354ada84a38182bf59096a7685ccf Mon Sep 17 00:00:00 2001 From: Madman-81 Date: Wed, 8 Dec 2021 21:39:55 +0100 Subject: [PATCH 5/6] Add Json extension to the list of required packages --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 77acc5b..0197de0 100755 --- a/composer.json +++ b/composer.json @@ -10,7 +10,8 @@ } ], "require": { - "php": "^7.2" + "php": "^7.2", + "ext-json": "*" }, "require-dev": { "phpunit/phpunit": "^8.0", From 7b59f61953cffe5c79bf2a4e8d8dd3ec7755dfaa Mon Sep 17 00:00:00 2001 From: Madman-81 Date: Wed, 8 Dec 2021 22:19:07 +0100 Subject: [PATCH 6/6] Add AggregateOffer --- src/ContextTypes/AbstractContext.php | 5 -- src/ContextTypes/AggregateOffer.php | 18 +++++ src/ContextTypes/Product.php | 2 +- .../ProductAggregateOfferTest.php | 74 +++++++++++++++++++ tests/ContextTypes/ProductTest.php | 1 + 5 files changed, 94 insertions(+), 6 deletions(-) create mode 100644 src/ContextTypes/AggregateOffer.php create mode 100644 tests/ContextTypes/ProductAggregateOfferTest.php diff --git a/src/ContextTypes/AbstractContext.php b/src/ContextTypes/AbstractContext.php index 2af5ef9..920ab33 100644 --- a/src/ContextTypes/AbstractContext.php +++ b/src/ContextTypes/AbstractContext.php @@ -181,11 +181,6 @@ protected function makeProperty(string $key, $property, $value = null) return $nested_context; } - // Map properties to object - if ($property !== null && is_array($property) && is_array($value)) { - return $this->mapProperty($property, $value); - } - // Set value return $value; } diff --git a/src/ContextTypes/AggregateOffer.php b/src/ContextTypes/AggregateOffer.php new file mode 100644 index 0000000..4c54b42 --- /dev/null +++ b/src/ContextTypes/AggregateOffer.php @@ -0,0 +1,18 @@ + null, + 'lowPrice' => null, + 'offerCount' => null, + ]; + +} diff --git a/src/ContextTypes/Product.php b/src/ContextTypes/Product.php index 21c50b7..752bf39 100644 --- a/src/ContextTypes/Product.php +++ b/src/ContextTypes/Product.php @@ -18,7 +18,7 @@ class Product extends Thing 'productID' => null, 'review' => Review::class, 'aggregateRating' => AggregateRating::class, - 'offers' => Offer::class, + 'offers' => [Offer::class, AggregateOffer::class], 'gtin8' => null, 'gtin13' => null, 'gtin14' => null, diff --git a/tests/ContextTypes/ProductAggregateOfferTest.php b/tests/ContextTypes/ProductAggregateOfferTest.php new file mode 100644 index 0000000..3e6f584 --- /dev/null +++ b/tests/ContextTypes/ProductAggregateOfferTest.php @@ -0,0 +1,74 @@ + 'Executive Anvil', + 'category' => 'Droppables / Anvils', + 'model' => 'Acme Exec. Anvil', + 'image' => 'http://www.example.com/anvil_executive.jpg', + 'description' => 'Sleeker than ACME\u0027s Classic Anvil, the Executive Anvil is perfect for the business traveler looking for something to drop from a height.', + 'sku' => '925872', + 'brand' => 'Acme Inc.', + 'aggregateRating' => [ + 'ratingValue' => '4.4', + 'reviewCount' => '89', + ], + 'offers' => [ + '@type' => 'AggregateOffer', + 'offerCount' => '3', + 'lowPrice' => '109.99', + 'highPrice' => '129.99', + 'priceCurrency' => 'USD', + 'priceValidUntil' => '2020-11-05', + 'itemCondition' => 'http://schema.org/UsedCondition', + 'availability' => 'http://schema.org/InStock', + ], + 'isSimilarTo' => [ + [ + '@type' => 'Product', + 'name' => 'Lorem ipsum dolor sit amet.', + 'category' => 'Vestibulum / Duis', + 'model' => 'Quisque at tortor', + 'image' => 'http://www.example.com/lorem_ipsum.jpg', + 'description' => 'Nulla vestibulum augue turpis, a vehicula diam ultrices vitae. Vivamus suscipit id neque ac venenatis. Interdum et malesuada fames ac ante ipsum primis in faucibus.', + 'sku' => '925379', + ], + [ + '@type' => 'Product', + 'name' => 'Donec lorem metus, bibendum ut lacus et, bibendum luctus arcu.', + 'category' => 'Maecenas / Maecenas', + 'model' => 'Pellentesque mollis felis vitae porta dapibus.', + 'image' => 'http://www.example.com/porta_ipsum.jpg', + 'description' => 'Duis tempor velit dui, vel tempor velit posuere eu. Suspendisse rhoncus rhoncus nisl, eu bibendum nunc pharetra at. Quisque dictum diam a tellus ultrices, eu blandit mi auctor.', + 'sku' => '185359', + ], + ] + ]; + + /** + * @test + */ + public function shouldHaveOfferObject() + { + $context = $this->make(); + + $this->assertEquals([ + '@type' => 'AggregateOffer', + 'priceCurrency' => 'USD', + 'offerCount' => '3', + 'lowPrice' => '109.99', + 'highPrice' => '129.99', + 'priceValidUntil' => '2020-11-05', + 'itemCondition' => 'http://schema.org/UsedCondition', + 'availability' => 'http://schema.org/InStock' + ], $context->getProperty('offers')); + } + +} diff --git a/tests/ContextTypes/ProductTest.php b/tests/ContextTypes/ProductTest.php index d98f962..d196c76 100644 --- a/tests/ContextTypes/ProductTest.php +++ b/tests/ContextTypes/ProductTest.php @@ -21,6 +21,7 @@ class ProductTest extends TestCase 'reviewCount' => '89', ], 'offers' => [ + '@type' => 'Offer', 'price' => '119.99', 'priceCurrency' => 'USD', 'priceValidUntil' => '2020-11-05',