465 lines
15 KiB
PHP
465 lines
15 KiB
PHP
<?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\Controller;
|
|
|
|
use Psr\Http\Message\ResponseInterface;
|
|
use Slim\Http\Response as Response;
|
|
use Slim\Http\ServerRequest as Request;
|
|
use Xibo\Factory\ModuleFactory;
|
|
use Xibo\Factory\ModuleTemplateFactory;
|
|
use Xibo\Storage\StorageServiceInterface;
|
|
use Xibo\Support\Exception\AccessDeniedException;
|
|
use Xibo\Support\Exception\ControllerNotImplemented;
|
|
use Xibo\Support\Exception\GeneralException;
|
|
use Xibo\Support\Exception\InvalidArgumentException;
|
|
use Xibo\Support\Exception\NotFoundException;
|
|
|
|
/**
|
|
* Class Module
|
|
* @package Xibo\Controller
|
|
*/
|
|
class Module extends Base
|
|
{
|
|
/** @var ModuleFactory */
|
|
private $moduleFactory;
|
|
|
|
/** @var \Xibo\Factory\ModuleTemplateFactory */
|
|
private $moduleTemplateFactory;
|
|
|
|
/**
|
|
* Set common dependencies.
|
|
* @param StorageServiceInterface $store
|
|
* @param ModuleFactory $moduleFactory
|
|
*/
|
|
public function __construct(
|
|
ModuleFactory $moduleFactory,
|
|
ModuleTemplateFactory $moduleTemplateFactory
|
|
) {
|
|
$this->moduleFactory = $moduleFactory;
|
|
$this->moduleTemplateFactory = $moduleTemplateFactory;
|
|
}
|
|
|
|
/**
|
|
* Display the module page
|
|
* @param Request $request
|
|
* @param Response $response
|
|
* @return \Psr\Http\Message\ResponseInterface|Response
|
|
* @throws GeneralException
|
|
* @throws \Xibo\Support\Exception\ControllerNotImplemented
|
|
*/
|
|
public function displayPage(Request $request, Response $response)
|
|
{
|
|
$this->getState()->template = 'module-page';
|
|
|
|
return $this->render($request, $response);
|
|
}
|
|
|
|
/**
|
|
* @SWG\Get(
|
|
* path="/module",
|
|
* operationId="moduleSearch",
|
|
* tags={"module"},
|
|
* summary="Module Search",
|
|
* description="Get a list of all modules available to this CMS",
|
|
* @SWG\Response(
|
|
* response=200,
|
|
* description="successful operation",
|
|
* @SWG\Schema(ref="#/definitions/Module")
|
|
* )
|
|
* )
|
|
* @param Request $request
|
|
* @param Response $response
|
|
* @return \Psr\Http\Message\ResponseInterface|Response
|
|
* @throws GeneralException
|
|
* @throws NotFoundException
|
|
* @throws \Xibo\Support\Exception\ControllerNotImplemented
|
|
*/
|
|
public function grid(Request $request, Response $response)
|
|
{
|
|
$parsedQueryParams = $this->getSanitizer($request->getQueryParams());
|
|
|
|
$filter = [
|
|
'name' => $parsedQueryParams->getString('name'),
|
|
'extension' => $parsedQueryParams->getString('extension'),
|
|
'moduleId' => $parsedQueryParams->getInt('moduleId')
|
|
];
|
|
|
|
$modules = $this->moduleFactory->getAllExceptCanvas($filter);
|
|
|
|
foreach ($modules as $module) {
|
|
/* @var \Xibo\Entity\Module $module */
|
|
|
|
if ($this->isApi($request)) {
|
|
break;
|
|
}
|
|
|
|
$module->includeProperty('buttons');
|
|
|
|
// Edit button
|
|
$module->buttons[] = [
|
|
'id' => 'module_button_edit',
|
|
'url' => $this->urlFor($request, 'module.settings.form', ['id' => $module->moduleId]),
|
|
'text' => __('Configure')
|
|
];
|
|
|
|
// Clear cache
|
|
if ($module->regionSpecific == 1) {
|
|
$module->buttons[] = [
|
|
'id' => 'module_button_clear_cache',
|
|
'url' => $this->urlFor($request, 'module.clear.cache.form', ['id' => $module->moduleId]),
|
|
'text' => __('Clear Cache'),
|
|
'dataAttributes' => [
|
|
['name' => 'auto-submit', 'value' => true],
|
|
[
|
|
'name' => 'commit-url',
|
|
'value' => $this->urlFor($request, 'module.clear.cache', ['id' => $module->moduleId])
|
|
],
|
|
['name' => 'commit-method', 'value' => 'PUT']
|
|
]
|
|
];
|
|
}
|
|
}
|
|
|
|
$this->getState()->template = 'grid';
|
|
$this->getState()->recordsTotal = 0;
|
|
$this->getState()->setData($modules);
|
|
|
|
return $this->render($request, $response);
|
|
}
|
|
|
|
// phpcs:disable
|
|
/**
|
|
* @SWG\Get(
|
|
* path="/module/properties/{id}",
|
|
* operationId="getModuleProperties",
|
|
* tags={"module"},
|
|
* summary="Get Module Properties",
|
|
* description="Get a module properties which are needed to for the editWidget call",
|
|
* @SWG\Parameter(
|
|
* name="id",
|
|
* in="path",
|
|
* description="The ModuleId",
|
|
* type="string",
|
|
* required=true
|
|
* ),
|
|
* @SWG\Response(
|
|
* response=200,
|
|
* description="successful operation",
|
|
* @SWG\Schema(ref="#/definitions/Property")
|
|
* )
|
|
* )
|
|
* @param Request $request
|
|
* @param Response $response
|
|
* @param $id
|
|
* @return \Psr\Http\Message\ResponseInterface|Response
|
|
* @throws AccessDeniedException
|
|
* @throws GeneralException
|
|
* @throws NotFoundException
|
|
* @throws \Xibo\Support\Exception\ControllerNotImplemented
|
|
*/
|
|
// phpcs:enable
|
|
public function getProperties(Request $request, Response $response, $id)
|
|
{
|
|
// Get properties, but return a key->value object for easy parsing.
|
|
$props = [];
|
|
foreach ($this->moduleFactory->getById($id)->properties as $property) {
|
|
$props[$property->id] = [
|
|
'type' => $property->type,
|
|
'title' => $property->title,
|
|
'helpText' => $property->helpText,
|
|
'options' => $property->options,
|
|
];
|
|
}
|
|
|
|
$this->getState()->setData($props);
|
|
return $this->render($request, $response);
|
|
}
|
|
|
|
/**
|
|
* Settings Form
|
|
* @param Request $request
|
|
* @param Response $response
|
|
* @param $id
|
|
* @return \Psr\Http\Message\ResponseInterface|Response
|
|
* @throws AccessDeniedException
|
|
* @throws GeneralException
|
|
* @throws NotFoundException
|
|
* @throws \Xibo\Support\Exception\ControllerNotImplemented
|
|
*/
|
|
public function settingsForm(Request $request, Response $response, $id)
|
|
{
|
|
// Can we edit?
|
|
if (!$this->getUser()->userTypeId == 1) {
|
|
throw new AccessDeniedException();
|
|
}
|
|
|
|
$module = $this->moduleFactory->getById($id);
|
|
|
|
// Pass to view
|
|
$this->getState()->template = 'module-form-settings';
|
|
$this->getState()->setData([
|
|
'moduleId' => $id,
|
|
'module' => $module,
|
|
]);
|
|
|
|
return $this->render($request, $response);
|
|
}
|
|
|
|
/**
|
|
* Settings
|
|
* @param Request $request
|
|
* @param Response $response
|
|
* @param $id
|
|
* @return \Psr\Http\Message\ResponseInterface|Response
|
|
* @throws AccessDeniedException
|
|
* @throws GeneralException
|
|
* @throws NotFoundException
|
|
* @throws \Xibo\Support\Exception\ControllerNotImplemented
|
|
*/
|
|
public function settings(Request $request, Response $response, $id)
|
|
{
|
|
if (!$this->getUser()->isSuperAdmin()) {
|
|
throw new AccessDeniedException();
|
|
}
|
|
|
|
$sanitizedParams = $this->getSanitizer($request->getParams());
|
|
|
|
// Get the module
|
|
$module = $this->moduleFactory->getById($id);
|
|
|
|
// Default settings
|
|
$module->enabled = $sanitizedParams->getCheckbox('enabled');
|
|
$module->previewEnabled = $sanitizedParams->getCheckbox('previewEnabled');
|
|
$module->defaultDuration = $sanitizedParams->getInt('defaultDuration');
|
|
|
|
// Parse out any settings we ought to expect.
|
|
foreach ($module->settings as $setting) {
|
|
$setting->setValueByType($sanitizedParams, null, true);
|
|
}
|
|
|
|
// Preview is not allowed for generic file type
|
|
if ($module->allowPreview === 0 && $sanitizedParams->getCheckbox('previewEnabled') == 1) {
|
|
throw new InvalidArgumentException(__('Preview is disabled'));
|
|
}
|
|
|
|
// Save
|
|
$module->save();
|
|
|
|
// Successful
|
|
$this->getState()->hydrate([
|
|
'message' => sprintf(__('Configured %s'), $module->name),
|
|
'id' => $module->moduleId,
|
|
'data' => $module
|
|
]);
|
|
|
|
return $this->render($request, $response);
|
|
}
|
|
|
|
/**
|
|
* Clear Cache Form
|
|
* @param Request $request
|
|
* @param Response $response
|
|
* @param $id
|
|
* @return \Psr\Http\Message\ResponseInterface|Response
|
|
* @throws GeneralException
|
|
* @throws NotFoundException
|
|
* @throws \Xibo\Support\Exception\ControllerNotImplemented
|
|
*/
|
|
public function clearCacheForm(Request $request, Response $response, $id)
|
|
{
|
|
$module = $this->moduleFactory->getById($id);
|
|
|
|
$this->getState()->template = 'module-form-clear-cache';
|
|
$this->getState()->autoSubmit = $this->getAutoSubmit('clearCache');
|
|
$this->getState()->setData([
|
|
'module' => $module,
|
|
]);
|
|
|
|
return $this->render($request, $response);
|
|
}
|
|
|
|
/**
|
|
* Clear Cache
|
|
* @param Request $request
|
|
* @param Response $response
|
|
* @param $id
|
|
* @return \Psr\Http\Message\ResponseInterface|Response
|
|
* @throws GeneralException
|
|
* @throws NotFoundException
|
|
* @throws \Xibo\Support\Exception\ControllerNotImplemented
|
|
*/
|
|
public function clearCache(Request $request, Response $response, $id)
|
|
{
|
|
$module = $this->moduleFactory->getById($id);
|
|
if ($module->isDataProviderExpected()) {
|
|
$this->moduleFactory->clearCacheForDataType($module->dataType);
|
|
}
|
|
|
|
$this->getState()->hydrate([
|
|
'message' => __('Cleared the Cache')
|
|
]);
|
|
|
|
return $this->render($request, $response);
|
|
}
|
|
|
|
/**
|
|
* @SWG\Get(
|
|
* path="/module/templates/{dataType}",
|
|
* operationId="moduleTemplateSearch",
|
|
* tags={"module"},
|
|
* summary="Module Template Search",
|
|
* description="Get a list of templates available for a particular data type",
|
|
* @SWG\Parameter(
|
|
* name="dataType",
|
|
* in="path",
|
|
* description="DataType to return templates for",
|
|
* type="string",
|
|
* required=true
|
|
* ),
|
|
* @SWG\Parameter(
|
|
* name="type",
|
|
* in="query",
|
|
* description="Type to return templates for",
|
|
* type="string",
|
|
* required=false
|
|
* ),
|
|
* @SWG\Response(
|
|
* response=200,
|
|
* description="An array of module templates for the provided datatype",
|
|
* @SWG\Schema(ref="#/definitions/ModuleTemplate")
|
|
* )
|
|
* )
|
|
* @param \Slim\Http\ServerRequest $request
|
|
* @param \Slim\Http\Response $response
|
|
* @param string $dataType
|
|
* @return \Slim\Http\Response
|
|
* @throws \Xibo\Support\Exception\GeneralException
|
|
*/
|
|
public function templateGrid(Request $request, Response $response, string $dataType): Response
|
|
{
|
|
if (empty($dataType)) {
|
|
throw new InvalidArgumentException(__('Please provide a datatype'), 'dataType');
|
|
}
|
|
|
|
$params = $this->getSanitizer($request->getParams());
|
|
$type = $params->getString('type');
|
|
|
|
$templates = !empty($type)
|
|
? $this->moduleTemplateFactory->getByTypeAndDataType($type, $dataType)
|
|
: $this->moduleTemplateFactory->getByDataType($dataType);
|
|
|
|
$this->getState()->template = 'grid';
|
|
$this->getState()->recordsTotal = 0;
|
|
$this->getState()->setData($templates);
|
|
return $this->render($request, $response);
|
|
}
|
|
|
|
// phpcs:disable
|
|
/**
|
|
* @SWG\Get(
|
|
* path="/module/template/{dataType}/properties/{id}",
|
|
* operationId="getModuleProperties",
|
|
* tags={"module"},
|
|
* summary="Get Module Template Properties",
|
|
* description="Get a module template properties which are needed to for the editWidget call",
|
|
* @SWG\Parameter(
|
|
* name="dataType",
|
|
* in="path",
|
|
* description="The Template DataType",
|
|
* type="string",
|
|
* required=true
|
|
* ),
|
|
* @SWG\Parameter(
|
|
* name="id",
|
|
* in="path",
|
|
* description="The Template Id",
|
|
* type="string",
|
|
* required=true
|
|
* ),
|
|
* @SWG\Response(
|
|
* response=200,
|
|
* description="successful operation",
|
|
* @SWG\Schema(
|
|
* type="object",
|
|
* additionalProperties={"id":"string", "type":"string", "title":"string", "helpText":"string", "options":"array"}
|
|
* )
|
|
* )
|
|
* )
|
|
* @param Request $request
|
|
* @param Response $response
|
|
* @param string $dataType
|
|
* @param string $id
|
|
* @return ResponseInterface|Response
|
|
* @throws GeneralException
|
|
* @throws NotFoundException
|
|
* @throws ControllerNotImplemented
|
|
*/
|
|
// phpcs:enable
|
|
public function getTemplateProperties(Request $request, Response $response, string $dataType, string $id)
|
|
{
|
|
// Get properties, but return a key->value object for easy parsing.
|
|
$props = [];
|
|
foreach ($this->moduleTemplateFactory->getByDataTypeAndId($dataType, $id)->properties as $property) {
|
|
$props[$property->id] = [
|
|
'id' => $property->id,
|
|
'type' => $property->type,
|
|
'title' => $property->title,
|
|
'helpText' => $property->helpText,
|
|
'options' => $property->options,
|
|
];
|
|
}
|
|
|
|
$this->getState()->setData($props);
|
|
return $this->render($request, $response);
|
|
}
|
|
|
|
/**
|
|
* Serve an asset
|
|
* @param \Slim\Http\ServerRequest $request
|
|
* @param \Slim\Http\Response $response
|
|
* @param string $assetId the ID of the asset to serve
|
|
* @return \Psr\Http\Message\ResponseInterface|Response
|
|
* @throws \Xibo\Support\Exception\InvalidArgumentException
|
|
* @throws \Xibo\Support\Exception\NotFoundException
|
|
* @throws \Xibo\Support\Exception\GeneralException
|
|
*/
|
|
public function assetDownload(Request $request, Response $response, string $assetId): Response
|
|
{
|
|
if (empty($assetId)) {
|
|
throw new InvalidArgumentException(__('Please provide an assetId'), 'assetId');
|
|
}
|
|
|
|
// Get this asset from somewhere
|
|
$asset = $this->moduleFactory->getAssetsFromAnywhereById(
|
|
$assetId,
|
|
$this->moduleTemplateFactory,
|
|
$this->getSanitizer($request->getParams())->getCheckbox('isAlias')
|
|
);
|
|
$asset->updateAssetCache($this->getConfig()->getSetting('LIBRARY_LOCATION'));
|
|
|
|
$this->getLog()->debug('assetDownload: found appropriate asset for assetId ' . $assetId);
|
|
|
|
// The asset can serve itself.
|
|
return $asset->psrResponse($request, $response, $this->getConfig()->getSetting('SENDFILE_MODE'));
|
|
}
|
|
}
|