Initial Upload

This commit is contained in:
Matt Batchelder
2025-12-02 10:32:59 -05:00
commit 05ce0da296
2240 changed files with 467811 additions and 0 deletions

View File

@@ -0,0 +1,449 @@
<?php
/*
* Copyright (C) 2024 Xibo Signage Ltd
*
* Xibo - Digital Signage - https://xibosignage.com
*
* This file is part of Xibo.
*
* Xibo is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* Xibo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Xibo\Widget\Provider;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Stash\Interfaces\PoolInterface;
use Xibo\Entity\Module;
use Xibo\Entity\Widget;
use Xibo\Factory\MediaFactory;
use Xibo\Helper\SanitizerService;
use Xibo\Support\Sanitizer\SanitizerInterface;
/**
* Xibo default implementation of a Widget Data Provider
*/
class DataProvider implements DataProviderInterface
{
/** @var \Xibo\Factory\MediaFactory */
private $mediaFactory;
/** @var boolean should we use the event? */
private $isUseEvent = false;
/** @var bool Is this data provider handled? */
private $isHandled = false;
/** @var array errors */
private $errors = [];
/** @var array the data */
private $data = [];
/** @var array the metadata */
private $meta = [];
/** @var \Xibo\Entity\Media[] */
private $media = [];
/** @var int the cache ttl in seconds - default to 7 days */
private $cacheTtl = 86400 * 7;
/** @var int the displayId */
private $displayId = 0;
/** @var float the display latitude */
private $latitude;
/** @var float the display longitude */
private $longitude;
/** @var bool Is this data provider in preview mode? */
private $isPreview = false;
/** @var \GuzzleHttp\Client */
private $client;
/** @var null cached property values. */
private $properties = null;
/** @var null cached setting values. */
private $settings = null;
/**
* Constructor
* @param Module $module
* @param Widget $widget
* @param array $guzzleProxy
* @param SanitizerService $sanitizer
* @param PoolInterface $pool
*/
public function __construct(
private readonly Module $module,
private readonly Widget $widget,
private readonly array $guzzleProxy,
private readonly SanitizerService $sanitizer,
private readonly PoolInterface $pool
) {
}
/**
* Set the latitude and longitude for this data provider.
* This is primary used if a widget is display specific
* @param $latitude
* @param $longitude
* @param int $displayId
* @return \Xibo\Widget\Provider\DataProviderInterface
*/
public function setDisplayProperties($latitude, $longitude, int $displayId = 0): DataProviderInterface
{
$this->latitude = $latitude;
$this->longitude = $longitude;
$this->displayId = $displayId;
return $this;
}
/**
* @param \Xibo\Factory\MediaFactory $mediaFactory
* @return \Xibo\Widget\Provider\DataProviderInterface
*/
public function setMediaFactory(MediaFactory $mediaFactory): DataProviderInterface
{
$this->mediaFactory = $mediaFactory;
return $this;
}
/**
* Set whether this data provider is in preview mode
* @param bool $isPreview
* @return DataProviderInterface
*/
public function setIsPreview(bool $isPreview): DataProviderInterface
{
$this->isPreview = $isPreview;
return $this;
}
/**
* @inheritDoc
*/
public function getDataSource(): string
{
return $this->module->type;
}
/**
* @inheritDoc
*/
public function getDataType(): string
{
return $this->module->dataType;
}
/**
* @inheritDoc
*/
public function getDisplayId(): int
{
return $this->displayId ?? 0;
}
/**
* @inheritDoc
*/
public function getDisplayLatitude(): ?float
{
return $this->latitude;
}
/**
* @inheritDoc
*/
public function getDisplayLongitude(): ?float
{
return $this->longitude;
}
/**
* @inheritDoc
*/
public function isPreview(): bool
{
return $this->isPreview;
}
/**
* @inheritDoc
*/
public function getWidgetId(): int
{
return $this->widget->widgetId;
}
/**
* @inheritDoc
*/
public function getProperty(string $property, $default = null)
{
if ($this->properties === null) {
$this->properties = $this->module->getPropertyValues(false);
}
$value = $this->properties[$property] ?? $default;
if (is_integer($default)) {
return intval($value);
} else if (is_numeric($value)) {
return doubleval($value);
}
return $value;
}
/**
* @inheritDoc
*/
public function getSetting(string $setting, $default = null)
{
if ($this->settings === null) {
foreach ($this->module->settings as $item) {
$this->settings[$item->id] = $item->value ?: $item->default;
}
}
return $this->settings[$setting] ?? $default;
}
/**
* Is this data provider handled?
* @return bool
*/
public function isHandled(): bool
{
return $this->isHandled;
}
/**
* @inheritDoc
*/
public function setIsUseEvent(): DataProviderInterface
{
$this->isUseEvent = true;
return $this;
}
/**
* @inheritDoc
*/
public function setIsHandled(): DataProviderInterface
{
$this->isHandled = true;
return $this;
}
/**
* @inheritDoc
*/
public function getData(): array
{
return $this->data;
}
/**
* @inheritDoc
*/
public function getMeta(): array
{
return $this->meta;
}
/**
* Get any errors recorded on this provider
* @return array
*/
public function getErrors(): array
{
return $this->errors;
}
/**
* @inheritDoc
*/
public function getWidgetModifiedDt(): ?Carbon
{
return Carbon::createFromTimestamp($this->widget->modifiedDt);
}
/**
* @inheritDoc
*/
public function addError(string $errorMessage): DataProviderInterface
{
$this->errors[] = $errorMessage;
return $this;
}
/**
* @inheritDoc
*/
public function addItem($item): DataProviderInterface
{
if (!is_array($item) && !is_object($item)) {
throw new \RuntimeException('Item must be an array or an object');
}
if (is_object($item) && !($item instanceof \JsonSerializable)) {
throw new \RuntimeException('Item must be JSON serilizable');
}
$this->data[] = $item;
return $this;
}
/**
* @inheritDoc
*/
public function addItems(array $items): DataProviderInterface
{
foreach ($items as $item) {
$this->addItem($item);
}
return $this;
}
/**
* @inheritDoc
*/
public function addOrUpdateMeta(string $key, $item): DataProviderInterface
{
if (!is_array($item) && (is_object($item) && !$item instanceof \JsonSerializable)) {
throw new \RuntimeException('Item must be an array or a JSON serializable object');
}
$this->meta[$key] = $item;
return $this;
}
/**
* @inheritDoc
*/
public function addImage(string $id, string $url, int $expiresAt): string
{
$media = $this->mediaFactory->queueDownload($id, $url, $expiresAt);
$this->media[] = $media;
return '[[mediaId=' . $media->mediaId . ']]';
}
/**
* @inheritDoc
*/
public function addLibraryFile(int $mediaId): string
{
$media = $this->mediaFactory->getById($mediaId);
$this->media[] = $media;
return '[[mediaId=' . $media->mediaId . ']]';
}
/**
* @return \Xibo\Entity\Media[]
*/
public function getImages(): array
{
return $this->media;
}
/**
* @return int[]
*/
public function getImageIds(): array
{
$mediaIds = [];
foreach ($this->getImages() as $media) {
$mediaIds[] = $media->mediaId;
}
return $mediaIds;
}
/**
* @inheritDoc
*/
public function clearData(): DataProviderInterface
{
$this->media = [];
$this->data = [];
return $this;
}
/**
* @inheritDoc
*/
public function clearMeta(): DataProviderInterface
{
$this->meta = [];
return $this;
}
/**
* @inheritDoc
*/
public function isUseEvent(): bool
{
return $this->isUseEvent;
}
/**
* @inheritDoc
*/
public function setCacheTtl(int $ttlSeconds): DataProviderInterface
{
$this->cacheTtl = $ttlSeconds;
return $this;
}
/**
* @inheritDoc
*/
public function getCacheTtl(): int
{
return $this->cacheTtl;
}
/**
* @inheritDoc
*/
public function getGuzzleClient(array $requestOptions = []): Client
{
if ($this->client === null) {
$this->client = new Client(array_merge($this->guzzleProxy, $requestOptions));
}
return $this->client;
}
/**
* @inheritDoc
*/
public function getPool(): PoolInterface
{
return $this->pool;
}
/**
* @inheritDoc
*/
public function getSanitizer(array $params): SanitizerInterface
{
return $this->sanitizer->getSanitizer($params);
}
}

View File

@@ -0,0 +1,205 @@
<?php
/*
* Copyright (C) 2024 Xibo Signage Ltd
*
* Xibo - Digital Signage - https://xibosignage.com
*
* This file is part of Xibo.
*
* Xibo is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* Xibo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Xibo\Widget\Provider;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Stash\Interfaces\PoolInterface;
use Xibo\Support\Sanitizer\SanitizerInterface;
/**
* Data Provider
* -------------
* A data provider is passed to a Widget which specifies a class in its configuration file
* It should return data for the widget in the formated expected by the widgets datatype
*
* The widget might provid a class for other reasons and wish to use the widget.request.data event
* to supply its data. In which case it should set is `setIsUseEvent()`.
*
* void methods on the data provider are chainable.
*/
interface DataProviderInterface
{
/**
* Get the data source expected by this provider
* This will be the Module type that requested the provider
* @return string
*/
public function getDataSource(): string;
/**
* Get the datatype expected by this provider
* @return string
*/
public function getDataType(): string;
/**
* Get the ID for this display
* @return int
*/
public function getDisplayId(): int;
/**
* Get the latitude for this display
* @return float|null
*/
public function getDisplayLatitude(): ?float;
/**
* Get the longitude for this display
* @return float|null
*/
public function getDisplayLongitude(): ?float;
/**
* Get the preview flag
* @return bool
*/
public function isPreview(): bool;
/**
* Get the ID for this Widget
* @return int
*/
public function getWidgetId(): int;
/**
* Get a configured Guzzle client
* this will have its proxy configuration set and be ready to use.
* @param array $requestOptions An optional array of additional request options.
* @return Client
*/
public function getGuzzleClient(array $requestOptions = []): Client;
/**
* Get a cache pool interface
* this will be a cache pool configured using the CMS settings.
* @return PoolInterface
*/
public function getPool(): PoolInterface;
/**
* Get property
* Properties are set on Widgets and can be things like "feedUrl"
* the property must exist in module properties for this type of widget
* @param string $property The property name
* @param mixed $default An optional default value. The return will be cast to the datatype of this default value.
* @return mixed
*/
public function getProperty(string $property, $default = null);
/**
* Get setting
* Settings are set on Modules and can be things like "apiKey"
* the setting must exist in module settings for this type of widget
* @param string $setting The setting name
* @param mixed $default An optional default value. The return will be cast to the datatype of this default value.
* @return mixed
*/
public function getSetting(string $setting, $default = null);
/**
* Get a Santiziter
* @param array $params key/value array of variable to sanitize
* @return SanitizerInterface
*/
public function getSanitizer(array $params): SanitizerInterface;
/**
* Get the widget modifiedDt
* @return \Carbon\Carbon|null
*/
public function getWidgetModifiedDt(): ?Carbon;
/**
* Indicate that we should use the event mechanism to handle this event.
* @return \Xibo\Widget\Provider\DataProviderInterface
*/
public function setIsUseEvent(): DataProviderInterface;
/**
* Indicate that this data provider has been handled.
* @return DataProviderInterface
*/
public function setIsHandled(): DataProviderInterface;
/**
* Add an error to this data provider, if no other data providers handle this request, the error will be
* thrown as a configuration error.
* @param string $errorMessage
* @return DataProviderInterface
*/
public function addError(string $errorMessage): DataProviderInterface;
/**
* Add an item to the provider
* You should ensure that you provide all properties required by the datatype you are returning
* example data types would be: article, social, event, menu, tabular
* @param array|object $item An array containing the item to render in any templates used by this data provider
* @return \Xibo\Widget\Provider\DataProviderInterface
*/
public function addItem($item): DataProviderInterface;
/**
* Add items to the provider
* You should ensure that you provide all properties required by the datatype you are returning
* example data types would be: article, social, event, menu, tabular
* @param array $items An array containing the item to render in any templates used by this data provider
* @return \Xibo\Widget\Provider\DataProviderInterface
*/
public function addItems(array $items): DataProviderInterface;
/**
* Add metadata to the provider
* This is a key/value array of metadata which should be delivered alongside the data
* @param string $key
* @param mixed $item An array/object containing the metadata, which must be JSON serializable
* @return \Xibo\Widget\Provider\DataProviderInterface
*/
public function addOrUpdateMeta(string $key, $item): DataProviderInterface;
/**
* Add an image to the data provider and return the URL for that image
* @param string $id A unique ID for this image, we recommend adding a module/connector specific prefix
* @param string $url The URL on which this image should be downloaded
* @param int $expiresAt A unix timestamp for when this image should be removed - should be longer than cache ttl
* @return string
* @throws \Xibo\Support\Exception\GeneralException
*/
public function addImage(string $id, string $url, int $expiresAt): string;
/**
* Add a library file
* @param int $mediaId The mediaId for this file.
* @return string
* @throws \Xibo\Support\Exception\GeneralException
*/
public function addLibraryFile(int $mediaId): string;
/**
* Set the cache TTL
* @param int $ttlSeconds The time to live in seconds
* @return \Xibo\Widget\Provider\DataProviderInterface
*/
public function setCacheTtl(int $ttlSeconds): DataProviderInterface;
}

View File

@@ -0,0 +1,97 @@
<?php
/*
* Copyright (C) 2023 Xibo Signage Ltd
*
* Xibo - Digital Signage - https://xibosignage.com
*
* This file is part of Xibo.
*
* Xibo is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* Xibo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Xibo\Widget\Provider;
use Xibo\Entity\Module;
use Xibo\Entity\Widget;
/**
* Xibo's default implementation of the Duration Provider
*/
class DurationProvider implements DurationProviderInterface
{
/** @var Module */
private $module;
/** @var Widget */
private $widget;
/** @var int Duration in seconds */
private $duration;
/** @var bool Has the duration been set? */
private $isDurationSet = false;
/**
* Constructor
* @param Module $module
* @param Widget $widget
*/
public function __construct(Module $module, Widget $widget)
{
$this->module = $module;
$this->widget = $widget;
}
/**
* @inheritDoc
*/
public function setDuration(int $seconds): DurationProviderInterface
{
$this->isDurationSet = true;
$this->duration = $seconds;
return $this;
}
/**
* @inheritDoc
*/
public function getDuration(): int
{
return $this->duration ?? 0;
}
/**
* @inheritDoc
*/
public function isDurationSet(): bool
{
return $this->isDurationSet;
}
/**
* @inheritDoc
*/
public function getModule(): Module
{
return $this->module;
}
/**
* @inheritDoc
*/
public function getWidget(): Widget
{
return $this->widget;
}
}

View File

@@ -0,0 +1,62 @@
<?php
/*
* Copyright (C) 2023 Xibo Signage Ltd
*
* Xibo - Digital Signage - https://xibosignage.com
*
* This file is part of Xibo.
*
* Xibo is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* Xibo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Xibo\Widget\Provider;
use Xibo\Entity\Module;
use Xibo\Entity\Widget;
/**
* A duration provider is used to return the duration for a Widget which has a media file
*/
interface DurationProviderInterface
{
/**
* Get the Module
* @return Module
*/
public function getModule(): Module;
/**
* Get the Widget
* @return Widget
*/
public function getWidget(): Widget;
/**
* Get the duration
* @return int the duration in seconds
*/
public function getDuration(): int;
/**
* Set the duration in seconds
* @param int $seconds the duration in seconds
* @return \Xibo\Widget\Provider\DurationProviderInterface
*/
public function setDuration(int $seconds): DurationProviderInterface;
/**
* @return bool true if the duration has been set
*/
public function isDurationSet(): bool;
}

View File

@@ -0,0 +1,50 @@
<?php
/*
* Copyright (C) 2023 Xibo Signage Ltd
*
* Xibo - Digital Signage - https://xibosignage.com
*
* This file is part of Xibo.
*
* Xibo is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* Xibo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Xibo\Widget\Provider;
/**
* A trait providing the duration for widgets using numItems, durationIsPerItem and itemsPerPage
*/
trait DurationProviderNumItemsTrait
{
public function fetchDuration(DurationProviderInterface $durationProvider): WidgetProviderInterface
{
$this->getLog()->debug('fetchDuration: DurationProviderNumItemsTrait');
// Take some default action to cover the majourity of region specific widgets
// Duration can depend on the number of items per page for some widgets
// this is a legacy way of working, and our preference is to use elements
$numItems = $durationProvider->getWidget()->getOptionValue('numItems', 15);
if ($durationProvider->getWidget()->getOptionValue('durationIsPerItem', 0) == 1 && $numItems > 1) {
// If we have paging involved then work out the page count.
$itemsPerPage = $durationProvider->getWidget()->getOptionValue('itemsPerPage', 0);
if ($itemsPerPage > 0) {
$numItems = ceil($numItems / $itemsPerPage);
}
$durationProvider->setDuration($durationProvider->getWidget()->calculatedDuration * $numItems);
}
return $this;
}
}

View File

@@ -0,0 +1,61 @@
<?php
/*
* Copyright (C) 2023 Xibo Signage Ltd
*
* Xibo - Digital Signage - https://xibosignage.com
*
* This file is part of Xibo.
*
* Xibo is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* Xibo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Xibo\Widget\Provider;
use Psr\Log\LoggerInterface;
use Xibo\Entity\Widget;
/**
* Widget Compatibility Interface should be implemented by custom widget upgrade classes.
* Takes necessary actions to make the existing widgets from v3 compatible with v4.
*
* The schema from and the schema to (currently set to 1 and 2, respectively).
* It also provides a method to save a template to the library in a sub-folder named templates/. This method
* is called whenever a widget is loaded with a different schema version.
*
*/
interface WidgetCompatibilityInterface
{
public function getLog(): LoggerInterface;
public function setLog(LoggerInterface $logger): WidgetCompatibilityInterface;
/**
* Upgrade the given widget to be compatible with the specified schema version.
*
* @param Widget $widget The widget model to upgrade.
* @param int $fromSchema The version of the schema the widget is currently using.
* @param int $toSchema The version of the schema to upgrade the widget to.
* @return bool Whether the upgrade was successful
*/
public function upgradeWidget(Widget $widget, int $fromSchema, int $toSchema): bool;
/**
* Save the given widget template to the templates/ subfolder.
*
* @param string $template The widget template to save.
* @param string $fileName The file name to save the template as.
* @return bool Returns true if the template was saved successfully, false otherwise.
*/
public function saveTemplate(string $template, string $fileName): bool;
}

View File

@@ -0,0 +1,48 @@
<?php
/*
* Copyright (C) 2023 Xibo Signage Ltd
*
* Xibo - Digital Signage - https://xibosignage.com
*
* This file is part of Xibo.
*
* Xibo is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* Xibo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Xibo\Widget\Provider;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
/**
* A trait to set common objects on a Widget Compatibility Interface
*/
trait WidgetCompatibilityTrait
{
private $log;
public function getLog(): LoggerInterface
{
if ($this->log === null) {
$this->log = new NullLogger();
}
return $this->log;
}
public function setLog(LoggerInterface $logger): WidgetCompatibilityInterface
{
$this->log = $logger;
return $this;
}
}

View File

@@ -0,0 +1,97 @@
<?php
/*
* Copyright (C) 2023 Xibo Signage Ltd
*
* Xibo - Digital Signage - http://www.xibo.org.uk
*
* This file is part of Xibo.
*
* Xibo is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* Xibo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Xibo\Widget\Provider;
use Carbon\Carbon;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
* The Widget Provider Interface should be implemented by any Widget which specifies a `class` in its Module
* configuration.
*
* The provider should be modified accordingly before returning $this
*
* If the widget does not need to fetch Data or fetch Duration, then it can return without
* modifying the provider.
*/
interface WidgetProviderInterface
{
public function getLog(): LoggerInterface;
public function setLog(LoggerInterface $logger): WidgetProviderInterface;
/**
* Get the event dispatcher
* @return \Symfony\Component\EventDispatcher\EventDispatcherInterface
*/
public function getDispatcher(): EventDispatcherInterface;
/**
* Set the event dispatcher
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $logger
* @return \Xibo\Widget\Provider\WidgetProviderInterface
*/
public function setDispatcher(EventDispatcherInterface $logger): WidgetProviderInterface;
/**
* Fetch data
* The widget provider must either addItems to the data provider, or indicate that data is provided by
* an event instead by setting isUseEvent()
* If data is to be provided by an event, core will raise the `widget.request.data` event with parameters
* indicating this widget's datatype, name, settings and currently configured options
* @param \Xibo\Widget\Provider\DataProviderInterface $dataProvider
* @return \Xibo\Widget\Provider\WidgetProviderInterface
* @throws \Xibo\Support\Exception\GeneralException
*/
public function fetchData(DataProviderInterface $dataProvider): WidgetProviderInterface;
/**
* Fetch duration
* This is typically only relevant to widgets which have a media file associated, for example video or audio
* in cases where this is not appropriate, return without modifying to use the module default duration from
* module configuration.
* @param \Xibo\Widget\Provider\DurationProviderInterface $durationProvider
* @return \Xibo\Widget\Provider\WidgetProviderInterface
*/
public function fetchDuration(DurationProviderInterface $durationProvider): WidgetProviderInterface;
/**
* Get data cache key
* Use this method to return a cache key for this widget. This is typically only relevant when the data cache
* should be different based on the value of a setting. For example, if the tweetDistance is set on a Twitter
* widget, then the cache should be by displayId. If the cache is always by displayId, then you should supply
* the `dataCacheKey` via module config XML instead.
* @param \Xibo\Widget\Provider\DataProviderInterface $dataProvider
* @return string|null
*/
public function getDataCacheKey(DataProviderInterface $dataProvider): ?string;
/**
* Get data modified date
* Use this method to invalidate cache ahead of its expiry date/time by returning the date/time that the underlying
* data is expected to or has been modified
* @param \Xibo\Widget\Provider\DataProviderInterface $dataProvider
* @return \Carbon\Carbon|null
*/
public function getDataModifiedDt(DataProviderInterface $dataProvider): ?Carbon;
}

View File

@@ -0,0 +1,67 @@
<?php
/*
* Copyright (C) 2023 Xibo Signage Ltd
*
* Xibo - Digital Signage - http://www.xibo.org.uk
*
* This file is part of Xibo.
*
* Xibo is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* Xibo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Xibo\Widget\Provider;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
* A trait to set common objects on a Widget Provider Interface
*/
trait WidgetProviderTrait
{
private $log;
private $dispatcher;
public function getLog(): LoggerInterface
{
if ($this->log === null) {
$this->log = new NullLogger();
}
return $this->log;
}
public function setLog(LoggerInterface $logger): WidgetProviderInterface
{
$this->log = $logger;
return $this;
}
/** @inheritDoc */
public function getDispatcher(): EventDispatcherInterface
{
if ($this->dispatcher === null) {
$this->dispatcher = new EventDispatcher();
}
return $this->dispatcher;
}
/** @inheritDoc */
public function setDispatcher(EventDispatcherInterface $dispatcher): WidgetProviderInterface
{
$this->dispatcher = $dispatcher;
return $this;
}
}

View File

@@ -0,0 +1,48 @@
<?php
/*
* Copyright (C) 2023 Xibo Signage Ltd
*
* Xibo - Digital Signage - https://xibosignage.com
*
* This file is part of Xibo.
*
* Xibo is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* Xibo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Xibo\Widget\Provider;
use Psr\Log\LoggerInterface;
use Xibo\Entity\Module;
use Xibo\Entity\Widget;
/**
* Widget Validator Interface
* --------------------------
* Used to validate the properties of a module after it all of its individual properties and those of its
* template have been validated via their property rules.
*/
interface WidgetValidatorInterface
{
public function getLog(): LoggerInterface;
public function setLog(LoggerInterface $logger): WidgetValidatorInterface;
/**
* Validate the widget provided
* @param Module $module The Module
* @param Widget $widget The Widget - this is read only
* @param string $stage Which stage are we validating, either `save` or `status`
*/
public function validate(Module $module, Widget $widget, string $stage): void;
}

View File

@@ -0,0 +1,48 @@
<?php
/*
* Copyright (C) 2023 Xibo Signage Ltd
*
* Xibo - Digital Signage - https://xibosignage.com
*
* This file is part of Xibo.
*
* Xibo is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* Xibo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Xibo\Widget\Provider;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
/**
* A trait to set common objects on a Widget Compatibility Interface
*/
trait WidgetValidatorTrait
{
private $log;
public function getLog(): LoggerInterface
{
if ($this->log === null) {
$this->log = new NullLogger();
}
return $this->log;
}
public function setLog(LoggerInterface $logger): WidgetValidatorInterface
{
$this->log = $logger;
return $this;
}
}