Files

465 lines
15 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\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'));
}
}