Обновление клиента (apps, 3rdparty, install)
This commit is contained in:
+142
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (c) Fusonic GmbH. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE file in the project root for license information.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Fusonic\OpenGraph;
|
||||
|
||||
use Fusonic\OpenGraph\Objects\ObjectBase;
|
||||
use Fusonic\OpenGraph\Objects\Website;
|
||||
use Psr\Http\Client\ClientExceptionInterface;
|
||||
use Psr\Http\Client\ClientInterface;
|
||||
use Psr\Http\Message\RequestFactoryInterface;
|
||||
use Symfony\Component\DomCrawler\Crawler;
|
||||
|
||||
/**
|
||||
* Consumer that extracts Open Graph data from either a URL or an HTML string.
|
||||
*/
|
||||
class Consumer
|
||||
{
|
||||
/**
|
||||
* When enabled, crawler will read content of title and meta description if no
|
||||
* Open Graph data is provided by target page.
|
||||
*/
|
||||
public bool $useFallbackMode = false;
|
||||
|
||||
/**
|
||||
* When enabled, crawler will throw exceptions for some crawling errors like unexpected
|
||||
* Open Graph elements.
|
||||
*/
|
||||
public bool $debug = false;
|
||||
|
||||
/**
|
||||
* @param ClientInterface|null $client a PSR-18 ClientInterface implementation
|
||||
* @param RequestFactoryInterface|null $requestFactory a PSR-17 RequestFactoryInterface implementation
|
||||
*/
|
||||
public function __construct(
|
||||
private ?ClientInterface $client = null,
|
||||
private ?RequestFactoryInterface $requestFactory = null,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches HTML content from the given URL and then crawls it for Open Graph data.
|
||||
*
|
||||
* @param string $url URL to be crawled
|
||||
*
|
||||
* @throws ClientExceptionInterface
|
||||
*/
|
||||
public function loadUrl(string $url): ObjectBase
|
||||
{
|
||||
if (null === $this->client || null === $this->requestFactory) {
|
||||
throw new \LogicException(
|
||||
'To use loadUrl() you must provide $client and $requestFactory when instantiating the consumer.'
|
||||
);
|
||||
}
|
||||
|
||||
$request = $this->requestFactory->createRequest('GET', $url);
|
||||
$response = $this->client->sendRequest($request);
|
||||
|
||||
return $this->loadHtml($response->getBody()->getContents(), $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Crawls the given HTML string for OpenGraph data.
|
||||
*
|
||||
* @param string $html HTML string, usually whole content of crawled web resource
|
||||
* @param string|null $fallbackUrl URL to use when fallback mode is enabled
|
||||
*/
|
||||
public function loadHtml(string $html, ?string $fallbackUrl = null): ObjectBase
|
||||
{
|
||||
// Extract all data that can be found
|
||||
$page = $this->extractOpenGraphData($html);
|
||||
|
||||
// Use the user's URL as fallback
|
||||
if ($this->useFallbackMode && null === $page->url) {
|
||||
$page->url = $fallbackUrl;
|
||||
}
|
||||
|
||||
// Return result
|
||||
return $page;
|
||||
}
|
||||
|
||||
private function extractOpenGraphData(string $content): ObjectBase
|
||||
{
|
||||
$crawler = new Crawler();
|
||||
$crawler->addHtmlContent(content: $content);
|
||||
|
||||
$properties = [];
|
||||
foreach (['name', 'property'] as $t) {
|
||||
// Get all meta-tags starting with "og:"
|
||||
$ogMetaTags = $crawler->filter("meta[{$t}^='og:']");
|
||||
|
||||
// Create clean property array
|
||||
$props = [];
|
||||
|
||||
/** @var \DOMElement $tag */
|
||||
foreach ($ogMetaTags as $tag) {
|
||||
$name = strtolower(trim($tag->getAttribute($t)));
|
||||
$value = trim($tag->getAttribute('content'));
|
||||
$props[] = new Property($name, $value);
|
||||
}
|
||||
|
||||
$properties = array_merge($properties, $props);
|
||||
}
|
||||
|
||||
// Create new object
|
||||
$object = new Website();
|
||||
|
||||
// Assign all properties to the object
|
||||
$object->assignProperties($properties, $this->debug);
|
||||
|
||||
// Fallback for url
|
||||
if ($this->useFallbackMode && null === $object->url) {
|
||||
$urlElement = $crawler->filter("link[rel='canonical']")->first();
|
||||
if ($urlElement->count() > 0) {
|
||||
$object->url = trim($urlElement->attr('href') ?? '');
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback for title
|
||||
if ($this->useFallbackMode && null === $object->title) {
|
||||
$titleElement = $crawler->filter('title')->first();
|
||||
if ($titleElement->count() > 0) {
|
||||
$object->title = trim($titleElement->text());
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback for description
|
||||
if ($this->useFallbackMode && null === $object->description) {
|
||||
$descriptionElement = $crawler->filter("meta[property='description']")->first();
|
||||
if ($descriptionElement->count() > 0) {
|
||||
$object->description = trim($descriptionElement->attr('content') ?? '');
|
||||
}
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (c) Fusonic GmbH. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE file in the project root for license information.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Fusonic\OpenGraph\Elements;
|
||||
|
||||
use Fusonic\OpenGraph\Property;
|
||||
|
||||
/**
|
||||
* An Open Graph audio element.
|
||||
*/
|
||||
class Audio extends ElementBase
|
||||
{
|
||||
/**
|
||||
* The URL of an audio resource associated with the object.
|
||||
*/
|
||||
public ?string $url = null;
|
||||
|
||||
/**
|
||||
* An alternate URL to use if an audio resource requires HTTPS.
|
||||
*/
|
||||
public ?string $secureUrl = null;
|
||||
|
||||
/**
|
||||
* The MIME type of an audio resource associated with the object.
|
||||
*/
|
||||
public ?string $type = null;
|
||||
|
||||
/**
|
||||
* @param string $url URL to the audio file
|
||||
*/
|
||||
public function __construct(string $url)
|
||||
{
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all properties set on this element.
|
||||
*
|
||||
* @return Property[]
|
||||
*/
|
||||
public function getProperties(): array
|
||||
{
|
||||
$properties = [];
|
||||
|
||||
// URL must precede all other properties
|
||||
if (null !== $this->url) {
|
||||
$properties[] = new Property(Property::AUDIO_URL, $this->url);
|
||||
}
|
||||
|
||||
if (null !== $this->secureUrl) {
|
||||
$properties[] = new Property(Property::AUDIO_SECURE_URL, $this->secureUrl);
|
||||
}
|
||||
|
||||
if (null !== $this->type) {
|
||||
$properties[] = new Property(Property::AUDIO_TYPE, $this->type);
|
||||
}
|
||||
|
||||
return $properties;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (c) Fusonic GmbH. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE file in the project root for license information.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Fusonic\OpenGraph\Elements;
|
||||
|
||||
use Fusonic\OpenGraph\Property;
|
||||
|
||||
/**
|
||||
* Abstract base class for all OpenGraph elements (e.g. images, videos etc.).
|
||||
*/
|
||||
abstract class ElementBase
|
||||
{
|
||||
/**
|
||||
* Gets all properties set on this element.
|
||||
*
|
||||
* @return Property[]
|
||||
*/
|
||||
abstract public function getProperties(): array;
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (c) Fusonic GmbH. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE file in the project root for license information.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Fusonic\OpenGraph\Elements;
|
||||
|
||||
use Fusonic\OpenGraph\Property;
|
||||
|
||||
/**
|
||||
* An Open Graph image element.
|
||||
*/
|
||||
class Image extends ElementBase
|
||||
{
|
||||
/**
|
||||
* The URL of an image resource associated with the object.
|
||||
*/
|
||||
public ?string $url = null;
|
||||
|
||||
/**
|
||||
* An alternate URL to use if an image resource requires HTTPS.
|
||||
*/
|
||||
public ?string $secureUrl = null;
|
||||
|
||||
/**
|
||||
* The MIME type of an image resource.
|
||||
*/
|
||||
public ?string $type = null;
|
||||
|
||||
/**
|
||||
* The width of an image resource in pixels.
|
||||
*/
|
||||
public ?int $width = null;
|
||||
|
||||
/**
|
||||
* The height of an image resource in pixels.
|
||||
*/
|
||||
public ?int $height = null;
|
||||
|
||||
/**
|
||||
* Whether the image is user-generated or not.
|
||||
*/
|
||||
public ?bool $userGenerated = null;
|
||||
|
||||
/**
|
||||
* @param string $url URL to the image file
|
||||
*/
|
||||
public function __construct(string $url)
|
||||
{
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all properties set on this element.
|
||||
*
|
||||
* @return Property[]
|
||||
*/
|
||||
public function getProperties(): array
|
||||
{
|
||||
$properties = [];
|
||||
|
||||
// URL must precede all other properties
|
||||
if (null !== $this->url) {
|
||||
$properties[] = new Property(Property::IMAGE_URL, $this->url);
|
||||
}
|
||||
|
||||
if (null !== $this->height) {
|
||||
$properties[] = new Property(Property::IMAGE_HEIGHT, $this->height);
|
||||
}
|
||||
|
||||
if (null !== $this->secureUrl) {
|
||||
$properties[] = new Property(Property::IMAGE_SECURE_URL, $this->secureUrl);
|
||||
}
|
||||
|
||||
if (null !== $this->type) {
|
||||
$properties[] = new Property(Property::IMAGE_TYPE, $this->type);
|
||||
}
|
||||
|
||||
if (null !== $this->width) {
|
||||
$properties[] = new Property(Property::IMAGE_WIDTH, $this->width);
|
||||
}
|
||||
|
||||
if (null !== $this->userGenerated) {
|
||||
$properties[] = new Property(Property::IMAGE_USER_GENERATED, $this->userGenerated);
|
||||
}
|
||||
|
||||
return $properties;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (c) Fusonic GmbH. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE file in the project root for license information.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Fusonic\OpenGraph\Elements;
|
||||
|
||||
use Fusonic\OpenGraph\Property;
|
||||
|
||||
/**
|
||||
* An OpenGraph video element.
|
||||
*/
|
||||
class Video extends ElementBase
|
||||
{
|
||||
/**
|
||||
* The URL of a video resource associated with the object.
|
||||
*/
|
||||
public ?string $url = null;
|
||||
|
||||
/**
|
||||
* An alternate URL to use if a video resource requires HTTPS.
|
||||
*/
|
||||
public ?string $secureUrl = null;
|
||||
|
||||
/**
|
||||
* The MIME type of a video resource associated with the object.
|
||||
*/
|
||||
public ?string $type = null;
|
||||
|
||||
/**
|
||||
* The width of a video resource associated with the object in pixels.
|
||||
*/
|
||||
public ?int $width = null;
|
||||
|
||||
/**
|
||||
* The height of a video resource associated with the object in pixels.
|
||||
*/
|
||||
public ?int $height = null;
|
||||
|
||||
/**
|
||||
* @param string $url URL to the video
|
||||
*/
|
||||
public function __construct(string $url)
|
||||
{
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all properties set on this element.
|
||||
*
|
||||
* @return Property[]
|
||||
*/
|
||||
public function getProperties(): array
|
||||
{
|
||||
$properties = [];
|
||||
|
||||
// URL must precede all other properties
|
||||
if (null !== $this->url) {
|
||||
$properties[] = new Property(Property::VIDEO_URL, $this->url);
|
||||
}
|
||||
|
||||
if (null !== $this->height) {
|
||||
$properties[] = new Property(Property::VIDEO_HEIGHT, $this->height);
|
||||
}
|
||||
|
||||
if (null !== $this->secureUrl) {
|
||||
$properties[] = new Property(Property::VIDEO_SECURE_URL, $this->secureUrl);
|
||||
}
|
||||
|
||||
if (null !== $this->type) {
|
||||
$properties[] = new Property(Property::VIDEO_TYPE, $this->type);
|
||||
}
|
||||
|
||||
if (null !== $this->width) {
|
||||
$properties[] = new Property(Property::VIDEO_WIDTH, $this->width);
|
||||
}
|
||||
|
||||
return $properties;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,355 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (c) Fusonic GmbH. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE file in the project root for license information.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Fusonic\OpenGraph\Objects;
|
||||
|
||||
use Fusonic\OpenGraph\Elements\Audio;
|
||||
use Fusonic\OpenGraph\Elements\Image;
|
||||
use Fusonic\OpenGraph\Elements\Video;
|
||||
use Fusonic\OpenGraph\Property;
|
||||
|
||||
/**
|
||||
* Abstract base class for all Open Graph objects (website, video, ...).
|
||||
*/
|
||||
abstract class ObjectBase
|
||||
{
|
||||
/**
|
||||
* An array of audio resources attached to the object.
|
||||
*
|
||||
* @var Audio[]
|
||||
*/
|
||||
public array $audios = [];
|
||||
|
||||
/**
|
||||
* A short description of the object.
|
||||
*/
|
||||
public ?string $description = null;
|
||||
|
||||
/**
|
||||
* The word that appears before the object's title in a sentence. This is an list of words from 'a', 'an', 'the',
|
||||
* ' "" ', or 'auto'. If 'auto' is chosen, the consumer of the object will chose between 'a' or 'an'. The default is
|
||||
* the blank, "".
|
||||
*/
|
||||
public ?string $determiner = null;
|
||||
|
||||
/**
|
||||
* An array of images attached to the object.
|
||||
*
|
||||
* @var Image[]
|
||||
*/
|
||||
public array $images = [];
|
||||
|
||||
/**
|
||||
* The locale that the object's tags are marked up in, in the format language_TERRITORY.
|
||||
*/
|
||||
public ?string $locale = null;
|
||||
|
||||
/**
|
||||
* An array of alternate locales in which the resource is available.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
public array $localeAlternate = [];
|
||||
|
||||
public ?bool $richAttachment = null;
|
||||
|
||||
/**
|
||||
* An array of URLs of related resources.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
public array $seeAlso = [];
|
||||
|
||||
/**
|
||||
* The name of the web site upon which the object resides.
|
||||
*/
|
||||
public ?string $siteName = null;
|
||||
|
||||
/**
|
||||
* The title of the object as it should appear in the graph.
|
||||
*/
|
||||
public ?string $title = null;
|
||||
|
||||
/**
|
||||
* The type of the object, such as 'article'.
|
||||
*/
|
||||
public ?string $type = null;
|
||||
|
||||
/**
|
||||
* The time when the object was last updated.
|
||||
*/
|
||||
public ?\DateTimeImmutable $updatedTime = null;
|
||||
|
||||
/**
|
||||
* The canonical URL of the object, used as its ID in the graph.
|
||||
*/
|
||||
public ?string $url = null;
|
||||
|
||||
/**
|
||||
* An array of videos attached to the object.
|
||||
*
|
||||
* @var Video[]
|
||||
*/
|
||||
public array $videos = [];
|
||||
|
||||
/**
|
||||
* Assigns all properties given to the this Object instance.
|
||||
*
|
||||
* @param array|Property[] $properties array of all properties to assign
|
||||
* @param bool $debug throw exceptions when parsing or not
|
||||
*
|
||||
* @throws \UnexpectedValueException
|
||||
*/
|
||||
public function assignProperties(array $properties, bool $debug = false): void
|
||||
{
|
||||
foreach ($properties as $property) {
|
||||
$name = $property->key;
|
||||
$value = $property->value;
|
||||
|
||||
switch ($name) {
|
||||
case Property::AUDIO:
|
||||
case Property::AUDIO_URL:
|
||||
$this->audios[] = new Audio($value);
|
||||
break;
|
||||
case Property::AUDIO_SECURE_URL:
|
||||
case Property::AUDIO_TYPE:
|
||||
if (\count($this->audios) > 0) {
|
||||
$this->handleAudioAttribute($this->audios[\count($this->audios) - 1], $name, $value);
|
||||
} elseif ($debug) {
|
||||
throw new \UnexpectedValueException(
|
||||
\sprintf(
|
||||
"Found '%s' property but no audio was found before.",
|
||||
$name
|
||||
)
|
||||
);
|
||||
}
|
||||
break;
|
||||
case Property::DESCRIPTION:
|
||||
if (null === $this->description) {
|
||||
$this->description = $value;
|
||||
}
|
||||
break;
|
||||
case Property::DETERMINER:
|
||||
if (null === $this->determiner) {
|
||||
$this->determiner = $value;
|
||||
}
|
||||
break;
|
||||
case Property::IMAGE:
|
||||
case Property::IMAGE_URL:
|
||||
$this->images[] = new Image($value);
|
||||
break;
|
||||
case Property::IMAGE_HEIGHT:
|
||||
case Property::IMAGE_SECURE_URL:
|
||||
case Property::IMAGE_TYPE:
|
||||
case Property::IMAGE_WIDTH:
|
||||
case Property::IMAGE_USER_GENERATED:
|
||||
if (\count($this->images) > 0) {
|
||||
$this->handleImageAttribute($this->images[\count($this->images) - 1], $name, $value);
|
||||
} elseif ($debug) {
|
||||
throw new \UnexpectedValueException(
|
||||
\sprintf(
|
||||
"Found '%s' property but no image was found before.",
|
||||
$name
|
||||
)
|
||||
);
|
||||
}
|
||||
break;
|
||||
case Property::LOCALE:
|
||||
if (null === $this->locale) {
|
||||
$this->locale = $value;
|
||||
}
|
||||
break;
|
||||
case Property::LOCALE_ALTERNATE:
|
||||
$this->localeAlternate[] = $value;
|
||||
break;
|
||||
case Property::RICH_ATTACHMENT:
|
||||
$this->richAttachment = $this->convertToBoolean($value);
|
||||
break;
|
||||
case Property::SEE_ALSO:
|
||||
$this->seeAlso[] = $value;
|
||||
break;
|
||||
case Property::SITE_NAME:
|
||||
if (null === $this->siteName) {
|
||||
$this->siteName = $value;
|
||||
}
|
||||
break;
|
||||
case Property::TITLE:
|
||||
if (null === $this->title) {
|
||||
$this->title = $value;
|
||||
}
|
||||
break;
|
||||
case Property::UPDATED_TIME:
|
||||
if (null === $this->updatedTime) {
|
||||
$this->updatedTime = $this->convertToDateTime($value);
|
||||
}
|
||||
break;
|
||||
case Property::URL:
|
||||
if (null === $this->url) {
|
||||
$this->url = $value;
|
||||
}
|
||||
break;
|
||||
case Property::VIDEO:
|
||||
case Property::VIDEO_URL:
|
||||
$this->videos[] = new Video($value);
|
||||
break;
|
||||
case Property::VIDEO_HEIGHT:
|
||||
case Property::VIDEO_SECURE_URL:
|
||||
case Property::VIDEO_TYPE:
|
||||
case Property::VIDEO_WIDTH:
|
||||
if (\count($this->videos) > 0) {
|
||||
$this->handleVideoAttribute($this->videos[\count($this->videos) - 1], $name, $value);
|
||||
} elseif ($debug) {
|
||||
throw new \UnexpectedValueException(\sprintf(
|
||||
"Found '%s' property but no video was found before.",
|
||||
$name
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function handleImageAttribute(Image $element, string $name, string $value): void
|
||||
{
|
||||
switch ($name) {
|
||||
case Property::IMAGE_HEIGHT:
|
||||
$element->height = (int) $value;
|
||||
break;
|
||||
case Property::IMAGE_WIDTH:
|
||||
$element->width = (int) $value;
|
||||
break;
|
||||
case Property::IMAGE_TYPE:
|
||||
$element->type = $value;
|
||||
break;
|
||||
case Property::IMAGE_SECURE_URL:
|
||||
$element->secureUrl = $value;
|
||||
break;
|
||||
case Property::IMAGE_USER_GENERATED:
|
||||
$element->userGenerated = $this->convertToBoolean($value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function handleVideoAttribute(Video $element, string $name, string $value): void
|
||||
{
|
||||
switch ($name) {
|
||||
case Property::VIDEO_HEIGHT:
|
||||
$element->height = (int) $value;
|
||||
break;
|
||||
case Property::VIDEO_WIDTH:
|
||||
$element->width = (int) $value;
|
||||
break;
|
||||
case Property::VIDEO_TYPE:
|
||||
$element->type = $value;
|
||||
break;
|
||||
case Property::VIDEO_SECURE_URL:
|
||||
$element->secureUrl = $value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function handleAudioAttribute(Audio $element, string $name, string $value): void
|
||||
{
|
||||
switch ($name) {
|
||||
case Property::AUDIO_TYPE:
|
||||
$element->type = $value;
|
||||
break;
|
||||
case Property::AUDIO_SECURE_URL:
|
||||
$element->secureUrl = $value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected function convertToDateTime(string $value): ?\DateTimeImmutable
|
||||
{
|
||||
try {
|
||||
return new \DateTimeImmutable($value);
|
||||
} catch (\Exception $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected function convertToBoolean(string $value): bool
|
||||
{
|
||||
switch (strtolower($value)) {
|
||||
case '1':
|
||||
case 'true':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all properties set on this object.
|
||||
*
|
||||
* @return Property[]
|
||||
*/
|
||||
public function getProperties(): array
|
||||
{
|
||||
$properties = [];
|
||||
|
||||
foreach ($this->audios as $audio) {
|
||||
$properties = array_merge($properties, $audio->getProperties());
|
||||
}
|
||||
|
||||
if (null !== $this->title) {
|
||||
$properties[] = new Property(Property::TITLE, $this->title);
|
||||
}
|
||||
|
||||
if (null !== $this->description) {
|
||||
$properties[] = new Property(Property::DESCRIPTION, $this->description);
|
||||
}
|
||||
|
||||
if (null !== $this->determiner) {
|
||||
$properties[] = new Property(Property::DETERMINER, $this->determiner);
|
||||
}
|
||||
|
||||
foreach ($this->images as $image) {
|
||||
$properties = array_merge($properties, $image->getProperties());
|
||||
}
|
||||
|
||||
if (null !== $this->locale) {
|
||||
$properties[] = new Property(Property::LOCALE, $this->locale);
|
||||
}
|
||||
|
||||
foreach ($this->localeAlternate as $locale) {
|
||||
$properties[] = new Property(Property::LOCALE_ALTERNATE, $locale);
|
||||
}
|
||||
|
||||
if (null !== $this->richAttachment) {
|
||||
$properties[] = new Property(Property::RICH_ATTACHMENT, (int) $this->richAttachment);
|
||||
}
|
||||
|
||||
foreach ($this->seeAlso as $seeAlso) {
|
||||
$properties[] = new Property(Property::SEE_ALSO, $seeAlso);
|
||||
}
|
||||
|
||||
if (null !== $this->siteName) {
|
||||
$properties[] = new Property(Property::SITE_NAME, $this->siteName);
|
||||
}
|
||||
|
||||
if (null !== $this->type) {
|
||||
$properties[] = new Property(Property::TYPE, $this->type);
|
||||
}
|
||||
|
||||
if (null !== $this->updatedTime) {
|
||||
$properties[] = new Property(Property::UPDATED_TIME, $this->updatedTime->format('c'));
|
||||
}
|
||||
|
||||
if (null !== $this->url) {
|
||||
$properties[] = new Property(Property::URL, $this->url);
|
||||
}
|
||||
|
||||
foreach ($this->videos as $video) {
|
||||
$properties = array_merge($properties, $video->getProperties());
|
||||
}
|
||||
|
||||
return $properties;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (c) Fusonic GmbH. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE file in the project root for license information.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Fusonic\OpenGraph\Objects;
|
||||
|
||||
/**
|
||||
* This object type represents a website. It is a simple object type and uses only common Open Graph properties. For
|
||||
* specific pages within a website, the article object type should be used.
|
||||
*
|
||||
* https://developers.facebook.com/docs/reference/opengraph/object-type/website/
|
||||
*/
|
||||
class Website extends ObjectBase
|
||||
{
|
||||
public const TYPE = 'website';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->type = self::TYPE;
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (c) Fusonic GmbH. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE file in the project root for license information.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Fusonic\OpenGraph;
|
||||
|
||||
/**
|
||||
* Class holding data for a single Open Graph property on a web page.
|
||||
*/
|
||||
class Property
|
||||
{
|
||||
public const AUDIO = 'og:audio';
|
||||
public const AUDIO_SECURE_URL = 'og:audio:secure_url';
|
||||
public const AUDIO_TYPE = 'og:audio:type';
|
||||
public const AUDIO_URL = 'og:audio:url';
|
||||
public const DESCRIPTION = 'og:description';
|
||||
public const DETERMINER = 'og:determiner';
|
||||
public const IMAGE = 'og:image';
|
||||
public const IMAGE_HEIGHT = 'og:image:height';
|
||||
public const IMAGE_SECURE_URL = 'og:image:secure_url';
|
||||
public const IMAGE_TYPE = 'og:image:type';
|
||||
public const IMAGE_URL = 'og:image:url';
|
||||
public const IMAGE_WIDTH = 'og:image:width';
|
||||
public const IMAGE_USER_GENERATED = 'og:image:user_generated';
|
||||
public const LOCALE = 'og:locale';
|
||||
public const LOCALE_ALTERNATE = 'og:locale:alternate';
|
||||
public const RICH_ATTACHMENT = 'og:rich_attachment';
|
||||
public const SEE_ALSO = 'og:see_also';
|
||||
public const SITE_NAME = 'og:site_name';
|
||||
public const TITLE = 'og:title';
|
||||
public const TYPE = 'og:type';
|
||||
public const UPDATED_TIME = 'og:updated_time';
|
||||
public const URL = 'og:url';
|
||||
public const VIDEO = 'og:video';
|
||||
public const VIDEO_HEIGHT = 'og:video:height';
|
||||
public const VIDEO_SECURE_URL = 'og:video:secure_url';
|
||||
public const VIDEO_TYPE = 'og:video:type';
|
||||
public const VIDEO_URL = 'og:video:url';
|
||||
public const VIDEO_WIDTH = 'og:video:width';
|
||||
|
||||
public function __construct(
|
||||
/**
|
||||
* Key of the property without "og:" prefix.
|
||||
*/
|
||||
public string $key,
|
||||
|
||||
/**
|
||||
* Value of the property.
|
||||
*/
|
||||
public mixed $value,
|
||||
) {
|
||||
}
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (c) Fusonic GmbH. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE file in the project root for license information.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Fusonic\OpenGraph;
|
||||
|
||||
use Fusonic\OpenGraph\Objects\ObjectBase;
|
||||
|
||||
/**
|
||||
* Class for generating Open Graph tags from objects.
|
||||
*/
|
||||
class Publisher
|
||||
{
|
||||
public const DOCTYPE_HTML5 = 1;
|
||||
public const DOCTYPE_XHTML = 2;
|
||||
|
||||
/**
|
||||
* Defines the style in which HTML tags should be written. Use one of Publisher::DOCTYPE_HTML5 or
|
||||
* Publisher::DOCTYPE_XHTML.
|
||||
*/
|
||||
public int $doctype = self::DOCTYPE_HTML5;
|
||||
|
||||
/**
|
||||
* Generated HTML tags from the given object.
|
||||
*/
|
||||
public function generateHtml(ObjectBase $object): string
|
||||
{
|
||||
$html = '';
|
||||
$format = '<meta property="%s" content="%s"'.(self::DOCTYPE_XHTML === $this->doctype ? ' />' : '>');
|
||||
|
||||
foreach ($object->getProperties() as $property) {
|
||||
if ('' !== $html) {
|
||||
$html .= "\n";
|
||||
}
|
||||
|
||||
if (null === $property->value) {
|
||||
continue;
|
||||
} elseif ($property->value instanceof \DateTimeInterface) {
|
||||
$value = $property->value->format('c');
|
||||
} elseif (\is_object($property->value)) {
|
||||
throw new \UnexpectedValueException(
|
||||
\sprintf(
|
||||
"Cannot handle value of type '%s' for property '%s'.",
|
||||
\get_class($property->value),
|
||||
$property->key
|
||||
)
|
||||
);
|
||||
} elseif (true === $property->value) {
|
||||
$value = '1';
|
||||
} elseif (false === $property->value) {
|
||||
$value = '0';
|
||||
} else {
|
||||
$value = (string) $property->value;
|
||||
}
|
||||
|
||||
$html .= \sprintf($format, $property->key, htmlspecialchars($value));
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user