Skip to content

Commit

Permalink
Merge pull request #2109 from xibosignage/develop
Browse files Browse the repository at this point in the history
Release 4.0.3
  • Loading branch information
dasgarner authored Sep 19, 2023
2 parents ce84386 + 010ec27 commit 0419cb8
Show file tree
Hide file tree
Showing 52 changed files with 1,842 additions and 1,222 deletions.
2 changes: 2 additions & 0 deletions docker/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ then
echo "#!/bin/bash" > /var/www/maintenance.sh
echo "" >> /var/www/maintenance.sh
/usr/bin/env | sed 's/^\(.*\)$/export \1/g' | grep -E "^export MYSQL" >> /var/www/maintenance.sh
/usr/bin/env | sed 's/^\(.*\)$/export \1/g' | grep -E "^export MEMCACHED" >> /var/www/maintenance.sh
echo "export CMS_USE_MEMCACHED=$CMS_USE_MEMCACHED" >> /var/www/maintenance.sh
echo "cd /var/www/cms && /usr/bin/php bin/xtr.php" >> /var/www/maintenance.sh
chmod 755 /var/www/maintenance.sh

Expand Down
2 changes: 1 addition & 1 deletion lib/Controller/Module.php
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ public function clearCacheForm(Request $request, Response $response, $id)
public function clearCache(Request $request, Response $response, $id)
{
$module = $this->moduleFactory->getById($id);
if ($module->isDataProviderExpected() || $module->isWidgetProviderAvailable()) {
if ($module->isDataProviderExpected()) {
$this->moduleFactory->clearCacheForDataType($module->dataType);
}

Expand Down
5 changes: 3 additions & 2 deletions lib/Controller/Playlist.php
Original file line number Diff line number Diff line change
Expand Up @@ -291,17 +291,18 @@ public function grid(Request $request, Response $response)

// Embed the name of this widget
$widget->setUnmatchedProperty('moduleName', $module->name);
$widgetName = $widget->getOptionValue('name', null);

if ($module->regionSpecific == 0) {
// Use the media assigned to this widget
$media = $this->mediaFactory->getById($widget->getPrimaryMediaId());
$media->load();
$widget->setUnmatchedProperty('name', $widget->getOptionValue('name', $media->name));
$widget->setUnmatchedProperty('name', $widgetName ?: $media->name);

// Augment with tags
$widget->setUnmatchedProperty('tags', $media->tags);
} else {
$widget->setUnmatchedProperty('name', $widget->getOptionValue('name', $module->name));
$widget->setUnmatchedProperty('name', $widgetName ?: $module->name);
$widget->setUnmatchedProperty('tags', []);
}

Expand Down
3 changes: 2 additions & 1 deletion lib/Controller/Widget.php
Original file line number Diff line number Diff line change
Expand Up @@ -1120,7 +1120,8 @@ public function getData(Request $request, Response $response, $regionId, $id)
$module = $this->moduleFactory->getByType($widget->type);

// This is always a preview
if (!$module->isDataProviderExpected() && !$module->isWidgetProviderAvailable()) {
// We only return data if a data provider is expected.
if (!$module->isDataProviderExpected()) {
return $response->withJson([]);
}

Expand Down
35 changes: 22 additions & 13 deletions lib/Entity/Layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -1643,26 +1643,35 @@ public function toXlf()
$mediaNode->setAttribute('fileId', $media->mediaId);
}

// Tracker whether we have an updateInterval configured.
// Track whether we have an updateInterval configured.
$hasUpdatedInterval = false;

// Output all properties belonging to the module
// Output all properties belonging to the module (we are not interested in templates because they
// are all HTML rendered)
$module->decorateProperties($widget, true, false);

foreach ($module->properties as $property) {
if ($property->isCData()) {
if ($property->value !== null) {
$optionNode = $document->createElement($property->id);
// We only output properties for native rendered widgets
if ($module->renderAs === 'native') {
if (($uriInjected && $property->id == 'uri') || empty($property->id)) {
// Skip any property named "uri" if we've already injected a special node for that.
// Skip properties without an id
continue;
}

// We have something to output
$optionNode = $document->createElement($property->id);

if ($property->isCData()) {
$cdata = $document->createCDATASection($property->value);
$optionNode->appendChild($cdata);

// Add to the raw node
$rawNode->appendChild($optionNode);
}
} else {
// Skip any property named "uri" if we've already injected a special node for that.
if ($uriInjected && $property->id == 'uri') {
continue;
}
} else {
$optionNode->nodeValue = $property->value ?? '';

if (!empty($property->id)) {
$optionNode = $document->createElement($property->id, $property->value ?? '');
// Add to the options node
$optionsNode->appendChild($optionNode);
}
}
Expand Down
9 changes: 0 additions & 9 deletions lib/Entity/Module.php
Original file line number Diff line number Diff line change
Expand Up @@ -351,15 +351,6 @@ public function hasRequiredElements(): bool
return count($this->requiredElements) > 0;
}

/**
* Is a widget provider available
* @return bool
*/
public function isWidgetProviderAvailable(): bool
{
return $this->widgetProvider !== null;
}

/**
* Get this module's widget provider, or null if there isn't one
* @return \Xibo\Widget\Provider\WidgetProviderInterface|null
Expand Down
25 changes: 22 additions & 3 deletions lib/Entity/ModulePropertyTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@
trait ModulePropertyTrait
{
/**
* @param \Xibo\Entity\Widget $widget
* @param Widget $widget
* @param bool $includeDefaults
* @param bool $reverseFilters Reverse filters?
* @return $this
*/
public function decorateProperties(Widget $widget, bool $includeDefaults = false)
public function decorateProperties(Widget $widget, bool $includeDefaults = false, bool $reverseFilters = true)
{
foreach ($this->properties as $property) {
$property->value = $widget->getOptionValue($property->id, null);
Expand All @@ -54,7 +55,9 @@ public function decorateProperties(Widget $widget, bool $includeDefaults = false
}
}

$property->reverseFilters();
if ($reverseFilters) {
$property->reverseFilters();
}
}
return $this;
}
Expand Down Expand Up @@ -162,6 +165,22 @@ public function getPropertyValues(
return $properties;
}

/**
* Gets the default value for a property
* @param string $id
* @return mixed
*/
public function getPropertyDefault(string $id): mixed
{
foreach ($this->properties as $property) {
if ($property->id === $id) {
return $property->default;
}
}

return null;
}

/**
* @throws \Xibo\Support\Exception\InvalidArgumentException|\Xibo\Support\Exception\ValueTooLargeException
*/
Expand Down
12 changes: 0 additions & 12 deletions lib/Entity/Widget.php
Original file line number Diff line number Diff line change
Expand Up @@ -973,18 +973,6 @@ public function save($options = [])
foreach ($this->widgetOptions as $widgetOption) {
// Assert the widgetId
$widgetOption->widgetId = $this->widgetId;

// Handle widgetId inside of the option value
if ($options['import'] && $widgetOption->option === 'elements') {
$widgetElements = $this->getOptionValue('elements', null);
$widgetElements = json_decode($widgetElements, true);
foreach ($widgetElements as $widgetIndex => $widgetElement) {
$widgetElements[$widgetIndex]['widgetId'] = $this->widgetId;
}

$this->setOptionValue('elements', 'raw', json_encode($widgetElements));
}

$widgetOption->save();
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/Helper/Environment.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
*/
class Environment
{
public static $WEBSITE_VERSION_NAME = '4.0.2';
public static $WEBSITE_VERSION_NAME = '4.0.3';
public static $XMDS_VERSION = '7';
public static $XLF_VERSION = 4;
public static $VERSION_REQUIRED = '8.1.0';
Expand Down
175 changes: 26 additions & 149 deletions lib/Service/DisplayNotifyService.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
use Xibo\Storage\StorageServiceInterface;
use Xibo\Support\Exception\DeadlockException;
use Xibo\XMR\CollectNowAction;
use Xibo\XMR\DataUpdateAction;

/**
* Class DisplayNotifyService
Expand Down Expand Up @@ -395,159 +396,17 @@ public function notifyByCampaignId($campaignId)
/** @inheritdoc */
public function notifyByDataSetId($dataSetId)
{
$this->log->debug('Notify by DataSetId ' . $dataSetId);
$this->log->debug('notifyByDataSetId: dataSetId: ' . $dataSetId);

if (in_array('dataSet_' . $dataSetId, $this->keysProcessed)) {
$this->log->debug('Already processed ' . $dataSetId . ' skipping this time.');
if (in_array('dataSet', $this->keysProcessed)) {
$this->log->debug('notifyByDataSetId: already processed.');
return;
}

$sql = '
SELECT DISTINCT display.displayId,
schedule.eventId,
schedule.fromDt,
schedule.toDt,
schedule.recurrence_type AS recurrenceType,
schedule.recurrence_detail AS recurrenceDetail,
schedule.recurrence_range AS recurrenceRange,
schedule.recurrenceRepeatsOn,
schedule.lastRecurrenceWatermark,
schedule.dayPartId
FROM `schedule`
INNER JOIN `lkscheduledisplaygroup`
ON `lkscheduledisplaygroup`.eventId = `schedule`.eventId
INNER JOIN `lkdgdg`
ON `lkdgdg`.parentId = `lkscheduledisplaygroup`.displayGroupId
INNER JOIN `lkdisplaydg`
ON lkdisplaydg.DisplayGroupID = `lkdgdg`.childId
INNER JOIN `display`
ON lkdisplaydg.DisplayID = display.displayID
INNER JOIN `lkcampaignlayout`
ON `lkcampaignlayout`.campaignId = `schedule`.campaignId
INNER JOIN `region`
ON `region`.layoutId = `lkcampaignlayout`.layoutId
INNER JOIN `playlist`
ON `playlist`.regionId = `region`.regionId
INNER JOIN `widget`
ON `widget`.playlistId = `playlist`.playlistId
INNER JOIN `widgetoption`
ON `widgetoption`.widgetId = `widget`.widgetId
AND `widgetoption`.type = \'attrib\'
AND `widgetoption`.option = \'dataSetId\'
AND `widgetoption`.value = :activeDataSetId
WHERE (
(schedule.FromDT < :toDt AND IFNULL(`schedule`.toDt, UNIX_TIMESTAMP()) > :fromDt)
OR `schedule`.recurrence_range >= :fromDt
OR (
IFNULL(`schedule`.recurrence_range, 0) = 0 AND IFNULL(`schedule`.recurrence_type, \'\') <> \'\'
)
)
UNION
SELECT DISTINCT display.displayId,
0 AS eventId,
0 AS fromDt,
0 AS toDt,
NULL AS recurrenceType,
NULL AS recurrenceDetail,
NULL AS recurrenceRange,
NULL AS recurrenceRepeatsOn,
NULL AS lastRecurrenceWatermark,
NULL AS dayPartId
FROM `display`
INNER JOIN `lkcampaignlayout`
ON `lkcampaignlayout`.LayoutID = `display`.DefaultLayoutID
INNER JOIN `region`
ON `region`.layoutId = `lkcampaignlayout`.layoutId
INNER JOIN `playlist`
ON `playlist`.regionId = `region`.regionId
INNER JOIN `widget`
ON `widget`.playlistId = `playlist`.playlistId
INNER JOIN `widgetoption`
ON `widgetoption`.widgetId = `widget`.widgetId
AND `widgetoption`.type = \'attrib\'
AND `widgetoption`.option = \'dataSetId\'
AND `widgetoption`.value = :activeDataSetId2
UNION
SELECT DISTINCT `lkdisplaydg`.displayId,
0 AS eventId,
0 AS fromDt,
0 AS toDt,
NULL AS recurrenceType,
NULL AS recurrenceDetail,
NULL AS recurrenceRange,
NULL AS recurrenceRepeatsOn,
NULL AS lastRecurrenceWatermark,
NULL AS dayPartId
FROM `lklayoutdisplaygroup`
INNER JOIN `lkdgdg`
ON `lkdgdg`.parentId = `lklayoutdisplaygroup`.displayGroupId
INNER JOIN `lkdisplaydg`
ON lkdisplaydg.DisplayGroupID = `lkdgdg`.childId
INNER JOIN `lkcampaignlayout`
ON `lkcampaignlayout`.layoutId = `lklayoutdisplaygroup`.layoutId
INNER JOIN `region`
ON `region`.layoutId = `lkcampaignlayout`.layoutId
INNER JOIN `playlist`
ON `playlist`.regionId = `region`.regionId
INNER JOIN `widget`
ON `widget`.playlistId = `playlist`.playlistId
INNER JOIN `widgetoption`
ON `widgetoption`.widgetId = `widget`.widgetId
AND `widgetoption`.type = \'attrib\'
AND `widgetoption`.option = \'dataSetId\'
AND `widgetoption`.value = :activeDataSetId3
';

$currentDate = Carbon::now();
$rfLookAhead = $currentDate->copy()->addSeconds($this->config->getSetting('REQUIRED_FILES_LOOKAHEAD'));

$params = [
'fromDt' => $currentDate->subHour()->format('U'),
'toDt' => $rfLookAhead->format('U'),
'activeDataSetId' => $dataSetId,
'activeDataSetId2' => $dataSetId,
'activeDataSetId3' => $dataSetId
];

foreach ($this->store->select($sql, $params) as $row) {
// Don't process if the displayId is already in the collection (there is little point in running the
// extra query)
if (in_array($row['displayId'], $this->displayIds)) {
$this->log->debug('displayId ' . $row['displayId'] . ' already in collection, skipping.');
continue;
}

// Is this schedule active?
if ($row['eventId'] != 0) {
$scheduleEvents = $this->scheduleFactory
->createEmpty()
->hydrate($row)
->getEvents($currentDate, $rfLookAhead);

if (count($scheduleEvents) <= 0) {
$this->log->debug(
'Skipping eventId ' . $row['eventId'] .
' because it doesnt have any active events in the window'
);
continue;
}
}

$this->log->debug(
'DataSet[' . $dataSetId .'] change caused notify on displayId[' .
$row['displayId'] . ']'
);

$this->displayIds[] = $row['displayId'];

if ($this->collectRequired) {
$this->displayIdsRequiringActions[] = $row['displayId'];
}
}

$this->keysProcessed[] = 'dataSet_' . $dataSetId;

$this->log->debug('Finished notify for dataSetId ' . $dataSetId);
// Set the Sync task to runNow
$this->store->update('UPDATE `task` SET `runNow` = 1 WHERE `class` LIKE :taskClassLike', [
'taskClassLike' => '%WidgetSyncTask%',
]);
}

/** @inheritdoc */
Expand Down Expand Up @@ -1057,4 +916,22 @@ public function notifyByMenuBoardId($menuId)

$this->log->debug('Finished notify for Menu Board ID ' . $menuId);
}

/** @inheritdoc */
public function notifyDataUpdate(Display $display, int $widgetId): void
{
if (in_array('dataUpdate_' . $display->displayId . '_' . $widgetId, $this->keysProcessed)) {
$this->log->debug('notifyDataUpdate: Already processed displayId: ' . $display->displayId
. ', widgetId: ' . $widgetId . ', skipping this time.');
return;
}
$this->log->debug('notifyDataUpdate: Process displayId: ' . $display->displayId . ', widgetId: ' . $widgetId);

try {
$this->playerActionService->sendAction($display, new DataUpdateAction($widgetId));
} catch (\Exception $e) {
$this->log->notice('notifyDataUpdate: displayId: ' . $display->displayId
. ', save would have triggered Player Action, but the action failed with message: ' . $e->getMessage());
}
}
}
Loading

0 comments on commit 0419cb8

Please sign in to comment.