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

v4 snagging for rc1 #1955

Merged
merged 9 commits into from
Aug 2, 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
20 changes: 8 additions & 12 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion db/migrations/20180130073838_install_migration.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
/**
* Class InstallMigration
* migration for initial installation of database
* @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
* @phpcs:disable Generic.Files.LineLength.TooLong
*/
class InstallMigration extends AbstractMigration
{
Expand Down Expand Up @@ -1068,7 +1070,6 @@ private function addData()
(55, \'LIBRARY_MEDIA_UPDATEINALL_CHECKB\', \'Checked\', \'dropdown\', \'Default the checkbox for updating media on all layouts when editing in the library\', \'Checked|Unchecked\', \'defaults\', 1, \'Default update media in all layouts\', \'\', 10, \'Unchecked\', 1, \'word\'),
(56, \'USER_PASSWORD_POLICY\', \'\', \'text\', \'Regular Expression for password complexity, leave blank for no policy.\', \'\', \'users\', 1, \'Password Policy Regular Expression\', \'\', 20, \'\', 1, \'string\'),
(57, \'USER_PASSWORD_ERROR\', \'\', \'text\', \'A text description of this password policy. Will be show to users when their password does not meet the required policy\', \'\', \'users\', 1, \'Description of Password Policy\', \'\', 30, \'\', 1, \'string\'),
(58, \'MODULE_CONFIG_LOCKED_CHECKB\', \'Unchecked\', \'dropdown\', \'Is the module config locked? Useful for Service providers.\', \'Checked|Unchecked\', \'defaults\', 0, \'Lock Module Config\', \'\', 30, \'Unchecked\', 0, \'word\'),
(59, \'LIBRARY_SIZE_LIMIT_KB\', \'0\', \'number\', \'The Limit for the Library Size in KB\', NULL, \'network\', 0, \'Library Size Limit\', \'\', 50, \'0\', 1, \'int\'),
(60, \'MONTHLY_XMDS_TRANSFER_LIMIT_KB\', \'0\', \'number\', \'XMDS Transfer Limit in KB/month\', NULL, \'network\', 0, \'Monthly bandwidth Limit\', \'\', 40, \'0\', 1, \'int\'),
(61, \'DEFAULT_LANGUAGE\', \'en_GB\', \'text\', \'The default language to use\', NULL, \'regional\', 1, \'Default Language\', \'\', 10, \'en_GB\', 1, \'string\'),
Expand Down
4 changes: 0 additions & 4 deletions lib/Controller/Module.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,6 @@ public function grid(Request $request, Response $response)
public function settingsForm(Request $request, Response $response, $id)
{
// Can we edit?
$moduleConfigLocked = $this->getConfig()->getSetting('MODULE_CONFIG_LOCKED_CHECKB') == 1
|| $this->getConfig()->getSetting('MODULE_CONFIG_LOCKED_CHECKB') == 'Checked';

if (!$this->getUser()->userTypeId == 1) {
throw new AccessDeniedException();
}
Expand All @@ -160,7 +157,6 @@ public function settingsForm(Request $request, Response $response, $id)
// Pass to view
$this->getState()->template = 'module-form-settings';
$this->getState()->setData([
'moduleConfigLocked' => $moduleConfigLocked,
'moduleId' => $id,
'module' => $module,
]);
Expand Down
6 changes: 1 addition & 5 deletions lib/Controller/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ public function displayPage(Request $request, Response $response)
* @throws InvalidArgumentException
* @throws \Xibo\Support\Exception\ControllerNotImplemented
* @throws \Xibo\Support\Exception\GeneralException
* @phpcs:disable Generic.Files.LineLength.TooLong
*/
public function update(Request $request, Response $response)
{
Expand Down Expand Up @@ -638,11 +639,6 @@ public function update(Request $request, Response $response)
$this->getConfig()->changeSetting('SCHEDULE_SHOW_LAYOUT_NAME', $sanitizedParams->getCheckbox('SCHEDULE_SHOW_LAYOUT_NAME'));
}

if ($this->getConfig()->isSettingEditable('MODULE_CONFIG_LOCKED_CHECKB')) {
$this->handleChangedSettings('MODULE_CONFIG_LOCKED_CHECKB', $this->getConfig()->getSetting('MODULE_CONFIG_LOCKED_CHECKB'), $sanitizedParams->getCheckbox('MODULE_CONFIG_LOCKED_CHECKB'), $changedSettings);
$this->getConfig()->changeSetting('MODULE_CONFIG_LOCKED_CHECKB', $sanitizedParams->getCheckbox('MODULE_CONFIG_LOCKED_CHECKB'));
}

if ($this->getConfig()->isSettingEditable('TASK_CONFIG_LOCKED_CHECKB')) {
$this->handleChangedSettings('TASK_CONFIG_LOCKED_CHECKB', $this->getConfig()->getSetting('TASK_CONFIG_LOCKED_CHECKB'), $sanitizedParams->getCheckbox('TASK_CONFIG_LOCKED_CHECKB'), $changedSettings);
$this->getConfig()->changeSetting('TASK_CONFIG_LOCKED_CHECKB', $sanitizedParams->getCheckbox('TASK_CONFIG_LOCKED_CHECKB'));
Expand Down
12 changes: 12 additions & 0 deletions lib/Entity/Module.php
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,18 @@ private function getSettingsForSaving(): string
return count($settings) > 0 ? json_encode($settings) : '[]';
}

/**
* @return array
*/
public function getSettingsForOutput(): array
{
$settings = [];
foreach ($this->settings as $setting) {
$settings[$setting->id] = $setting->value ?? $setting->default;
}
return $settings;
}

/**
* Delete this module
* @return void
Expand Down
47 changes: 28 additions & 19 deletions lib/Factory/ModuleXmlTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,22 +125,7 @@ private function parseProperties($propertyNodes, ?Module $module = null): array
$defaultValue = $this->getFirstValueOrDefaultFromXmlNode($node, 'default');

// Is this a variable?
if ($defaultValue !== null) {
// If we're not empty, then try and do any variable substitutions
if (!empty($defaultValue)) {
if ($module !== null
&& Str::startsWith($defaultValue, '%')
&& Str::endsWith($defaultValue, '%')
) {
$defaultValue = $module->getSetting(str_replace('%', '', $defaultValue));
} else if (Str::startsWith($defaultValue, '#')
&& Str::endsWith($defaultValue, '#')
) {
$defaultValue = $this->getConfig()->getSetting(str_replace('#', '', $defaultValue));
}
}
$defaultValues[$property->id] = $defaultValue;
}
$defaultValues[$property->id] = $this->decorateWithSettings($module, $defaultValue);

// Validation (rule) conditions
$validationNodes = $node->getElementsByTagName('rule');
Expand All @@ -163,7 +148,7 @@ private function parseProperties($propertyNodes, ?Module $module = null): array
$conditions[] = [
'field' => $condNode->getAttribute('field'),
'type' => $condNode->getAttribute('type'),
'value' => $condNode->textContent
'value' => $this->decorateWithSettings($module, trim($condNode->textContent)),
];
}
}
Expand Down Expand Up @@ -195,7 +180,7 @@ private function parseProperties($propertyNodes, ?Module $module = null): array
$optionNode->getAttribute('name'),
$optionNode->getAttribute('image'),
$set,
$optionNode->textContent
trim($optionNode->textContent),
);
}
}
Expand All @@ -213,7 +198,7 @@ private function parseProperties($propertyNodes, ?Module $module = null): array
$conditions[] = [
'field' => $condNode->getAttribute('field'),
'type' => $condNode->getAttribute('type'),
'value' => $condNode->textContent
'value' => $this->decorateWithSettings($module, trim($condNode->textContent)),
];
}
}
Expand Down Expand Up @@ -260,6 +245,30 @@ private function parseProperties($propertyNodes, ?Module $module = null): array
return $properties;
}

/**
* Take a value and decorate it with any module/global settings
* @param Module|null $module
* @param string|null $value
* @return string|null
*/
private function decorateWithSettings(?Module $module, ?string $value): ?string
{
// If we're not empty, then try and do any variable substitutions
if (!empty($value)) {
if ($module !== null
&& Str::startsWith($value, '%')
&& Str::endsWith($value, '%')
) {
$value = $module->getSetting(str_replace('%', '', $value));
} else if (Str::startsWith($value, '#')
&& Str::endsWith($value, '#')
) {
$value = $this->getConfig()->getSetting(str_replace('#', '', $value));
}
}
return $value;
}

/**
* @param \DOMNode[]|\DOMNodeList $propertyGroupNodes
* @return array
Expand Down
2 changes: 1 addition & 1 deletion lib/Widget/Render/WidgetHtmlRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ private function render(
if ($module->stencil->twig !== null) {
$twig['twig'][] = $this->twig->fetchFromString(
$this->decorateTranslations($module->stencil->twig),
$module->getPropertyValues()
array_merge($module->getPropertyValues(), ['settings' => $module->getSettingsForOutput()]),
);
}
if ($module->stencil->hbs !== null) {
Expand Down
Binary file not shown.
8 changes: 4 additions & 4 deletions modules/clock-digital.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
<title>Enter a format for the Digital Clock e.g. [HH:mm] or [DD/MM/YYYY]. See the manual for more information.</title>
</property>
<property id="format" type="richText" allowLibraryRefs="true">
<title>Enter text or HTML in the box below.</title>
<title>Enter text in the box below.</title>
<default><![CDATA[
<span style="font-size: 48px; color:#1c1c1c;">[HH:mm:ss]</span>
]]></default>
Expand All @@ -56,9 +56,9 @@
<option name="DD/MM/YYYY">Day/Month/Year</option>
</options>
</property>
<property id="offset" type="text">
<property id="offset" type="number">
<title>Offset</title>
<helpText>The offset in minutes that should be applied to the current time, or if a counter then date/time to run from in the format Y-m-d H:i:s.</helpText>
<helpText>The offset in minutes that should be applied to the current time.</helpText>
<default></default>
</property>
</properties>
Expand Down Expand Up @@ -87,7 +87,7 @@ xiboIC.set(
var offset = properties.offset || 0;
$(".clock").each(function() {
$(this).html(moment().format($(this).attr("format")));
$(this).html(moment().add(' + offset + ', "m").format($(this).attr("format")));
$(this).html(moment().add(offset, "m").format($(this).attr("format")));
});
}
);
Expand Down
3 changes: 0 additions & 3 deletions modules/countdown-custom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,4 @@ $contentContainer.xiboCountdownRender(
$contentContainer.html(),
);
]]></onRender>
<assets>
<asset id="countdown-custom-thumb" type="path" cmsOnly="true" mimeType="image/png" path="/modules/assets/template-thumbnails/countdown/countdown-custom-thumb.png" />
</assets>
</module>
64 changes: 49 additions & 15 deletions modules/googletraffic.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,12 @@
<default></default>
</property>
<property id="minDuration" type="number">
<title>Minimum allowed duration</title>
<helpText>Please enter a minimum allowed duration in seconds for this Module. This can be used to prevent run-away charges.</helpText>
</property>
<property id="resetAllWidgets" type="checkbox">
<title>Reset all Widgets to the minimum duration?</title>
<default>0</default>
<title>Minimum recommended duration</title>
<helpText>Please enter a minimum recommended duration in seconds for this Module.</helpText>
<default>600</default>
</property>
<property type="message" variant="danger">
<title>This module uses the Google Traffic JavaScript API which is a paid-for API from Google. Charges will apply each time the map is loaded in the CMS preview and on each Player, therefore we recommend setting a high minimum duration.</title>
<title>This module uses the Google Traffic JavaScript API which is a paid-for API from Google. Charges will apply each time the map is loaded in the CMS preview and on each Player, therefore we recommend setting a high widget duration.</title>
<default></default>
</property>
</settings>
Expand All @@ -61,7 +58,7 @@
<property id="latitude" type="number">
<title>Latitude</title>
<helpText>The Latitude for this widget</helpText>
<default>0</default>
<default>#DEFAULT_LAT#</default>
<visibility>
<test>
<condition field="useDisplayLocation" type="eq">0</condition>
Expand All @@ -71,7 +68,7 @@
<property id="longitude" type="number">
<title>Longitude</title>
<helpText>The Longitude for this widget</helpText>
<default>0</default>
<default>#DEFAULT_LONG#</default>
<visibility>
<test>
<condition field="useDisplayLocation" type="eq">0</condition>
Expand All @@ -81,15 +78,26 @@
<property id="zoom" type="number">
<title>Zoom</title>
<helpText>How far should the map be zoomed in? The higher the number the closer, 1 represents the entire globe.</helpText>
<default>1</default>
<default>15</default>
</property>
<property type="message">
<title>This module is rendered on the Player which means the Player must have an internet connection.</title>
<default></default>
</property>
<property type="message">
<title>The Traffic Widget has not been configured yet, please ask your CMS Administrator to look at it for you.</title>
<default></default>
<visibility>
<test>
<condition type="ne">%apiKey%</condition>
</test>
</visibility>
</property>
<property type="message" variant="danger">
<title>You have entered a duration lower than the recommended minimum, this could cause significant API charges.</title>
<visibility>
<test>
<condition field="duration" type="lt">%minDuration%</condition>
</test>
</visibility>
</property>
</properties>
<preview></preview>
Expand All @@ -98,7 +106,7 @@

]]></hbs>
<twig><![CDATA[
<script async defer src="https://maps.googleapis.com/maps/api/js?key={{ apiKey }}&callback=initMap"></script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key={{ settings.apiKey }}&callback=init"></script>

<style>
body {
Expand All @@ -117,10 +125,36 @@ h1, h2, h3, h4, p {
</style>

<script type="text/javascript">
function initMap() {
function init() {
var lat = {{ latitude }};
var lng = {{ longitude }};
// Not preview and useDisplayLocation
if ({{useDisplayLocation}} === 1 && !xiboIC.checkIsPreview()) {
// Get the lat/lng from player info.
xiboIC.info({
done: function(xhr) {
info = JSON.parse(xhr.responseText);
if (info && info.latitude) {
lat = info.latitude;
}
if (info && info.longitude) {
lng = info.longitude;
}
initMap(lat, lng);
},
error: function() {
initMap(lat, lng);
}
});
} else {
initMap(lat, lng);
}
}

function initMap(lat, lng) {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: {{ zoom }},
center: {lat: {{ latitude }}, lng: {{ longitude }}},
center: {lat: lat, lng: lng},
disableDefaultUI: true
});

Expand Down
Loading
Loading