Skip to content

Commit

Permalink
Menu Boards: BE, admin and minor widget additions (#1944)
Browse files Browse the repository at this point in the history
* Bump to v4.0.0-rc1

* Menu Boards:
 - re-enabled admin UI
 - fix feature checking
 - fix thumbnail columns/unmatched properties
 - add product data type
 - add menu board product and category widget with filters, sorting, etc
 - add calories, displayOrder to product, convert price to decimal
 - add description to category
 - translate datatypes
 - install modules by default

Preview:
 - pass properties into onElementParseData

Weather:
 - fix issue with element rendering in preview

* Widgets: add isRepeatData for data widgets xibosignageltd/xibo-private#371
  • Loading branch information
dasgarner authored Jul 28, 2023
1 parent 64de002 commit 613afe7
Show file tree
Hide file tree
Showing 38 changed files with 1,321 additions and 192 deletions.
15 changes: 4 additions & 11 deletions db/migrations/20220330111440_modules_table_ver_four_migration.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,19 +135,12 @@ public function change()
(\'core-worldclock-digital-text\', '.$enabled.', '.$previewEnabled.', '.$defaultDuration.', \''.$settings.'\');
');

// Add new modules.
$this->execute('
INSERT INTO `module` (`moduleId`, `enabled`, `previewEnabled`, `defaultDuration`, `settings`) VALUES
(\'core-canvas\', \'1\', \'1\', \'60\', \'[]\');
');

$this->execute('
INSERT INTO `module` (`moduleId`, `enabled`, `previewEnabled`, `defaultDuration`, `settings`) VALUES
(\'core-mastodon\', \'1\', \'1\', \'60\', \'[]\');
');

$this->execute('
INSERT INTO `module` (`moduleId`, `enabled`, `previewEnabled`, `defaultDuration`, `settings`) VALUES
(\'core-countdown-custom\', \'1\', \'1\', \'60\', \'[]\');
(\'core-canvas\', \'1\', \'1\', \'60\', \'[]\'),
(\'core-mastodon\', \'1\', \'1\', \'60\', \'[]\'),
(\'core-countdown-custom\', \'1\', \'1\', \'60\', \'[]\')
');
} catch (Exception $e) {
// Keep the old module table around for diagnosis and just continue on.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?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/>.
*/

use Phinx\Migration\AbstractMigration;

/**
* Add some additional fields to menu boards
* @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
*/
class MenuboardAdditionalFieldsMigration extends AbstractMigration
{
public function change(): void
{
// Before I do this I need to make sure that all products in this table have a numeric field in price
foreach ($this->fetchAll('SELECT `menuProductId`, `price` FROM `menu_product`') as $row) {
if (!empty($row['price'])) {
$this->execute('UPDATE `menu_product` SET `price` = :price WHERE menuProductId = :id', [
'id' => $row['menuProductId'],
'price' => preg_replace('/[^A-Za-z0-9 ]/', '', $row['price']),
]);
}
}

$this->table('menu_product')
->addColumn('calories', 'integer', [
'length' => \Phinx\Db\Adapter\MysqlAdapter::INT_SMALL,
'null' => true,
'default' => null,
])
->addColumn('displayOrder', 'integer', [
'length' => \Phinx\Db\Adapter\MysqlAdapter::INT_MEDIUM,
'null' => false,
'default' => 0,
])
->changeColumn('price', 'decimal', [
'precision' => 10,
'scale' => 4,
'default' => null,
'null' => true,
])
->save();

$this->table('menu_category')
->addColumn('description', 'string', [
'length' => 254,
'null' => true,
'default' => null,
])
->save();

// Drop the old menu-board module entirely, and insert the new ones.
$this->execute('DELETE FROM `module` WHERE moduleId = \'core-menuboard\'');
$this->execute('
INSERT INTO `module` (`moduleId`, `enabled`, `previewEnabled`, `defaultDuration`, `settings`) VALUES
(\'core-menuboard-category\', \'1\', \'1\', \'60\', \'[]\'),
(\'core-menuboard-product\', \'1\', \'1\', \'60\', \'[]\');
');
}
}
6 changes: 3 additions & 3 deletions lib/Controller/MenuBoard.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ public function grid(Request $request, Response $response): Response
$menuBoard->includeProperty('buttons');
$menuBoard->buttons = [];

if ($this->getUser()->featureEnabled('menuboard.modify') && $this->getUser()->checkEditable($menuBoard)) {
if ($this->getUser()->featureEnabled('menuBoard.modify') && $this->getUser()->checkEditable($menuBoard)) {
$menuBoard->buttons[] = [
'id' => 'menuBoard_button_viewcategories',
'url' => $this->urlFor($request, 'menuBoard.category.view', ['id' => $menuBoard->menuId]),
Expand Down Expand Up @@ -203,7 +203,7 @@ public function grid(Request $request, Response $response): Response
}
}

if ($this->getUser()->featureEnabled('menuboard.modify') && $this->getUser()->checkPermissionsModifyable($menuBoard)) {
if ($this->getUser()->featureEnabled('menuBoard.modify') && $this->getUser()->checkPermissionsModifyable($menuBoard)) {
$menuBoard->buttons[] = ['divider' => true];

// Share button
Expand Down Expand Up @@ -231,7 +231,7 @@ public function grid(Request $request, Response $response): Response
];
}

if ($this->getUser()->featureEnabled('menuboard.modify')
if ($this->getUser()->featureEnabled('menuBoard.modify')
&& $this->getUser()->checkDeleteable($menuBoard)
) {
$menuBoard->buttons[] = ['divider' => true];
Expand Down
43 changes: 31 additions & 12 deletions lib/Controller/MenuBoardCategory.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?php
/**
* Copyright (C) 2021 Xibo Signage Ltd
/*
* Copyright (C) 2023 Xibo Signage Ltd
*
* Xibo - Digital Signage - http://www.xibo.org.uk
* Xibo - Digital Signage - https://xibosignage.com
*
* This file is part of Xibo.
*
Expand Down Expand Up @@ -162,18 +162,22 @@ public function grid(Request $request, Response $response, $id): Response
continue;
}

$menuBoardCategory->thumbnail = '';

if ($menuBoardCategory->mediaId != 0) {
$download = $this->urlFor($request, 'library.download', ['id' => $menuBoardCategory->mediaId], ['preview' => 1]);
$menuBoardCategory->thumbnail = '<a class="img-replace" data-toggle="lightbox" data-type="image" href="' . $download . '"><img src="' . $download . '&isThumb=1" /></i></a>';
$menuBoardCategory->thumbnailUrl = $download . '&isThumb=1';
$menuBoardCategory->setUnmatchedProperty(
'thumbnail',
$this->urlFor(
$request,
'library.download',
['id' => $menuBoardCategory->mediaId],
['preview' => 1],
)
);
}

$menuBoardCategory->includeProperty('buttons');
$menuBoardCategory->buttons = [];

if ($this->getUser()->featureEnabled('menuboard.modify') && $this->getUser()->checkEditable($menuBoard)) {
if ($this->getUser()->featureEnabled('menuBoard.modify') && $this->getUser()->checkEditable($menuBoard)) {
$menuBoardCategory->buttons[] = [
'id' => 'menuBoardCategory_button_viewproducts',
'url' => $this->urlFor($request, 'menuBoard.product.view', ['id' => $menuBoardCategory->menuCategoryId]),
Expand All @@ -188,7 +192,7 @@ public function grid(Request $request, Response $response, $id): Response
];
}

if ($this->getUser()->featureEnabled('menuboard.modify') && $this->getUser()->checkDeleteable($menuBoard)) {
if ($this->getUser()->featureEnabled('menuBoard.modify') && $this->getUser()->checkDeleteable($menuBoard)) {
$menuBoardCategory->buttons[] = ['divider' => true];

$menuBoardCategory->buttons[] = [
Expand Down Expand Up @@ -270,6 +274,13 @@ public function addForm(Request $request, Response $response, $id): Response
* type="string",
* required=false
* ),
* @SWG\Parameter(
* name="description",
* in="formData",
* description="Menu Board Category description",
* type="string",
* required=false
* ),
* @SWG\Response(
* response=201,
* description="successful operation",
Expand Down Expand Up @@ -301,8 +312,9 @@ public function add(Request $request, Response $response, $id): Response
$name = $sanitizedParams->getString('name');
$mediaId = $sanitizedParams->getInt('mediaId');
$code = $sanitizedParams->getString('code');
$description = $sanitizedParams->getString('description');

$menuBoardCategory = $this->menuBoardCategoryFactory->create($id, $name, $mediaId, $code);
$menuBoardCategory = $this->menuBoardCategoryFactory->create($id, $name, $mediaId, $code, $description);
$menuBoardCategory->save();

// Return
Expand Down Expand Up @@ -380,6 +392,13 @@ public function editForm(Request $request, Response $response, $id): Response
* type="string",
* required=false
* ),
* @SWG\Parameter(
* name="description",
* in="formData",
* description="Menu Board Category description",
* type="string",
* required=false
* ),
* @SWG\Response(
* response=204,
* description="successful operation"
Expand Down Expand Up @@ -409,7 +428,7 @@ public function edit(Request $request, Response $response, $id): Response
$menuBoardCategory->name = $sanitizedParams->getString('name');
$menuBoardCategory->mediaId = $sanitizedParams->getInt('mediaId');
$menuBoardCategory->code = $sanitizedParams->getString('code');

$menuBoardCategory->description = $sanitizedParams->getString('description');
$menuBoardCategory->save();

// Success
Expand Down
73 changes: 56 additions & 17 deletions lib/Controller/MenuBoardProduct.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?php
/**
* Copyright (C) 2021 Xibo Signage Ltd
/*
* Copyright (C) 2023 Xibo Signage Ltd
*
* Xibo - Digital Signage - http://www.xibo.org.uk
* Xibo - Digital Signage - https://xibosignage.com
*
* This file is part of Xibo.
*
Expand Down Expand Up @@ -174,25 +174,25 @@ public function grid(Request $request, Response $response, $id): Response
continue;
}

$menuBoardProduct->thumbnail = '';
$menuBoardProduct->includeProperty('buttons');
$menuBoardProduct->buttons = [];

if ($menuBoardProduct->mediaId != 0) {
$download = $this->urlFor($request, 'library.download', ['id' => $menuBoardProduct->mediaId], ['preview' => 1]);
$menuBoardProduct->thumbnail = '<a class="img-replace" data-toggle="lightbox" data-type="image" href="' . $download . '"><img src="' . $download . '&isThumb=1" /></i></a>';
$menuBoardProduct->thumbnailUrl = $download . '&isThumb=1';
$menuBoardProduct->setUnmatchedProperty(
'thumbnail',
$this->urlFor($request, 'library.download', ['id' => $menuBoardProduct->mediaId], ['preview' => 1]),
);
}

if ($this->getUser()->featureEnabled('menuboard.modify') && $this->getUser()->checkEditable($menuBoard)) {
if ($this->getUser()->featureEnabled('menuBoard.modify') && $this->getUser()->checkEditable($menuBoard)) {
$menuBoardProduct->buttons[] = [
'id' => 'menuBoardProduct_edit_button',
'url' => $this->urlFor($request, 'menuBoard.product.edit.form', ['id' => $menuBoardProduct->menuProductId]),
'text' => __('Edit')
];
}

if ($this->getUser()->featureEnabled('menuboard.modify') && $this->getUser()->checkDeleteable($menuBoard)) {
if ($this->getUser()->featureEnabled('menuBoard.modify') && $this->getUser()->checkDeleteable($menuBoard)) {
$menuBoardProduct->buttons[] = ['divider' => true];

$menuBoardProduct->buttons[] = [
Expand Down Expand Up @@ -303,9 +303,9 @@ public function addForm(Request $request, Response $response, $id): Response
* @SWG\Parameter(
* name="price",
* in="formData",
* description="Menu Board Product price, including the currency symbol if needed",
* type="string",
* required=true
* description="Menu Board Product price",
* type="decimal",
* required=false
* ),
* @SWG\Parameter(
* name="allergyInfo",
Expand All @@ -315,6 +315,20 @@ public function addForm(Request $request, Response $response, $id): Response
* required=false
* ),
* @SWG\Parameter(
* name="calories",
* in="formData",
* description="Menu Board Product calories",
* type="integer",
* required=false
* ),
* @SWG\Parameter(
* name="displayOrder",
* in="formData",
* description="Menu Board Product Display Order, used for sorting",
* type="integer",
* required=true
* ),
* @SWG\Parameter(
* name="availability",
* in="formData",
* description="Menu Board Product availability",
Expand Down Expand Up @@ -382,21 +396,30 @@ public function add(Request $request, Response $response, $id): Response

$name = $sanitizedParams->getString('name');
$mediaId = $sanitizedParams->getInt('mediaId');
$price = $sanitizedParams->getString('price');
$price = $sanitizedParams->getDouble('price');
$description = $sanitizedParams->getString('description');
$allergyInfo = $sanitizedParams->getString('allergyInfo');
$calories = $sanitizedParams->getInt('calories');
$displayOrder = $sanitizedParams->getInt('displayOrder');
$availability = $sanitizedParams->getCheckbox('availability');
$productOptions = $sanitizedParams->getArray('productOptions', ['default' => []]);
$productValues = $sanitizedParams->getArray('productValues', ['default' => []]);
$code = $sanitizedParams->getString('code');

// If the display order is empty, get the next highest one.
if ($displayOrder === null) {
$displayOrder = $this->menuBoardCategoryFactory->getNextDisplayOrder($menuBoardCategory->menuCategoryId);
}

$menuBoardProduct = $this->menuBoardCategoryFactory->createProduct(
$menuBoard->menuId,
$menuBoardCategory->menuCategoryId,
$name,
$price,
$description,
$allergyInfo,
$calories,
$displayOrder,
$availability,
$mediaId,
$code
Expand Down Expand Up @@ -488,9 +511,9 @@ public function editForm(Request $request, Response $response, $id): Response
* @SWG\Parameter(
* name="price",
* in="formData",
* description="Menu Board Product price, including the currency symbol if needed",
* type="string",
* required=true
* description="Menu Board Product price",
* type="decimal",
* required=false
* ),
* @SWG\Parameter(
* name="allergyInfo",
Expand All @@ -500,6 +523,20 @@ public function editForm(Request $request, Response $response, $id): Response
* required=false
* ),
* @SWG\Parameter(
* name="calories",
* in="formData",
* description="Menu Board Product calories",
* type="integer",
* required=false
* ),
* @SWG\Parameter(
* name="displayOrder",
* in="formData",
* description="Menu Board Product Display Order, used for sorting",
* type="integer",
* required=true
* ),
* @SWG\Parameter(
* name="availability",
* in="formData",
* description="Menu Board Product availability",
Expand Down Expand Up @@ -564,8 +601,10 @@ public function edit(Request $request, Response $response, $id): Response

$menuBoardProduct->name = $sanitizedParams->getString('name');
$menuBoardProduct->description = $sanitizedParams->getString('description');
$menuBoardProduct->price = $sanitizedParams->getString('price');
$menuBoardProduct->price = $sanitizedParams->getDouble('price');
$menuBoardProduct->allergyInfo = $sanitizedParams->getString('allergyInfo');
$menuBoardProduct->calories = $sanitizedParams->getString('calories');
$menuBoardProduct->displayOrder = $sanitizedParams->getInt('displayOrder');
$menuBoardProduct->availability = $sanitizedParams->getCheckbox('availability');
$menuBoardProduct->mediaId = $sanitizedParams->getInt('mediaId');
$menuBoardProduct->code = $sanitizedParams->getString('code');
Expand Down
5 changes: 5 additions & 0 deletions lib/Controller/Widget.php
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,11 @@ public function editWidget(Request $request, Response $response, $id)
$widget->setOptionValue('name', 'attrib', $params->getString('name'));
$widget->setOptionValue('enableStat', 'attrib', $params->getString('enableStat'));

// Handle special common properties for widgets with data
if ($module->isDataProviderExpected()) {
$widget->setOptionValue('isRepeatData', 'attrib', $params->getCheckbox('isRepeatData'));
}

// Validate common parameters if we don't have a validator present.
$widgetValidators = $module->getWidgetValidators();
if (count($widgetValidators) <= 0 && $widget->duration < 0) {
Expand Down
Loading

0 comments on commit 613afe7

Please sign in to comment.