Initial Upload
This commit is contained in:
196
lib/Widget/Definition/Asset.php
Normal file
196
lib/Widget/Definition/Asset.php
Normal file
@@ -0,0 +1,196 @@
|
||||
<?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\Definition;
|
||||
|
||||
use GuzzleHttp\Psr7\Stream;
|
||||
use Illuminate\Support\Str;
|
||||
use Intervention\Image\ImageManagerStatic as Img;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Slim\Http\Response;
|
||||
use Slim\Http\ServerRequest;
|
||||
use Xibo\Support\Exception\GeneralException;
|
||||
use Xibo\Support\Exception\NotFoundException;
|
||||
use Xibo\Xmds\Entity\Dependency;
|
||||
|
||||
/**
|
||||
* An asset
|
||||
*/
|
||||
class Asset implements \JsonSerializable
|
||||
{
|
||||
public $id;
|
||||
public $type;
|
||||
public $alias;
|
||||
public $path;
|
||||
public $mimeType;
|
||||
|
||||
/** @var bool */
|
||||
public $autoInclude;
|
||||
|
||||
/** @var bool */
|
||||
public $cmsOnly;
|
||||
|
||||
public $assetNo;
|
||||
|
||||
private $fileSize;
|
||||
private $md5;
|
||||
|
||||
/** @inheritDoc */
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'alias' => $this->alias,
|
||||
'type' => $this->type,
|
||||
'path' => $this->path,
|
||||
'mimeType' => $this->mimeType,
|
||||
'cmsOnly' => $this->cmsOnly,
|
||||
'autoInclude' => $this->autoInclude,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Should this asset be sent to the player?
|
||||
* @return bool
|
||||
*/
|
||||
public function isSendToPlayer(): bool
|
||||
{
|
||||
return !($this->cmsOnly ?? false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Should this asset be auto included in the HTML sent to the player
|
||||
* @return bool
|
||||
*/
|
||||
public function isAutoInclude(): bool
|
||||
{
|
||||
return $this->autoInclude && $this->isSendToPlayer();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $libraryLocation
|
||||
* @param bool $forceUpdate
|
||||
* @return $this
|
||||
* @throws GeneralException
|
||||
*/
|
||||
public function updateAssetCache(string $libraryLocation, bool $forceUpdate = false): Asset
|
||||
{
|
||||
// Verify the asset is cached and update its path.
|
||||
$assetPath = $libraryLocation . 'assets/' . $this->getFilename();
|
||||
if (!file_exists($assetPath) || $forceUpdate) {
|
||||
$result = @copy(PROJECT_ROOT . $this->path, $assetPath);
|
||||
if (!$result) {
|
||||
throw new GeneralException('Unable to copy asset');
|
||||
}
|
||||
$forceUpdate = true;
|
||||
}
|
||||
|
||||
// Get the bundle MD5
|
||||
$assetMd5CachePath = $assetPath . '.md5';
|
||||
if (!file_exists($assetMd5CachePath) || $forceUpdate) {
|
||||
$assetMd5 = md5_file($assetPath);
|
||||
file_put_contents($assetMd5CachePath, $assetMd5);
|
||||
} else {
|
||||
$assetMd5 = file_get_contents($assetPath . '.md5');
|
||||
}
|
||||
|
||||
$this->path = $assetPath;
|
||||
$this->md5 = $assetMd5;
|
||||
$this->fileSize = filesize($assetPath);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this asset as a dependency.
|
||||
* @return \Xibo\Xmds\Entity\Dependency
|
||||
* @throws \Xibo\Support\Exception\NotFoundException
|
||||
*/
|
||||
public function getDependency(): Dependency
|
||||
{
|
||||
// Check that this asset is valid.
|
||||
if (!file_exists($this->path)) {
|
||||
throw new NotFoundException(sprintf(__('Asset %s not found'), $this->path));
|
||||
}
|
||||
|
||||
// Return a dependency
|
||||
return new Dependency(
|
||||
'asset',
|
||||
$this->id,
|
||||
$this->getLegacyId(),
|
||||
$this->path,
|
||||
$this->fileSize,
|
||||
$this->md5,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file name for this asset
|
||||
* @return string
|
||||
*/
|
||||
public function getFilename(): string
|
||||
{
|
||||
return basename($this->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a PSR response for this asset.
|
||||
* @throws \Xibo\Support\Exception\NotFoundException
|
||||
*/
|
||||
public function psrResponse(ServerRequest $request, Response $response, string $sendFileMode): ResponseInterface
|
||||
{
|
||||
// Make sure this asset exists
|
||||
if (!file_exists($this->path)) {
|
||||
throw new NotFoundException(__('Asset file does not exist'));
|
||||
}
|
||||
|
||||
$response = $response->withHeader('Content-Length', $this->fileSize);
|
||||
$response = $response->withHeader('Content-Type', $this->mimeType);
|
||||
|
||||
// Output the file
|
||||
if ($sendFileMode === 'Apache') {
|
||||
// Send via Apache X-Sendfile header?
|
||||
$response = $response->withHeader('X-Sendfile', $this->path);
|
||||
} else if ($sendFileMode === 'Nginx') {
|
||||
// Send via Nginx X-Accel-Redirect?
|
||||
$response = $response->withHeader('X-Accel-Redirect', '/download/assets/' . $this->getFilename());
|
||||
} else if (Str::startsWith('image', $this->mimeType)) {
|
||||
$response = Img::make('/' . $this->path)->psrResponse();
|
||||
} else {
|
||||
// Set the right content type.
|
||||
$response = $response->withBody(new Stream(fopen($this->path, 'r')));
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Legacy ID for this asset on older players
|
||||
* there is a risk that this ID will change as modules/templates with assets are added/removed in the system
|
||||
* however, we have mitigated by ensuring that only one instance of any required file is added to rf return
|
||||
* @return int
|
||||
*/
|
||||
private function getLegacyId(): int
|
||||
{
|
||||
return (Dependency::LEGACY_ID_OFFSET_ASSET + $this->assetNo) * -1;
|
||||
}
|
||||
}
|
||||
43
lib/Widget/Definition/Condition.php
Normal file
43
lib/Widget/Definition/Condition.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?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\Definition;
|
||||
|
||||
/**
|
||||
* Represents a condition for a test
|
||||
*/
|
||||
class Condition implements \JsonSerializable
|
||||
{
|
||||
public $field;
|
||||
public $type;
|
||||
public $value;
|
||||
|
||||
/** @inheritDoc */
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return [
|
||||
'field' => $this->field,
|
||||
'type' => $this->type,
|
||||
'value' => $this->value
|
||||
];
|
||||
}
|
||||
}
|
||||
56
lib/Widget/Definition/DataType.php
Normal file
56
lib/Widget/Definition/DataType.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?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\Definition;
|
||||
|
||||
/**
|
||||
* A module data type
|
||||
*/
|
||||
class DataType implements \JsonSerializable
|
||||
{
|
||||
public $id;
|
||||
public $name;
|
||||
|
||||
/** @var \Xibo\Widget\Definition\Field[] */
|
||||
public $fields = [];
|
||||
|
||||
public function addField(string $id, string $title, string $type, bool $isRequired = false): DataType
|
||||
{
|
||||
$field = new Field();
|
||||
$field->id = $id;
|
||||
$field->type = $type;
|
||||
$field->title = $title;
|
||||
$field->isRequired = $isRequired;
|
||||
$this->fields[] = $field;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'fields' => $this->fields,
|
||||
];
|
||||
}
|
||||
}
|
||||
56
lib/Widget/Definition/Element.php
Normal file
56
lib/Widget/Definition/Element.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?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\Definition;
|
||||
|
||||
/**
|
||||
* @SWG\Definition()
|
||||
* A class representing an instance of an element template
|
||||
*/
|
||||
class Element implements \JsonSerializable
|
||||
{
|
||||
public $id;
|
||||
public $top;
|
||||
public $left;
|
||||
public $width;
|
||||
public $height;
|
||||
public $rotation;
|
||||
public $layer;
|
||||
public $elementGroupId;
|
||||
public $properties = [];
|
||||
|
||||
/** @inheritDoc */
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'top' => $this->top,
|
||||
'left' => $this->left,
|
||||
'width' => $this->width,
|
||||
'height' => $this->height,
|
||||
'rotation' => $this->rotation,
|
||||
'layer' => $this->layer,
|
||||
'elementGroupId' => $this->elementGroupId,
|
||||
'properties' => $this->properties
|
||||
];
|
||||
}
|
||||
}
|
||||
56
lib/Widget/Definition/ElementGroup.php
Normal file
56
lib/Widget/Definition/ElementGroup.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?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\Definition;
|
||||
|
||||
/**
|
||||
* A class representing an instance of a group of elements
|
||||
* @SWG\Definition()
|
||||
*/
|
||||
class ElementGroup implements \JsonSerializable
|
||||
{
|
||||
public $id;
|
||||
public $top;
|
||||
public $left;
|
||||
public $width;
|
||||
public $height;
|
||||
public $layer;
|
||||
public $title;
|
||||
public $slot;
|
||||
public $pinSlot;
|
||||
|
||||
/** @inheritDoc */
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'top' => $this->top,
|
||||
'left' => $this->left,
|
||||
'width' => $this->width,
|
||||
'height' => $this->height,
|
||||
'layer' => $this->layer,
|
||||
'title' => $this->title,
|
||||
'slot' => $this->slot,
|
||||
'pinSlot' => $this->pinSlot
|
||||
];
|
||||
}
|
||||
}
|
||||
46
lib/Widget/Definition/Extend.php
Normal file
46
lib/Widget/Definition/Extend.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?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\Definition;
|
||||
|
||||
/**
|
||||
* @SWG\Definition()
|
||||
* A class representing one template extending another
|
||||
*/
|
||||
class Extend implements \JsonSerializable
|
||||
{
|
||||
public $template;
|
||||
public $override;
|
||||
public $with;
|
||||
public $escapeHtml;
|
||||
|
||||
/** @inheritDoc */
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return [
|
||||
'template' => $this->template,
|
||||
'override' => $this->override,
|
||||
'with' => $this->with,
|
||||
'escapeHtml' => $this->escapeHtml,
|
||||
];
|
||||
}
|
||||
}
|
||||
45
lib/Widget/Definition/Field.php
Normal file
45
lib/Widget/Definition/Field.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?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\Definition;
|
||||
|
||||
/**
|
||||
* Class representing a data type field
|
||||
*/
|
||||
class Field implements \JsonSerializable
|
||||
{
|
||||
public $id;
|
||||
public $type;
|
||||
public $title;
|
||||
public $isRequired;
|
||||
|
||||
/** @inheritDoc */
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'type' => $this->type,
|
||||
'title' => $this->title,
|
||||
'isRequired' => $this->isRequired,
|
||||
];
|
||||
}
|
||||
}
|
||||
42
lib/Widget/Definition/LegacyType.php
Normal file
42
lib/Widget/Definition/LegacyType.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?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\Definition;
|
||||
|
||||
/**
|
||||
* A Legacy Type
|
||||
* @SWG\Definition()
|
||||
*/
|
||||
class LegacyType implements \JsonSerializable
|
||||
{
|
||||
public $name;
|
||||
public $condition;
|
||||
|
||||
/** @inheritDoc */
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return [
|
||||
'name' => $this->name,
|
||||
'condition' => $this->condition,
|
||||
];
|
||||
}
|
||||
}
|
||||
67
lib/Widget/Definition/Option.php
Normal file
67
lib/Widget/Definition/Option.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?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\Definition;
|
||||
|
||||
/**
|
||||
* Option: typically used when paired with a dropdown
|
||||
* @SWG\Definition()
|
||||
*/
|
||||
class Option implements \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* @SWG\Property(description="Name")
|
||||
* @var string
|
||||
*/
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* @SWG\Property(description="Image: optional image asset")
|
||||
* @var string
|
||||
*/
|
||||
public $image;
|
||||
|
||||
/**
|
||||
* @SWG\Property(description="Set")
|
||||
* @var string[]
|
||||
*/
|
||||
public $set = [];
|
||||
|
||||
/**
|
||||
* * @SWG\Property(description="Title: shown in the dropdown/select")
|
||||
* @var string
|
||||
*/
|
||||
public $title;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return [
|
||||
'name' => $this->name,
|
||||
'image' => $this->image,
|
||||
'set' => $this->set,
|
||||
'title' => $this->title
|
||||
];
|
||||
}
|
||||
}
|
||||
53
lib/Widget/Definition/PlayerCompatibility.php
Normal file
53
lib/Widget/Definition/PlayerCompatibility.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?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\Definition;
|
||||
|
||||
/**
|
||||
* Player compatibility
|
||||
*/
|
||||
class PlayerCompatibility implements \JsonSerializable
|
||||
{
|
||||
public $windows;
|
||||
public $linux;
|
||||
public $android;
|
||||
public $webos;
|
||||
public $tizen;
|
||||
public $chromeos;
|
||||
public $message;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return [
|
||||
'windows' => $this->windows,
|
||||
'linux' => $this->linux,
|
||||
'android' => $this->android,
|
||||
'webos' => $this->webos,
|
||||
'tizen' => $this->tizen,
|
||||
'chromeos' => $this->chromeos,
|
||||
'message' => $this->message,
|
||||
];
|
||||
}
|
||||
}
|
||||
554
lib/Widget/Definition/Property.php
Normal file
554
lib/Widget/Definition/Property.php
Normal file
@@ -0,0 +1,554 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2025 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\Definition;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Carbon\CarbonInterval;
|
||||
use Illuminate\Support\Str;
|
||||
use Respect\Validation\Validator as v;
|
||||
use Xibo\Support\Exception\InvalidArgumentException;
|
||||
use Xibo\Support\Exception\ValueTooLargeException;
|
||||
use Xibo\Support\Sanitizer\SanitizerInterface;
|
||||
|
||||
/**
|
||||
* A Property
|
||||
* @SWG\Definition()
|
||||
*/
|
||||
class Property implements \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* @SWG\Property(description="ID, saved as a widget option")
|
||||
* @var string
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @SWG\Property(description="Type, determines the field type")
|
||||
* @var string
|
||||
*/
|
||||
public $type;
|
||||
|
||||
/**
|
||||
* @SWG\Property(description="Title: shown in the property panel")
|
||||
* @var string
|
||||
*/
|
||||
public $title;
|
||||
|
||||
/**
|
||||
* @SWG\Property(description="Help Text: shown in the property panel")
|
||||
* @var string
|
||||
*/
|
||||
public $helpText;
|
||||
|
||||
/** @var \Xibo\Widget\Definition\Rule */
|
||||
public $validation;
|
||||
|
||||
/**
|
||||
* @SWG\Property()
|
||||
* @var string An optional default value
|
||||
*/
|
||||
public $default;
|
||||
|
||||
/** @var \Xibo\Widget\Definition\Option[] */
|
||||
public $options;
|
||||
|
||||
/** @var \Xibo\Widget\Definition\Test[] */
|
||||
public $visibility = [];
|
||||
|
||||
/** @var string The element variant */
|
||||
public $variant;
|
||||
|
||||
/** @var string The data format */
|
||||
public $format;
|
||||
|
||||
/** @var bool Should library refs be permitted in the value? */
|
||||
public $allowLibraryRefs = false;
|
||||
|
||||
/** @var bool Should asset refs be permitted in the value? */
|
||||
public $allowAssetRefs = false;
|
||||
|
||||
/** @var bool Should translations be parsed in the value? */
|
||||
public $parseTranslations = false;
|
||||
|
||||
/** @var bool Should the property be included in the XLF? */
|
||||
public $includeInXlf = false;
|
||||
|
||||
/** @var bool Should the property be sent into Elements */
|
||||
public $sendToElements = false;
|
||||
|
||||
/** @var bool Should the default value be written out to widget options */
|
||||
public $saveDefault = false;
|
||||
|
||||
/** @var \Xibo\Widget\Definition\PlayerCompatibility */
|
||||
public $playerCompatibility;
|
||||
|
||||
/** @var string HTML to populate a custom popover to be shown next to the input */
|
||||
public $customPopOver;
|
||||
|
||||
/** @var string HTML selector of the element that this property depends on */
|
||||
public $dependsOn;
|
||||
|
||||
/** @var string ID of the target element */
|
||||
public $target;
|
||||
|
||||
/** @var string The mode of the property */
|
||||
public $mode;
|
||||
|
||||
/** @var string The group ID of the property */
|
||||
public $propertyGroupId;
|
||||
|
||||
/** @var mixed The value assigned to this property. This is set from widget options, or settings, never via XML */
|
||||
public $value;
|
||||
|
||||
/** @inheritDoc */
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'value' => $this->value,
|
||||
'type' => $this->type,
|
||||
'variant' => $this->variant,
|
||||
'format' => $this->format,
|
||||
'title' => $this->title,
|
||||
'mode' => $this->mode,
|
||||
'target' => $this->target,
|
||||
'propertyGroupId' => $this->propertyGroupId,
|
||||
'helpText' => $this->helpText,
|
||||
'validation' => $this->validation,
|
||||
'default' => $this->default,
|
||||
'options' => $this->options,
|
||||
'customPopOver' => $this->customPopOver,
|
||||
'playerCompatibility' => $this->playerCompatibility,
|
||||
'visibility' => $this->visibility,
|
||||
'allowLibraryRefs' => $this->allowLibraryRefs,
|
||||
'allowAssetRefs' => $this->allowAssetRefs,
|
||||
'parseTranslations' => $this->parseTranslations,
|
||||
'saveDefault' => $this->saveDefault,
|
||||
'dependsOn' => $this->dependsOn,
|
||||
'sendToElements' => $this->sendToElements,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an option
|
||||
* @param string $name
|
||||
* @param string $image
|
||||
* @param array $set
|
||||
* @param string $title
|
||||
* @return $this
|
||||
*/
|
||||
public function addOption(string $name, string $image, array $set, string $title): Property
|
||||
{
|
||||
$option = new Option();
|
||||
$option->name = $name;
|
||||
$option->image = $image;
|
||||
$option->set = $set;
|
||||
$option->title = __($title);
|
||||
$this->options[] = $option;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a visibility test
|
||||
* @param string $type
|
||||
* @param string|null $message
|
||||
* @param array $conditions
|
||||
* @return $this
|
||||
*/
|
||||
public function addVisibilityTest(string $type, ?string $message, array $conditions): Property
|
||||
{
|
||||
$this->visibility[] = $this->parseTest($type, $message, $conditions);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Xibo\Support\Sanitizer\SanitizerInterface $params
|
||||
* @param string|null $key
|
||||
* @return \Xibo\Widget\Definition\Property
|
||||
* @throws \Xibo\Support\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function setDefaultByType(SanitizerInterface $params, ?string $key = null): Property
|
||||
{
|
||||
$this->default = $this->getByType($params, $key);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SanitizerInterface $params
|
||||
* @param string|null $key
|
||||
* @param bool $ignoreDefault
|
||||
* @return Property
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function setValueByType(
|
||||
SanitizerInterface $params,
|
||||
?string $key = null,
|
||||
bool $ignoreDefault = false
|
||||
): Property {
|
||||
$value = $this->getByType($params, $key);
|
||||
if ($value !== $this->default || $ignoreDefault || $this->saveDefault) {
|
||||
$this->value = $value;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $properties A key/value array of all properties for this entity (be it module or template)
|
||||
* @param string $stage What stage are we at?
|
||||
* @return Property
|
||||
* @throws InvalidArgumentException
|
||||
* @throws ValueTooLargeException
|
||||
*/
|
||||
public function validate(array $properties, string $stage): Property
|
||||
{
|
||||
if (!empty($this->value) && strlen($this->value) > 67108864) {
|
||||
throw new ValueTooLargeException(sprintf(__('Value too large for %s'), $this->title), $this->id);
|
||||
}
|
||||
|
||||
// Skip if no validation.
|
||||
if ($this->validation === null
|
||||
|| ($stage === 'save' && !$this->validation->onSave)
|
||||
|| ($stage === 'status' && !$this->validation->onStatus)
|
||||
) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
foreach ($this->validation->tests as $test) {
|
||||
// We have a test, evaulate its conditions.
|
||||
$exceptions = [];
|
||||
|
||||
foreach ($test->conditions as $condition) {
|
||||
try {
|
||||
// Assume we're testing the field we belong to, and if that's empty use the default value
|
||||
$testValue = $this->value ?? $this->default;
|
||||
|
||||
// What value are we testing against (only used by certain types)
|
||||
if (empty($condition->field)) {
|
||||
$valueToTestAgainst = $condition->value;
|
||||
} else {
|
||||
// If a field and a condition value is provided, test against those, ignoring my own field value
|
||||
if (!empty($condition->value)) {
|
||||
$testValue = $condition->value;
|
||||
}
|
||||
|
||||
$valueToTestAgainst = $properties[$condition->field] ?? null;
|
||||
}
|
||||
|
||||
// Do we have a message
|
||||
$message = empty($test->message) ? null : __($test->message);
|
||||
|
||||
switch ($condition->type) {
|
||||
case 'required':
|
||||
// We will accept the default value here
|
||||
if (empty($testValue) && empty($this->default)) {
|
||||
throw new InvalidArgumentException(
|
||||
$message ?? sprintf(__('Missing required property %s'), $this->title),
|
||||
$this->id
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'uri':
|
||||
if (!empty($testValue)
|
||||
&& !v::url()->validate($testValue)
|
||||
) {
|
||||
throw new InvalidArgumentException(
|
||||
$message ?? sprintf(__('%s must be a valid URI'), $this->title),
|
||||
$this->id
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'windowsPath':
|
||||
// Ensure the path is a valid Windows file path ending in a file, not a directory
|
||||
$windowsPathRegex = '/^(?P<Root>[A-Za-z]:)(?P<Relative>(?:\\\\[^<>:"\/\\\\|?*\r\n]+)+)(?P<File>\\\\[^<>:"\/\\\\|?*\r\n]+)$/';
|
||||
|
||||
// Check if the test value is not empty and does not match the regular expression
|
||||
if (!empty($testValue)
|
||||
&& !preg_match($windowsPathRegex, $testValue)
|
||||
) {
|
||||
// Throw an InvalidArgumentException if the test value is not a valid Windows path
|
||||
throw new InvalidArgumentException(
|
||||
$message ?? sprintf(__('%s must be a valid Windows path'), $this->title),
|
||||
$this->id
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'interval':
|
||||
if (!empty($testValue)) {
|
||||
// Try to create a date interval from it
|
||||
$dateInterval = CarbonInterval::createFromDateString($testValue);
|
||||
if ($dateInterval === false) {
|
||||
throw new InvalidArgumentException(
|
||||
// phpcs:ignore Generic.Files.LineLength
|
||||
__('That is not a valid date interval, please use natural language such as 1 week'),
|
||||
'customInterval'
|
||||
);
|
||||
}
|
||||
|
||||
// Use now and add the date interval to it
|
||||
$now = Carbon::now();
|
||||
$check = $now->copy()->add($dateInterval);
|
||||
|
||||
if ($now->equalTo($check)) {
|
||||
throw new InvalidArgumentException(
|
||||
// phpcs:ignore Generic.Files.LineLength
|
||||
$message ?? __('That is not a valid date interval, please use natural language such as 1 week'),
|
||||
$this->id
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'eq':
|
||||
if ($testValue != $valueToTestAgainst) {
|
||||
throw new InvalidArgumentException(
|
||||
$message ?? sprintf(__('%s must equal %s'), $this->title, $valueToTestAgainst),
|
||||
$this->id,
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'neq':
|
||||
if ($testValue == $valueToTestAgainst) {
|
||||
throw new InvalidArgumentException(
|
||||
$message ?? sprintf(__('%s must not equal %s'), $this->title, $valueToTestAgainst),
|
||||
$this->id,
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'contains':
|
||||
if (!empty($testValue) && !Str::contains($testValue, $valueToTestAgainst)) {
|
||||
throw new InvalidArgumentException(
|
||||
$message ?? sprintf(__('%s must contain %s'), $this->title, $valueToTestAgainst),
|
||||
$this->id,
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'ncontains':
|
||||
if (!empty($testValue) && Str::contains($testValue, $valueToTestAgainst)) {
|
||||
throw new InvalidArgumentException(
|
||||
// phpcs:ignore Generic.Files.LineLength
|
||||
$message ?? sprintf(__('%s must not contain %s'), $this->title, $valueToTestAgainst),
|
||||
$this->id,
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'lt':
|
||||
// Value must be < to the condition value, or field value
|
||||
if (!($testValue < $valueToTestAgainst)) {
|
||||
throw new InvalidArgumentException(
|
||||
// phpcs:ignore Generic.Files.LineLength
|
||||
$message ?? sprintf(__('%s must be less than %s'), $this->title, $valueToTestAgainst),
|
||||
$this->id
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'lte':
|
||||
// Value must be <= to the condition value, or field value
|
||||
if (!($testValue <= $valueToTestAgainst)) {
|
||||
throw new InvalidArgumentException(
|
||||
// phpcs:ignore Generic.Files.LineLength
|
||||
$message ?? sprintf(__('%s must be less than or equal to %s'), $this->title, $valueToTestAgainst),
|
||||
$this->id
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'gte':
|
||||
// Value must be >= to the condition value, or field value
|
||||
if (!($testValue >= $valueToTestAgainst)) {
|
||||
throw new InvalidArgumentException(
|
||||
// phpcs:ignore Generic.Files.LineLength
|
||||
$message ?? sprintf(__('%s must be greater than or equal to %s'), $this->title, $valueToTestAgainst),
|
||||
$this->id
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'gt':
|
||||
// Value must be > to the condition value, or field value
|
||||
if (!($testValue > $valueToTestAgainst)) {
|
||||
throw new InvalidArgumentException(
|
||||
// phpcs:ignore Generic.Files.LineLength
|
||||
$message ?? sprintf(__('%s must be greater than %s'), $this->title, $valueToTestAgainst),
|
||||
$this->id
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Nothing to validate
|
||||
}
|
||||
} catch (InvalidArgumentException $invalidArgumentException) {
|
||||
// If we are an AND test, all conditions must pass, so we know already to exception here.
|
||||
if ($test->type === 'and') {
|
||||
throw $invalidArgumentException;
|
||||
}
|
||||
|
||||
// We're an OR
|
||||
$exceptions[] = $invalidArgumentException;
|
||||
}
|
||||
}
|
||||
|
||||
// If we are an OR then make sure all conditions have failed.
|
||||
$countOfFailures = count($exceptions);
|
||||
if ($test->type === 'or' && $countOfFailures === count($test->conditions)) {
|
||||
throw $exceptions[0];
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Xibo\Support\Sanitizer\SanitizerInterface $params
|
||||
* @param string|null $key
|
||||
* @return bool|float|int|string|null
|
||||
* @throws \Xibo\Support\Exception\InvalidArgumentException
|
||||
*/
|
||||
private function getByType(SanitizerInterface $params, ?string $key = null)
|
||||
{
|
||||
$key = $key ?: $this->id;
|
||||
|
||||
if (!$params->hasParam($key) && $this->type !== 'checkbox') {
|
||||
// Clear the stored value and therefore use the default
|
||||
return null;
|
||||
}
|
||||
|
||||
// Parse according to the type of field we're expecting
|
||||
switch ($this->type) {
|
||||
case 'checkbox':
|
||||
return $params->getCheckbox($key);
|
||||
|
||||
case 'integer':
|
||||
return $params->getInt($key);
|
||||
|
||||
case 'number':
|
||||
return $params->getDouble($key);
|
||||
|
||||
case 'dropdown':
|
||||
$value = $params->getString($key);
|
||||
if ($value === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$found = false;
|
||||
foreach ($this->options as $option) {
|
||||
if ($option->name === $value) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($found) {
|
||||
return $value;
|
||||
} else {
|
||||
throw new InvalidArgumentException(
|
||||
sprintf(__('%s is not a valid option'), $value),
|
||||
$key
|
||||
);
|
||||
}
|
||||
|
||||
case 'code':
|
||||
case 'richText':
|
||||
return $params->getParam($key);
|
||||
case 'text':
|
||||
if ($this->variant === 'sql') {
|
||||
// Handle raw SQL clauses
|
||||
return str_ireplace(Sql::DISALLOWED_KEYWORDS, '', $params->getParam($key));
|
||||
} else {
|
||||
return $params->getString($key);
|
||||
}
|
||||
default:
|
||||
return $params->getString($key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply any filters on the data.
|
||||
* @return void
|
||||
*/
|
||||
public function applyFilters(): void
|
||||
{
|
||||
if ($this->variant === 'uri' || $this->type === 'commandBuilder') {
|
||||
$this->value = urlencode($this->value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse filters
|
||||
* @return void
|
||||
*/
|
||||
public function reverseFilters(): void
|
||||
{
|
||||
$this->value = $this->reverseFiltersOnValue($this->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function reverseFiltersOnValue(mixed $value): mixed
|
||||
{
|
||||
if (($this->variant === 'uri' || $this->type === 'commandBuilder') && !empty($value)) {
|
||||
$value = urldecode($value);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should this property be represented with CData
|
||||
* @return bool
|
||||
*/
|
||||
public function isCData(): bool
|
||||
{
|
||||
return $this->type === 'code' || $this->type === 'richText';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param string $message
|
||||
* @param array $conditions
|
||||
* @return Test
|
||||
*/
|
||||
public function parseTest(string $type, string $message, array $conditions): Test
|
||||
{
|
||||
$test = new Test();
|
||||
$test->type = $type ?: 'and';
|
||||
$test->message = $message;
|
||||
|
||||
foreach ($conditions as $item) {
|
||||
$condition = new Condition();
|
||||
$condition->type = $item['type'];
|
||||
$condition->field = $item['field'];
|
||||
$condition->value = $item['value'];
|
||||
$test->conditions[] = $condition;
|
||||
}
|
||||
return $test;
|
||||
}
|
||||
}
|
||||
46
lib/Widget/Definition/PropertyGroup.php
Normal file
46
lib/Widget/Definition/PropertyGroup.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?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\Definition;
|
||||
|
||||
/**
|
||||
* A class representing an instance of a group property to put a property in assigned Tab
|
||||
* @SWG\Definition()
|
||||
*/
|
||||
class PropertyGroup implements \JsonSerializable
|
||||
{
|
||||
public $id;
|
||||
public $expanded;
|
||||
public $title;
|
||||
public $helpText;
|
||||
|
||||
/** @inheritDoc */
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'expanded' => $this->expanded,
|
||||
'title' => $this->title,
|
||||
'helpText' => $this->helpText
|
||||
];
|
||||
}
|
||||
}
|
||||
52
lib/Widget/Definition/Rule.php
Normal file
52
lib/Widget/Definition/Rule.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?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\Definition;
|
||||
|
||||
/**
|
||||
* A rule to apply to a property
|
||||
* @SWG\Definition()
|
||||
*/
|
||||
class Rule implements \JsonSerializable
|
||||
{
|
||||
public $onSave = true;
|
||||
|
||||
public $onStatus = true;
|
||||
|
||||
/** @var Test[] */
|
||||
public $tests;
|
||||
|
||||
public function addRuleTest(Test $test): Rule
|
||||
{
|
||||
$this->tests[] = $test;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return [
|
||||
'onSave' => $this->onSave,
|
||||
'onStatus' => $this->onStatus,
|
||||
'tests' => $this->tests,
|
||||
];
|
||||
}
|
||||
}
|
||||
46
lib/Widget/Definition/Sql.php
Normal file
46
lib/Widget/Definition/Sql.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?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\Definition;
|
||||
|
||||
/**
|
||||
* SQL definitions
|
||||
*/
|
||||
class Sql
|
||||
{
|
||||
const DISALLOWED_KEYWORDS = [
|
||||
';',
|
||||
'INSERT',
|
||||
'UPDATE',
|
||||
'SELECT',
|
||||
'FROM',
|
||||
'WHERE',
|
||||
'DELETE',
|
||||
'TRUNCATE',
|
||||
'TABLE',
|
||||
'ALTER',
|
||||
'GRANT',
|
||||
'REVOKE',
|
||||
'CREATE',
|
||||
'DROP',
|
||||
];
|
||||
}
|
||||
80
lib/Widget/Definition/Stencil.php
Normal file
80
lib/Widget/Definition/Stencil.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?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\Definition;
|
||||
|
||||
/**
|
||||
* @SWG\Definition()
|
||||
* A Stencil is a template which is rendered in the server and/or client
|
||||
* it can optionally have properties and/or elements
|
||||
*/
|
||||
class Stencil implements \JsonSerializable
|
||||
{
|
||||
/** @var \Xibo\Widget\Definition\Element[] */
|
||||
public $elements = [];
|
||||
|
||||
/** @var string|null */
|
||||
public $twig;
|
||||
|
||||
/** @var string|null */
|
||||
public $hbs;
|
||||
|
||||
/** @var string|null */
|
||||
public $head;
|
||||
|
||||
/** @var string|null */
|
||||
public $style;
|
||||
|
||||
/** @var string|null */
|
||||
public $hbsId;
|
||||
|
||||
/** @var double Optional positional information if contained as part of an element group */
|
||||
public $width;
|
||||
|
||||
/** @var double Optional positional information if contained as part of an element group */
|
||||
public $height;
|
||||
|
||||
/** @var double Optional positional information if contained as part of an element group */
|
||||
public $gapBetweenHbs;
|
||||
|
||||
/**
|
||||
* @SWG\Property(description="An array of element groups")
|
||||
* @var \Xibo\Widget\Definition\ElementGroup[]
|
||||
*/
|
||||
public $elementGroups = [];
|
||||
|
||||
/** @inheritDoc */
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return [
|
||||
'hbsId' => $this->hbsId,
|
||||
'hbs' => $this->hbs,
|
||||
'head' => $this->head,
|
||||
'style' => $this->style,
|
||||
'width' => $this->width,
|
||||
'height' => $this->height,
|
||||
'gapBetweenHbs' => $this->gapBetweenHbs,
|
||||
'elements' => $this->elements,
|
||||
'elementGroups' => $this->elementGroups
|
||||
];
|
||||
}
|
||||
}
|
||||
49
lib/Widget/Definition/Test.php
Normal file
49
lib/Widget/Definition/Test.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?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\Definition;
|
||||
|
||||
/**
|
||||
* Represents a test/group of conditions
|
||||
* @SWG\Definition()
|
||||
*/
|
||||
class Test implements \JsonSerializable
|
||||
{
|
||||
/** @var string */
|
||||
public $type;
|
||||
|
||||
/** @var Condition[] */
|
||||
public $conditions;
|
||||
|
||||
/** @var string|null */
|
||||
public $message;
|
||||
|
||||
/** @inheritDoc */
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return [
|
||||
'type' => $this->type,
|
||||
'message' => $this->message,
|
||||
'conditions' => $this->conditions,
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user