Skip to content

Commit

Permalink
Misc Fixes: (#1980)
Browse files Browse the repository at this point in the history
* Layout editor: playlist preview -fix for controls not clicking in published mode xibosignageltd/xibo-private#401
* Player software: fix type filter.
* Fix PDF default duration and include PDF worker (copy to assets), implement duration per item  xibosignageltd/xibo-private#402
* Default enable stat setting for a widget xibosignageltd/xibo-private#354
* Dashboard: fix issue with spinner and token exception. xibosignageltd/xibo-private#245
* Player: globalThis polyfill for webos/tizen.
  • Loading branch information
dasgarner authored Aug 10, 2023
1 parent bad52bd commit 6ab3bd7
Show file tree
Hide file tree
Showing 19 changed files with 281 additions and 137 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ containers/
web/dist
cypress/videos/
modules/bundle*.js*
modules/assets/pdfjs

# The OpenOOH specification
openooh/
Expand Down
47 changes: 1 addition & 46 deletions lib/Connector/XiboDashboardConnector.php
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,7 @@ public function onDataRequest(DashboardDataRequestEvent $event, $eventName, Even
} catch (\Exception $e) {
$this->getLogger()->error('onDataRequest: Failed to get token. e = ' . $e->getMessage());
$event->getDataProvider()->addError(__('No token returned'));
return;
}

if ($event->getDataProvider()->isPreview()) {
Expand All @@ -536,54 +537,8 @@ public function onDataRequest(DashboardDataRequestEvent $event, $eventName, Even
$item['url'] = $url;
$item['token'] = $token;
$item['isPreview'] = $event->getDataProvider()->isPreview();
$item['spinner'] = $this->getSpinner();

$event->getDataProvider()->addItem($item);
$event->getDataProvider()->setIsHandled();
}

private function getSpinner(): string
{
return 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8IURPQ1RZUEUgc3ZnIFBVQkxJQy
AiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8c3ZnIH
dpZHRoPSI0MHB4IiBoZWlnaHQ9IjQwcHgiIHZpZXdCb3g9IjAgMCA0MCA0MCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcm
cvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3BhY2U9InByZXNlcnZlIiBzdHlsZT0iZm
lsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjEuNDE0MjE7Ii
B4PSIwcHgiIHk9IjBweCI+CiAgICA8ZGVmcz4KICAgICAgICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPjwhW0NEQVRBWwogICAgICAgICAgICBALX
dlYmtpdC1rZXlmcmFtZXMgc3BpbiB7CiAgICAgICAgICAgICAgZnJvbSB7CiAgICAgICAgICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogcm90YX
RlKDBkZWcpCiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHRvIHsKICAgICAgICAgICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiByb3RhdG
UoLTM1OWRlZykKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQGtleWZyYW1lcyBzcGluIHsKICAgICAgICAgICAgIC
Bmcm9tIHsKICAgICAgICAgICAgICAgIHRyYW5zZm9ybTogcm90YXRlKDBkZWcpCiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHRvIHsKIC
AgICAgICAgICAgICAgIHRyYW5zZm9ybTogcm90YXRlKC0zNTlkZWcpCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIH
N2ZyB7CiAgICAgICAgICAgICAgICAtd2Via2l0LXRyYW5zZm9ybS1vcmlnaW46IDUwJSA1MCU7CiAgICAgICAgICAgICAgICAtd2Via2l0LWFuaW
1hdGlvbjogc3BpbiAxLjVzIGxpbmVhciBpbmZpbml0ZTsKICAgICAgICAgICAgICAgIC13ZWJraXQtYmFja2ZhY2UtdmlzaWJpbGl0eTogaGlkZG
VuOwogICAgICAgICAgICAgICAgYW5pbWF0aW9uOiBzcGluIDEuNXMgbGluZWFyIGluZmluaXRlOwogICAgICAgICAgICB9CiAgICAgICAgXV0+PC
9zdHlsZT4KICAgIDwvZGVmcz4KICAgIDxnIGlkPSJvdXRlciI+CiAgICAgICAgPGc+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMCwwQzIyLjIwNT
gsMCAyMy45OTM5LDEuNzg4MTMgMjMuOTkzOSwzLjk5MzlDMjMuOTkzOSw2LjE5OTY4IDIyLjIwNTgsNy45ODc4MSAyMCw3Ljk4NzgxQzE3Ljc5ND
IsNy45ODc4MSAxNi4wMDYxLDYuMTk5NjggMTYuMDA2MSwzLjk5MzlDMTYuMDA2MSwxLjc4ODEzIDE3Ljc5NDIsMCAyMCwwWiIgc3R5bGU9ImZpbG
w6YmxhY2s7Ii8+CiAgICAgICAgPC9nPgogICAgICAgIDxnPgogICAgICAgICAgICA8cGF0aCBkPSJNNS44NTc4Niw1Ljg1Nzg2QzcuNDE3NTgsNC
4yOTgxNSA5Ljk0NjM4LDQuMjk4MTUgMTEuNTA2MSw1Ljg1Nzg2QzEzLjA2NTgsNy40MTc1OCAxMy4wNjU4LDkuOTQ2MzggMTEuNTA2MSwxMS41MD
YxQzkuOTQ2MzgsMTMuMDY1OCA3LjQxNzU4LDEzLjA2NTggNS44NTc4NiwxMS41MDYxQzQuMjk4MTUsOS45NDYzOCA0LjI5ODE1LDcuNDE3NTggNS
44NTc4Niw1Ljg1Nzg2WiIgc3R5bGU9ImZpbGw6cmdiKDIxMCwyMTAsMjEwKTsiLz4KICAgICAgICA8L2c+CiAgICAgICAgPGc+CiAgICAgICAgIC
AgIDxwYXRoIGQ9Ik0yMCwzMi4wMTIyQzIyLjIwNTgsMzIuMDEyMiAyMy45OTM5LDMzLjgwMDMgMjMuOTkzOSwzNi4wMDYxQzIzLjk5MzksMzguMj
ExOSAyMi4yMDU4LDQwIDIwLDQwQzE3Ljc5NDIsNDAgMTYuMDA2MSwzOC4yMTE5IDE2LjAwNjEsMzYuMDA2MUMxNi4wMDYxLDMzLjgwMDMgMTcuNz
k0MiwzMi4wMTIyIDIwLDMyLjAxMjJaIiBzdHlsZT0iZmlsbDpyZ2IoMTMwLDEzMCwxMzApOyIvPgogICAgICAgIDwvZz4KICAgICAgICA8Zz4KIC
AgICAgICAgICAgPHBhdGggZD0iTTI4LjQ5MzksMjguNDkzOUMzMC4wNTM2LDI2LjkzNDIgMzIuNTgyNCwyNi45MzQyIDM0LjE0MjEsMjguNDkzOU
MzNS43MDE5LDMwLjA1MzYgMzUuNzAxOSwzMi41ODI0IDM0LjE0MjEsMzQuMTQyMUMzMi41ODI0LDM1LjcwMTkgMzAuMDUzNiwzNS43MDE5IDI4Lj
Q5MzksMzQuMTQyMUMyNi45MzQyLDMyLjU4MjQgMjYuOTM0MiwzMC4wNTM2IDI4LjQ5MzksMjguNDkzOVoiIHN0eWxlPSJmaWxsOnJnYigxMDEsMT
AxLDEwMSk7Ii8+CiAgICAgICAgPC9nPgogICAgICAgIDxnPgogICAgICAgICAgICA8cGF0aCBkPSJNMy45OTM5LDE2LjAwNjFDNi4xOTk2OCwxNi
4wMDYxIDcuOTg3ODEsMTcuNzk0MiA3Ljk4NzgxLDIwQzcuOTg3ODEsMjIuMjA1OCA2LjE5OTY4LDIzLjk5MzkgMy45OTM5LDIzLjk5MzlDMS43OD
gxMywyMy45OTM5IDAsMjIuMjA1OCAwLDIwQzAsMTcuNzk0MiAxLjc4ODEzLDE2LjAwNjEgMy45OTM5LDE2LjAwNjFaIiBzdHlsZT0iZmlsbDpyZ2
IoMTg3LDE4NywxODcpOyIvPgogICAgICAgIDwvZz4KICAgICAgICA8Zz4KICAgICAgICAgICAgPHBhdGggZD0iTTUuODU3ODYsMjguNDkzOUM3Lj
QxNzU4LDI2LjkzNDIgOS45NDYzOCwyNi45MzQyIDExLjUwNjEsMjguNDkzOUMxMy4wNjU4LDMwLjA1MzYgMTMuMDY1OCwzMi41ODI0IDExLjUwNj
EsMzQuMTQyMUM5Ljk0NjM4LDM1LjcwMTkgNy40MTc1OCwzNS43MDE5IDUuODU3ODYsMzQuMTQyMUM0LjI5ODE1LDMyLjU4MjQgNC4yOTgxNSwzMC
4wNTM2IDUuODU3ODYsMjguNDkzOVoiIHN0eWxlPSJmaWxsOnJnYigxNjQsMTY0LDE2NCk7Ii8+CiAgICAgICAgPC9nPgogICAgICAgIDxnPgogIC
AgICAgICAgICA8cGF0aCBkPSJNMzYuMDA2MSwxNi4wMDYxQzM4LjIxMTksMTYuMDA2MSA0MCwxNy43OTQyIDQwLDIwQzQwLDIyLjIwNTggMzguMj
ExOSwyMy45OTM5IDM2LjAwNjEsMjMuOTkzOUMzMy44MDAzLDIzLjk5MzkgMzIuMDEyMiwyMi4yMDU4IDMyLjAxMjIsMjBDMzIuMDEyMiwxNy43OT
QyIDMzLjgwMDMsMTYuMDA2MSAzNi4wMDYxLDE2LjAwNjFaIiBzdHlsZT0iZmlsbDpyZ2IoNzQsNzQsNzQpOyIvPgogICAgICAgIDwvZz4KICAgIC
AgICA8Zz4KICAgICAgICAgICAgPHBhdGggZD0iTTI4LjQ5MzksNS44NTc4NkMzMC4wNTM2LDQuMjk4MTUgMzIuNTgyNCw0LjI5ODE1IDM0LjE0Mj
EsNS44NTc4NkMzNS43MDE5LDcuNDE3NTggMzUuNzAxOSw5Ljk0NjM4IDM0LjE0MjEsMTEuNTA2MUMzMi41ODI0LDEzLjA2NTggMzAuMDUzNiwxMy
4wNjU4IDI4LjQ5MzksMTEuNTA2MUMyNi45MzQyLDkuOTQ2MzggMjYuOTM0Miw3LjQxNzU4IDI4LjQ5MzksNS44NTc4NloiIHN0eWxlPSJmaWxsOn
JnYig1MCw1MCw1MCk7Ii8+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4K';
}
}
5 changes: 3 additions & 2 deletions lib/Controller/PlayerSoftware.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,11 @@ function displayPage(Request $request, Response $response)
{
$this->getState()->template = 'playersoftware-page';
$this->getState()->setData([
'types' => $this->playerVersionFactory->getDistinctType(),
'types' => array_map(function ($element) {
return $element->jsonSerialize();
}, $this->playerVersionFactory->getDistinctType()),
'versions' => $this->playerVersionFactory->getDistinctVersion(),
'validExt' => implode('|', $this->getValidExtensions()),
'warningLabel' => __("Please set Player Software Version")
]);

return $this->render($request, $response);
Expand Down
7 changes: 7 additions & 0 deletions lib/Controller/Widget.php
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,13 @@ public function addWidget(Request $request, Response $response, $type, $id)
$module->schemaVersion
);

// Default status setting
$widget->setOptionValue(
'enableStat',
'attrib',
$this->getConfig()->getSetting('WIDGET_STATS_ENABLED_DEFAULT')
);

// Get the template
if ($module->isTemplateExpected()) {
$templateId = $params->getString('templateId', [
Expand Down
19 changes: 19 additions & 0 deletions lib/Entity/Widget.php
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,25 @@ public function getPrimaryMedia()
return array_values(array_diff($this->mediaIds, $this->getAudioIds()));
}

/**
* Get the temporary path
* @return string
*/
public function getLibraryTempPath(): string
{
return $this->widgetMediaFactory->getLibraryTempPath();
}

/**
* Get the path of the primary media
* @return string
* @throws NotFoundException
*/
public function getPrimaryMediaPath(): string
{
return $this->widgetMediaFactory->getPathForMediaId($this->getPrimaryMediaId());
}

/**
* Clear Media
* this must only clear module media, not "primary" media
Expand Down
1 change: 1 addition & 0 deletions lib/Factory/ModuleXmlTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,7 @@ private function parseAssets($assetNodes): array
$asset->mimeType = $node->getAttribute('mimeType');
$asset->type = $node->getAttribute('type');
$asset->cmsOnly = $node->getAttribute('cmsOnly') === 'true';
$asset->autoInclude = $node->getAttribute('autoInclude') !== 'true';
$asset->assetNo = count($this->assetCache) + 1;
$this->assetCache[$assetId] = $asset;
}
Expand Down
26 changes: 26 additions & 0 deletions lib/Factory/WidgetMediaFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,32 @@ public function getDurationForMediaId(int $mediaId): int
return intval($results[0]['duration'] ?? 0);
}

/**
* @return string
*/
public function getLibraryTempPath(): string
{
return $this->getConfig()->getSetting('LIBRARY_LOCATION') . '/temp';
}

/**
* @param int $mediaId
* @return string
* @throws NotFoundException
*/
public function getPathForMediaId(int $mediaId): string
{
$results = $this->getStore()->select('SELECT `storedAs` FROM `media` WHERE `mediaId` = :mediaId', [
'mediaId' => $mediaId
]);

if (count($results) <= 0) {
throw new NotFoundException();
}

return $this->getConfig()->getSetting('LIBRARY_LOCATION') . $results[0]['storedAs'];
}

/**
* Query Media Linked to Widgets
* @param array $sortOrder
Expand Down
13 changes: 13 additions & 0 deletions lib/Widget/Definition/Asset.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ class Asset implements \JsonSerializable
public $path;
public $mimeType;

/** @var bool */
public $autoInclude;

/** @var bool */
public $cmsOnly;

Expand All @@ -59,6 +62,7 @@ public function jsonSerialize(): array
'path' => $this->path,
'mimeType' => $this->mimeType,
'cmsOnly' => $this->cmsOnly,
'autoInclude' => $this->autoInclude,
];
}

Expand All @@ -71,6 +75,15 @@ public function isSendToPlayer(): bool
return !($this->cmsOnly ?? false);
}

/**
* Should this asset be sent to the player?
* @return bool
*/
public function isAutoInclude(): bool
{
return !($this->autoInclude ?? false);
}

/**
* @param string $libraryLocation
* @param bool $forceUpdate
Expand Down
85 changes: 85 additions & 0 deletions lib/Widget/PdfProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?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;

use Carbon\Carbon;
use Mpdf\Mpdf;
use Xibo\Widget\Provider\DataProviderInterface;
use Xibo\Widget\Provider\DurationProviderInterface;
use Xibo\Widget\Provider\WidgetProviderInterface;
use Xibo\Widget\Provider\WidgetProviderTrait;

/**
* PDF provider to calculate the duration if durationIsPerItem is selected.
*/
class PdfProvider implements WidgetProviderInterface
{
use WidgetProviderTrait;

public function fetchData(DataProviderInterface $dataProvider): WidgetProviderInterface
{
return $this;
}

public function fetchDuration(DurationProviderInterface $durationProvider): WidgetProviderInterface
{
$widget = $durationProvider->getWidget();
if ($widget->getOptionValue('durationIsPerItem', 0) == 1) {
// Do we already have an option stored for the number of pages?
$pageCount = 1;
$cachedPageCount = $widget->getOptionValue('pageCount', null);
if ($cachedPageCount === null) {
try {
$sourceFile = $widget->getPrimaryMediaPath();

$this->getLog()->debug('fetchDuration: loading PDF file to get the number of pages, file: '
. $sourceFile);

$mPdf = new Mpdf([
'tempDir' => $widget->getLibraryTempPath(),
]);
$pageCount = $mPdf->setSourceFile($sourceFile);

$widget->setOptionValue('pageCount', 'attrib', $pageCount);
} catch (\Exception $e) {
$this->getLog()->error('fetchDuration: unable to get PDF page count, e: ' . $e->getMessage());
}
} else {
$pageCount = $cachedPageCount;
}

$durationProvider->setDuration($durationProvider->getWidget()->calculatedDuration * $pageCount);
}
return $this;
}

public function getDataCacheKey(DataProviderInterface $dataProvider): ?string
{
return null;
}

public function getDataModifiedDt(DataProviderInterface $dataProvider): ?Carbon
{
return null;
}
}
Loading

0 comments on commit 6ab3bd7

Please sign in to comment.