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

Interactive : navigate to Layout action, fix potential infinite loop. #1543

Merged
merged 3 commits into from
Jan 17, 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
130 changes: 70 additions & 60 deletions lib/Factory/LayoutFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -2470,70 +2470,80 @@ public function handleWidgetMediaIdReferences($widget, $newMediaId, $oldMediaId)
/**
* @param int $layoutId
* @param array $actionLayoutIds
* @param array $processedLayoutIds
* @return array
*/
public function getActionPublishedLayoutIds(int $layoutId, array &$actionLayoutIds): array
public function getActionPublishedLayoutIds(int $layoutId, array &$actionLayoutIds, array &$processedLayoutIds): array
{
// Get Layout Codes set in Actions on this Layout
// Actions directly on this Layout
$sql = '
SELECT DISTINCT `action`.layoutCode
FROM `action`
INNER JOIN `layout`
ON `layout`.layoutId = `action`.sourceId
WHERE `action`.actionType = :actionType
AND `layout`.layoutId = :layoutId
AND `layout`.parentId IS NULL
';

// Actions on this Layout's Regions
$sql .= '
UNION
SELECT DISTINCT `action`.layoutCode
FROM `action`
INNER JOIN `region`
ON `region`.regionId = `action`.sourceId
INNER JOIN `layout`
ON `layout`.layoutId = `region`.layoutId
WHERE `action`.actionType = :actionType
AND `layout`.layoutId = :layoutId
AND `layout`.parentId IS NULL
';

// Actions on this Layout's Widgets
$sql .= '
UNION
SELECT DISTINCT `action`.layoutCode
FROM `action`
INNER JOIN `widget`
ON `widget`.widgetId = `action`.sourceId
INNER JOIN `playlist`
ON `playlist`.playlistId = `widget`.playlistId
INNER JOIN `region`
ON `region`.regionId = `playlist`.regionId
INNER JOIN `layout`
ON `layout`.layoutId = `region`.layoutId
WHERE `action`.actionType = :actionType
AND `layout`.layoutId = :layoutId
AND `layout`.parentId IS NULL
';

// Join them together and get the Layout's referenced by those codes
$actionLayoutCodes = $this->getStore()->select('
SELECT `layout`.layoutId
FROM `layout`
WHERE `layout`.code IN (
' . $sql . '
)
', [
'actionType' => 'navLayout',
'layoutId' => $layoutId,
]);
// if Layout was already processed, do not attempt to do it again
// we should have all actionLayoutsIds from it at this point, there is no need to process it again
if (!in_array($layoutId, $processedLayoutIds)) {
// Get Layout Codes set in Actions on this Layout
// Actions directly on this Layout
$sql = '
SELECT DISTINCT `action`.layoutCode
FROM `action`
INNER JOIN `layout`
ON `layout`.layoutId = `action`.sourceId
WHERE `action`.actionType = :actionType
AND `layout`.layoutId = :layoutId
AND `layout`.parentId IS NULL
';

foreach ($actionLayoutCodes as $row) {
$actionLayoutIds[] = $row['layoutId'];
// check if this layout is linked with any further navLayout actions
$this->getActionPublishedLayoutIds($row['layoutId'], $actionLayoutIds);
// Actions on this Layout's Regions
$sql .= '
UNION
SELECT DISTINCT `action`.layoutCode
FROM `action`
INNER JOIN `region`
ON `region`.regionId = `action`.sourceId
INNER JOIN `layout`
ON `layout`.layoutId = `region`.layoutId
WHERE `action`.actionType = :actionType
AND `layout`.layoutId = :layoutId
AND `layout`.parentId IS NULL
';

// Actions on this Layout's Widgets
$sql .= '
UNION
SELECT DISTINCT `action`.layoutCode
FROM `action`
INNER JOIN `widget`
ON `widget`.widgetId = `action`.sourceId
INNER JOIN `playlist`
ON `playlist`.playlistId = `widget`.playlistId
INNER JOIN `region`
ON `region`.regionId = `playlist`.regionId
INNER JOIN `layout`
ON `layout`.layoutId = `region`.layoutId
WHERE `action`.actionType = :actionType
AND `layout`.layoutId = :layoutId
AND `layout`.parentId IS NULL
';

// Join them together and get the Layout's referenced by those codes
$actionLayoutCodes = $this->getStore()->select('
SELECT `layout`.layoutId
FROM `layout`
WHERE `layout`.code IN (
' . $sql . '
)
', [
'actionType' => 'navLayout',
'layoutId' => $layoutId,
]);

$processedLayoutIds[] = $layoutId;

foreach ($actionLayoutCodes as $row) {
// if we have not processed this Layout yet, do it now
if (!in_array($row['layoutId'], $actionLayoutIds)) {
$actionLayoutIds[] = $row['layoutId'];
// check if this layout is linked with any further navLayout actions
$this->getActionPublishedLayoutIds($row['layoutId'], $actionLayoutIds, $processedLayoutIds);
}
}
}

return $actionLayoutIds;
Expand Down
3 changes: 2 additions & 1 deletion lib/Xmds/Soap.php
Original file line number Diff line number Diff line change
Expand Up @@ -501,9 +501,10 @@ protected function doRequiredFiles($serverKey, $hardwareKey, $httpDownloads)

// workout if any of the layouts we have in our list has Actions pointing to another Layout.
$actionLayoutIds = [];
$processedLayoutIds = [];
foreach ($layouts as $layoutId) {
// this is recursive function, as we need to get 2nd level nesting and beyond
$this->layoutFactory->getActionPublishedLayoutIds($layoutId, $actionLayoutIds);
$this->layoutFactory->getActionPublishedLayoutIds($layoutId, $actionLayoutIds, $processedLayoutIds);

// merge the Action layouts to our array, we need the player to download all resources on them
if (!empty($actionLayoutIds)) {
Expand Down