Files
Cloud-CMS/lib/Entity/ModuleTemplate.php

381 lines
9.7 KiB
PHP
Raw Permalink Normal View History

2025-12-02 10:32:59 -05:00
<?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\Entity;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Xibo\Factory\ModuleTemplateFactory;
use Xibo\Service\LogServiceInterface;
use Xibo\Storage\StorageServiceInterface;
use Xibo\Widget\Definition\Asset;
/**
* Represents a module template
* @SWG\Definition()
*/
class ModuleTemplate implements \JsonSerializable
{
use EntityTrait;
use ModulePropertyTrait;
/** @var int The database ID */
public $id;
/**
* @SWG\Property()
* @var string The templateId
*/
public $templateId;
/**
* @SWG\Property()
* @var string Type of template (static|element|stencil)
*/
public $type;
/**
* @SWG\Property()
* @var \Xibo\Widget\Definition\Extend|null If this template extends another
*/
public $extends;
/**
* @SWG\Property()
* @var string The datatype of this template
*/
public $dataType;
/**
* @SWG\Property()
* @var string The title
*/
public $title;
/**
* @SWG\Property(description="Description of the Module Template")
* @var string
*/
public $description;
/**
* @SWG\Property()
* @var string Icon
*/
public $icon;
/**
* @SWG\Property()
* Thumbnail
* this is the location to a module template's thumbnail, which should be added to the installation
* relative to the module class file.
* @var string
*/
public $thumbnail;
/** @var int The width of the zone */
public $startWidth;
/** @var int The height of the zone */
public $startHeight;
/** @var bool Does this template have dimensions? */
public $hasDimensions;
/** @var bool Can this template be rotated? */
public $canRotate;
/**
* @SWG\Property(description="A flag indicating whether the template should be excluded from the Layout Editor")
* @var string
*/
public $showIn = 'both';
/**
* @SWG\Property()
* @var \Xibo\Widget\Definition\Property[]|null Properties
*/
public $properties;
/**
* @SWG\Property()
* @var bool Is Visible?
*/
public $isVisible = true;
/**
* @SWG\Property()
* @var bool Is Enabled?
*/
public $isEnabled = true;
/**
* @SWG\Property(description="An array of additional module specific group properties")
* @var \Xibo\Widget\Definition\PropertyGroup[]
*/
public $propertyGroups = [];
/**
* @SWG\Property()
* @var \Xibo\Widget\Definition\Stencil|null A stencil, if needed
*/
public $stencil;
/**
* @SWG\Property()
* @var Asset[]
*/
public $assets;
/** @var string A Renderer to run if custom rendering is required. */
public $onTemplateRender;
/** @var string JavaScript function run when the template becomes visible. */
public $onTemplateVisible;
/** @var string A data parser for elements */
public $onElementParseData;
/** @var bool $isError Does this module have any errors? */
public $isError;
/** @var string[] $errors An array of errors this module has. */
public $errors;
/** @var string $ownership Who owns this file? system|custom|user */
public $ownership;
/** @var int $ownerId User ID of the owner of this template */
public $ownerId;
/**
* @SWG\Property(description="A comma separated list of groups/users with permissions to this template")
* @var string
*/
public $groupsWithPermissions;
/** @var string $xml The XML used to build this template */
private $xml;
/** @var \DOMDocument The DOM Document for this templates XML */
private $document;
/** @var \Xibo\Factory\ModuleTemplateFactory */
private $moduleTemplateFactory;
/**
* Entity constructor.
* @param \Xibo\Storage\StorageServiceInterface $store
* @param LogServiceInterface $log
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher
* @param \Xibo\Factory\ModuleTemplateFactory $moduleTemplateFactory
* @param string $file The file this template resides in
*/
public function __construct(
StorageServiceInterface $store,
LogServiceInterface $log,
EventDispatcherInterface $dispatcher,
ModuleTemplateFactory $moduleTemplateFactory,
private readonly string $file
) {
$this->setCommonDependencies($store, $log, $dispatcher);
$this->setPermissionsClass('Xibo\Entity\ModuleTemplate');
$this->moduleTemplateFactory = $moduleTemplateFactory;
}
public function getId()
{
return $this->id;
}
public function getOwnerId()
{
return $this->ownerId;
}
public function __clone()
{
$this->id = null;
$this->templateId = null;
}
/**
* Get assets
* @return \Xibo\Widget\Definition\Asset[]
*/
public function getAssets(): array
{
return $this->assets;
}
/**
* Set XML for this Module Template
* @param string $xml
* @return void
*/
public function setXml(string $xml): void
{
$this->xml = $xml;
}
/**
* Get XML for this Module Template
* @return string
*/
public function getXml(): string
{
// for system templates
if ($this->file !== 'database') {
$xml = new \DOMDocument();
// load whole file to document
$xml->loadXML(file_get_contents($this->file));
// go through template tags
foreach ($xml->getElementsByTagName('template') as $templateXml) {
if ($templateXml instanceof \DOMElement) {
foreach ($templateXml->childNodes as $childNode) {
if ($childNode instanceof \DOMElement) {
// match the template to what was requested
// set the xml and return it.
if ($childNode->nodeName === 'id' && $childNode->nodeValue == $this->templateId) {
$this->setXml($xml->saveXML($templateXml));
}
}
}
}
}
}
return $this->xml;
}
/**
* Set Document
* @param \DOMDocument $document
* @return void
*/
public function setDocument(\DOMDocument $document): void
{
$this->document = $document;
}
/**
* Get this templates DOM document
* @return \DOMDocument
*/
public function getDocument(): \DOMDocument
{
if ($this->document === null) {
$this->document = new \DOMDocument();
$this->document->load($this->getXml());
}
return $this->document;
}
/**
* Save
* @return void
*/
public function save(): void
{
if ($this->file === 'database') {
if ($this->id === null) {
$this->add();
} else {
$this->edit();
}
}
}
/**
* Delete
* @return void
*/
public function delete(): void
{
if ($this->file === 'database') {
$this->getStore()->update('DELETE FROM module_templates WHERE id = :id', [
'id' => $this->id
]);
}
}
/**
* Invalidate this module template for any widgets that use it
* @return void
*/
public function invalidate(): void
{
// TODO: can we improve this via the event mechanism instead?
$this->getStore()->update('
UPDATE `widget` SET modifiedDt = :now
WHERE widgetId IN (
SELECT widgetId
FROM widgetoption
WHERE `option` = \'templateId\'
AND `value` = :templateId
)
', [
'now' => time(),
'templateId' => $this->templateId,
]);
}
/**
* Add
* @return void
*/
private function add(): void
{
$this->id = $this->getStore()->insert('
INSERT INTO `module_templates` (`templateId`, `dataType`, `xml`, `ownerId`)
VALUES (:templateId, :dataType, :xml, :ownerId)
', [
'templateId' => $this->templateId,
'dataType' => $this->dataType,
'xml' => $this->xml,
'ownerId' => $this->ownerId,
]);
}
/**
* Edit
* @return void
*/
private function edit(): void
{
$this->getStore()->update('
UPDATE `module_templates` SET
`templateId` = :templateId,
`dataType`= :dataType,
`enabled` = :enabled,
`xml` = :xml,
`ownerId` = :ownerId
WHERE `id` = :id
', [
'templateId' => $this->templateId,
'dataType' => $this->dataType,
'xml' => $this->xml,
'enabled' => $this->isEnabled ? 1 : 0,
'ownerId' => $this->ownerId,
'id' => $this->id,
]);
}
}