. */ 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')); } }