Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misc Fixes: #1980

Merged
merged 7 commits into from
Aug 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading