diff --git a/zenario/admin/db_updates/latest_revision_no.inc.php b/zenario/admin/db_updates/latest_revision_no.inc.php index dec5c29f1..ad5ae49cf 100644 --- a/zenario/admin/db_updates/latest_revision_no.inc.php +++ b/zenario/admin/db_updates/latest_revision_no.inc.php @@ -27,8 +27,8 @@ */ if (!defined('NOT_ACCESSED_DIRECTLY')) exit('This file may not be directly accessed'); -define('LATEST_REVISION_NO', 45403); //N.b. 8.2 starts at revision #45600 -define('LATEST_BIG_CHANGE_REVISION_NO', 45400); +define('LATEST_REVISION_NO', 45404); //N.b. 8.3 starts at revision #45600 +define('LATEST_BIG_CHANGE_REVISION_NO', 45404); define('INSTALLER_REVISION_NO', 41600); define('INSTALLER_DEFAULT_THEME', 'duke_street'); @@ -37,6 +37,6 @@ define('ZENARIO_MAJOR_VERSION', '8'); define('ZENARIO_MINOR_VERSION', '2'); define('ZENARIO_IS_BUILD', true); -define('ZENARIO_REVISION', '46436'); +define('ZENARIO_REVISION', '46614'); define('TINYMCE_DIR', 'zenario/libs/manually_maintained/lgpl/tinymce_4_7_3/'); \ No newline at end of file diff --git a/zenario/autoload/datasetAdm.php b/zenario/autoload/datasetAdm.php index ea857b303..ffb77338d 100644 --- a/zenario/autoload/datasetAdm.php +++ b/zenario/autoload/datasetAdm.php @@ -261,6 +261,7 @@ public static function listCustomFields($dataset, $flat = true, $filter = false, [ 'group', 'checkbox', + 'consent', 'checkboxes', 'date', 'editor', diff --git a/zenario/autoload/document.php b/zenario/autoload/document.php index fd502eac6..b439eda3c 100644 --- a/zenario/autoload/document.php +++ b/zenario/autoload/document.php @@ -128,6 +128,7 @@ public static function createFolder($name, $parentId = false, $makeNameUnqiue = 'type' => 'folder', 'folder_name' => $name, 'folder_id' => $parentId, + 'privacy' => 'public', 'ordinal' => 0 ] ); diff --git a/zenario/js/panel_type_form_builder.js b/zenario/js/panel_type_form_builder.js index 6b2693f40..5e39a38e8 100644 --- a/zenario/js/panel_type_form_builder.js +++ b/zenario/js/panel_type_form_builder.js @@ -475,7 +475,7 @@ methods.loadFieldDetailsPage = function(page, fieldId, errors) { }); } } else if (page == 'translations') { - var transFieldNamesList = _.toArray(thus.tuix.field_details.tabs[page].translapagele_fields); + var transFieldNamesList = _.toArray(thus.tuix.field_details.tabs[page].translatable_fields); var transFieldNames = {}; for (var i = 0; i < transFieldNamesList.length; i++) { transFieldNames[transFieldNamesList[i]] = true; @@ -1619,7 +1619,7 @@ methods.addNewField = function(type, ord, datasetFieldId, datasetPageId, dataset if (datasetField.db_column == 'terms_and_conditions_accepted') { newField.field_label = 'By submitting your details you are agreeing that we can store your data for legitimate business purposes and contact you to inform you about our products and services.'; - newField.note_to_user = 'Full details can be found in our privacy policy.'; + newField.note_to_user = 'Full details can be found in our privacy policy.'; } if (datasetField.dataset_repeat_grouping) { diff --git a/zenario/js/panel_type_form_builder.min.js b/zenario/js/panel_type_form_builder.min.js index c89705c75..3b1fc0860 100644 --- a/zenario/js/panel_type_form_builder.min.js +++ b/zenario/js/panel_type_form_builder.min.js @@ -15,7 +15,7 @@ function(){var b={},c;for(c in d.tuix.fields)if(n(d.tuix.fields,c)){var f=d.tuix JSON.parse(c.details.calculation_code):"";d.changeMadeToPanel();d.saveCurrentOpenDetails();d.loadFieldDetailsPage("details",a)})})}else if("advanced"==b)$("#field__css_classes").on("keyup",function(){$("#organizer_form_field_"+a+" .form_field_classes .css").toggle(!!$(this).val()).prop("title",$(this).val())}),$("#field__div_wrap_class").on("keyup",function(){$("#organizer_form_field_"+a+" .form_field_classes .div").toggle(!!$(this).val()).prop("title",$(this).val())});else if("values"==b)m.values&& !m.values._hidden&&(l=d.getOrderedFieldValues(a),f=d.microTemplate("zenario_organizer_admin_box_builder_field_value",l),$("#field_values_list").html(f).sortable({containment:"parent",tolerance:"pointer",axis:"y",start:function(a,b){d.startIndex=b.item.index()},stop:function(b,c){d.startIndex!=c.item.index()&&(d.saveFieldListOfValues(d.tuix.fields[a]),d.loadFieldValuesListPreview(a),d.changeMadeToPanel())}}),$("#field_values_list input").on("keyup",function(){var a=$(this).data("id");$("#organizer_field_value_"+ a+" label").text($(this).val());d.changeMadeToPanel()}),$("#organizer_add_a_field_value").on("click",function(){d.addFieldValue(e);d.saveItemTUIXPage("field_details",b,e);d.loadFieldDetailsPage(b,a);d.loadFieldValuesListPreview(a);d.changeMadeToPanel()}),$("#field_values_list .delete_icon").on("click",function(){var c=$(this).data("id");e.lov[c]&&(d.deletedValues.push(c),delete e.lov[c]);d.saveItemTUIXPage("field_details",b,e);d.loadFieldDetailsPage(b,a);d.loadFieldValuesListPreview(a);d.changeMadeToPanel()})); -else if("translations"==b){f=_._tA(d.tuix.field_details.tabs[b].translapagele_fields);c={};for(l=0;l=h;h++)this.addFieldValue(k,"Option "+h);else"repeat_start"==b&&this.addNewField("repeat_end",a+0.001);for(var t in this.tuix.field_details.tabs)if(n(this.tuix.field_details.tabs,t)&&(page=this.tuix.field_details.tabs[t],page.fields))for(var p in page.fields)n(page.fields,p)&&(d=page.fields[p],w(d.value)&&!w(k[p])&&(k[p]=d.value));if(k){if(f&&(k=JSON.parse(JSON.stringify(this.tuix.fields[f])),"checkboxes"==k.type||"select"==k.type||"radios"==k.type)){f=k.lov;delete k.lov;k.lov= {};for(var s in f)this.addFieldValue(k,f[s].label,f[s].ord)}k.ord=a;k._is_new=!0;k.just_added=!0;k.id=g;if("page_break"==b)b=this.getOrderedPages(),k.name="Page "+(b.length+1),k.fields={},this.tuix.items[g]=k,l||this.clickPage(g,!0);else if(this.tuix.items[this.currentPageId].fields[g]=1,this.tuix.fields[g]=k,!e||c)this.loadFieldsList(this.currentPageId),l||this.clickField(g,k.just_added)}};g.clickField=function(b,a){this.selectedFieldId!=b&&this.tuix.fields[b]&&"repeat_end"!=this.tuix.fields[b].type&& diff --git a/zenario/modules/zenario_banner/fun/formatAdminBox.php b/zenario/modules/zenario_banner/fun/formatAdminBox.php index 94681bf0d..1f3599fa3 100644 --- a/zenario/modules/zenario_banner/fun/formatAdminBox.php +++ b/zenario/modules/zenario_banner/fun/formatAdminBox.php @@ -33,6 +33,13 @@ if (!ze\module::inc('zenario_ctype_picture')) { unset($fields['first_tab/image_source']['values']['_PICTURE']); } + + $retinaSideNote = "If the source image is large enough, + the resized image will be output at twice its displayed width & height + to appear crisp on retina screens. + This will increase the download size. +
+ If the source image is not large enough this will have no effect."; $fields['first_tab/use_rollover']['hidden'] = @@ -94,6 +101,11 @@ !$imagePicked; $this->showHideImageOptions($fields, $values, 'first_tab', $hidden); + if ($values['first_tab/canvas'] != "unlimited") { + $fields['first_tab/canvas']['side_note'] = $retinaSideNote; + } else { + $fields['first_tab/canvas']['side_note'] = ""; + } $fields['first_tab/floating_box_title']['hidden'] = !$imagePicked @@ -164,6 +176,11 @@ $hidden = $values['first_tab/link_type'] != '_ENLARGE_IMAGE'; $this->showHideImageOptions($fields, $values, 'first_tab', $hidden, 'enlarge_'); + if ($values['first_tab/enlarge_canvas'] != "unlimited") { + $fields['first_tab/enlarge_canvas']['side_note'] = $retinaSideNote; + } else { + $fields['first_tab/enlarge_canvas']['side_note'] = ""; + } $cID = $cType = false; if ($values['first_tab/link_type'] == '_CONTENT_ITEM' @@ -216,6 +233,11 @@ $fields['mobile_tab/mobile_image']['hidden'] = $hideMobileOptions; $this->showHideImageOptions($fields, $values, 'mobile_tab', $hideMobileOptions, 'mobile_'); + if ($values['mobile_tab/mobile_canvas'] != "unlimited") { + $fields['mobile_tab/mobile_canvas']['side_note'] = $retinaSideNote; + } else { + $fields['mobile_tab/mobile_canvas']['side_note'] = ""; + } //Privacy warning: //Get selected document... diff --git a/zenario/modules/zenario_content_list/fun/formatAdminBox.php b/zenario/modules/zenario_content_list/fun/formatAdminBox.php index 9497d5c3b..35dd89212 100644 --- a/zenario/modules/zenario_content_list/fun/formatAdminBox.php +++ b/zenario/modules/zenario_content_list/fun/formatAdminBox.php @@ -33,8 +33,20 @@ $fields['each_item/author_retina']['hidden'] = !$values['each_item/show_author_image']; + $retinaSideNote = "If the source image is large enough, + the resized image will be output at twice its displayed width & height + to appear crisp on retina screens. + This will increase the download size. +
+ If the source image is not large enough this will have no effect."; + $hidden = !$values['each_item/show_author_image']; $this->showHideImageOptions($fields, $values, 'each_item', $hidden, 'author_'); + if ($values['each_item/author_canvas'] != "unlimited") { + $fields['each_item/author_canvas']['side_note'] = $retinaSideNote; + } else { + $fields['each_item/author_canvas']['side_note'] = ""; + } $fields['overall_list/heading_if_items']['hidden'] = $fields['overall_list/heading_tags']['hidden'] = @@ -55,6 +67,11 @@ $hidden = !$values['each_item/show_sticky_images']; $this->showHideImageOptions($fields, $values, 'each_item', $hidden); + if ($values['each_item/canvas'] != "unlimited") { + $fields['each_item/canvas']['side_note'] = $retinaSideNote; + } else { + $fields['each_item/canvas']['side_note'] = ""; + } $fields['each_item/date_format']['hidden'] = $fields['each_item/show_times']['hidden'] = diff --git a/zenario/modules/zenario_content_list/tuix/admin_boxes/plugin_settings.yaml b/zenario/modules/zenario_content_list/tuix/admin_boxes/plugin_settings.yaml index e9264878d..4c8da3693 100644 --- a/zenario/modules/zenario_content_list/tuix/admin_boxes/plugin_settings.yaml +++ b/zenario/modules/zenario_content_list/tuix/admin_boxes/plugin_settings.yaml @@ -447,26 +447,6 @@ plugin_settings: indent: 2 validation: required_if_not_hidden: Please choose a default image. - retina: - indent: 1 - plugin_setting: - name: retina - label: 'Output a retina image' - type: checkbox - value: "" - side_note: | - <% if (zenarioAB.value('canvas') == 'unlimited') { %> - Halve the width & height at which the image is displayed, - so it appears crisp on retina screens. - <% } else { %> - If the source image is large enough - output the resized image at twice its displayed width & height, - so it appear crisp on retina screens. - This will increase the download size. -
- If the source image is not large enough this will have no effect. - <% } %> - enable_microtemplates_in_properties: true canvas: plugin_setting: name: canvas @@ -512,6 +492,16 @@ plugin_settings: style: 'width: 5em;' post_field_html: ' pixels' indent: 2 + retina: + indent: 2 + plugin_setting: + name: retina + label: 'This is a retina image' + type: checkbox + value: "" + side_note: | + Display image at double density. + enable_microtemplates_in_properties: true show_dates: plugin_setting: @@ -613,21 +603,11 @@ plugin_settings: indent: 1 plugin_setting: name: author_retina - label: 'Output a retina image' + label: 'This is a retina image' type: checkbox value: "" side_note: | - <% if (zenarioAB.value('author_canvas') == 'unlimited') { %> - Halve the width & height at which the image is displayed, - so it appears crisp on retina screens. - <% } else { %> - If the source image is large enough - output the resized image at twice its displayed width & height, - so it appear crisp on retina screens. - This will increase the download size. -
- If the source image is not large enough this will have no effect. - <% } %> + Display image at double density. enable_microtemplates_in_properties: true show_times: plugin_setting: diff --git a/zenario/modules/zenario_document_container/frameworks/standard/framework.twig.html b/zenario/modules/zenario_document_container/frameworks/standard/framework.twig.html index f8716e1be..499c90ca8 100644 --- a/zenario/modules/zenario_document_container/frameworks/standard/framework.twig.html +++ b/zenario/modules/zenario_document_container/frameworks/standard/framework.twig.html @@ -1,3 +1,4 @@ +
{% if error == false %} {% if Documents or Download_Archive %} @@ -67,4 +68,5 @@ {% if error == 'no_user' %}
You must be an extranet user to see this plugin
{% endif %} -{% endif %} \ No newline at end of file +{% endif %} +
\ No newline at end of file diff --git a/zenario/modules/zenario_document_container/module_code.php b/zenario/modules/zenario_document_container/module_code.php index ec0e14388..8c876d396 100644 --- a/zenario/modules/zenario_document_container/module_code.php +++ b/zenario/modules/zenario_document_container/module_code.php @@ -131,6 +131,9 @@ private function addToDocuments($document, $isUserDocument = false, $level = 1) $this->getArchiveDownloadLink($document, array_keys($documents)); } + //Folders should always be public. + $document['privacy'] = "public"; + } elseif ($document['type'] == 'file') { $file = ze\row::get('files', ['filename', 'created_datetime', 'size', 'mime_type', 'privacy'], $document['file_id']); $document['Document_Created'] = $file['created_datetime']; diff --git a/zenario/modules/zenario_newsletter/classes/admin_boxes/newsletter.php b/zenario/modules/zenario_newsletter/classes/admin_boxes/newsletter.php index 08db62b2d..4aeaadf9d 100644 --- a/zenario/modules/zenario_newsletter/classes/admin_boxes/newsletter.php +++ b/zenario/modules/zenario_newsletter/classes/admin_boxes/newsletter.php @@ -160,6 +160,7 @@ public function fillAdminBox($path, $settingGroup, &$box, &$fields, &$values) { = '' . zenario_newsletter::getTrackerURL() . 'delete_account.php?t=XXXXXXXXXXXXXXX'; $box['tabs']['unsub_exclude']['fields']['delete_account_text']['post_field_html'] = '
Preview: ' . $values['unsub_exclude/delete_account_text'] . ' ' . zenario_newsletter::getTrackerURL() . 'delete_account.php?t=XXXXXXXXXXXXXXX
'; + } public function formatAdminBox($path, $settingGroup, &$box, &$fields, &$values, $changes) { @@ -309,6 +310,17 @@ public function formatAdminBox($path, $settingGroup, &$box, &$fields, &$values, $box['tabs']['meta_data']['notices']['test_send_sucesses']['message'] = $success; } } + + + $newsletterConsentPolicy = ze::setting('zenario_newsletter__newsletter_consent_policy'); + $values['unsub_exclude/exclude_recipients_with_no_consent'] = ($newsletterConsentPolicy == 'consent_required'); + if (!$newsletterConsentPolicy) { + //If the newsletter consent flag is not set, show a link to the site settings tab + $link= ze\link::absolute() . 'zenario/admin/organizer.php#zenario__administration/panels/site_settings//zenario_newsletter__site_settings_group~.site_settings~tzenario_newsletter__site_settings~k' . urlencode('{"id":"zenario_newsletter__site_settings_group"}'); + $fields['unsub_exclude/exclude_recipients_with_no_consent']['note_below'] = ze\admin::phrase('Select a flag that represents a recipients consent to recieve newsletters here.', ['link' => $link]); + } else { + unset($fields['unsub_exclude/exclude_recipients_with_no_consent']['note_below']); + } } public function validateAdminBox($path, $settingGroup, &$box, &$fields, &$values, $changes, $saving) { @@ -319,7 +331,14 @@ public function validateAdminBox($path, $settingGroup, &$box, &$fields, &$values ZENARIO_NEWSLETTER_PREFIX. 'newsletters', ['newsletter_name' => $values['meta_data/newsletter_name'], 'id' => ['!' => $box['key']['id']]] )) { - $box['tabs']['meta_data']['errors'][] = ze\admin::phrase('Please ensure the Name you give this Newsletter is Unique.'); + $box['tabs']['meta_data']['errors'][] = ze\admin::phrase('Please ensure the name you give this newsletter is unique.'); + } + } + + if (ze\ring::engToBoolean($box['tabs']['unsub_exclude']['edit_mode']['on'] ?? false)) { + //The consent flag must be chosen in the site-settings to proceed + if (!ze::setting('zenario_newsletter__newsletter_consent_policy')) { + $fields['unsub_exclude/exclude_recipients_with_no_consent']['error'] = ze\admin::phrase('You have not yet selected a consent policy for users receiving newsletters'); } } } diff --git a/zenario/modules/zenario_newsletter/classes/admin_boxes/site_settings.php b/zenario/modules/zenario_newsletter/classes/admin_boxes/site_settings.php index a013812ea..37e5aafed 100644 --- a/zenario/modules/zenario_newsletter/classes/admin_boxes/site_settings.php +++ b/zenario/modules/zenario_newsletter/classes/admin_boxes/site_settings.php @@ -33,8 +33,11 @@ class zenario_newsletter__admin_boxes__site_settings extends zenario_newsletter public function fillAdminBox($path, $settingGroup, &$box, &$fields, &$values) { switch($settingGroup) { case 'zenario_newsletter__site_settings_group': - $box['tabs']['zenario_newsletter__site_settings']['fields']['zenario_newsletter__all_newsletters_opt_out']['values'] = - ze\datasetAdm::listCustomFields('users', $flat = false, 'boolean_and_groups_only', $customOnly = true, $useOptGroups = true); + $fields['zenario_newsletter__all_newsletters_opt_out']['values'] = + ze\datasetAdm::listCustomFields('users', $flat = false, 'boolean_and_groups_only', $customOnly = true, $useOptGroups = true, $hideEmptyOptGroupParents = true); + + $fields['zenario_newsletter__newsletter_consent_flag']['values'] = + ze\datasetAdm::listCustomFields('users', $flat = false, 'consent', $customOnly = false, $useOptGroups = true, $hideEmptyOptGroupParents = true); break; } } diff --git a/zenario/modules/zenario_newsletter/module_code.php b/zenario/modules/zenario_newsletter/module_code.php index 74691368f..6a1107010 100644 --- a/zenario/modules/zenario_newsletter/module_code.php +++ b/zenario/modules/zenario_newsletter/module_code.php @@ -114,8 +114,7 @@ protected static function newsletterRecipientsPart($id, $mode, $smartGroupId) { ON ucd.user_id = u.id"; $whereStatement = " - WHERE u.email != ''"; - //AND u.status IN('active', 'contact')"; + WHERE TRUE " . ze\row::whereCol('users', 'u', 'email', '!=', ""); if (!ze\smartGroup::sql($whereStatement, $sql, $smartGroupId)) { return false; @@ -135,23 +134,37 @@ protected static function newsletterRecipientsPart($id, $mode, $smartGroupId) { AND nul_". (int) $sentNewsletterId. ".user_id IS NULL"; } - $cField = false; - if (($cFieldId = ze::setting('zenario_newsletter__all_newsletters_opt_out')) - && ($cField = ze\dataset::fieldDetails($cFieldId))) { + //Exclude users who have opted out of newsletters + $optOutFlag = false; + if (($optOutFlagId = ze::setting('zenario_newsletter__all_newsletters_opt_out')) + && ($optOutFlag = ze\dataset::fieldDetails($optOutFlagId))) { $sql .= " LEFT JOIN ". DB_PREFIX. "users_custom_data AS noo ON noo.user_id = u.id - AND noo.`". ze\escape::sql($cField['db_column']). "` = 1"; + AND noo.`". ze\escape::sql($optOutFlag['db_column']). "` = 1"; + $whereStatement .= " + AND noo.user_id IS NULL"; + } + + //Exclude users who have not given consent to recieve newsletters + $consentFlag = false; + if (ze::setting('zenario_newsletter__newsletter_consent_policy') == 'consent_required' + && ($consentFlagId = ze::setting('zenario_newsletter__newsletter_consent_flag')) + && ($consentFlagId != 'no_consent_required') + && ($consentFlag = ze\dataset::fieldDetails($consentFlagId))) { + + if ($consentFlag['is_system_field']) { + $whereStatement .= " + AND u.`". ze\escape::sql($consentFlag['db_column']). "` = 1"; + } else { + $whereStatement .= " + AND ucd.`" . ze\escape::sql($consentFlag['db_column']) . "` = 1"; + } } $sql .= " ". $whereStatement; - if ($cField) { - $sql .= " - AND noo.user_id IS NULL"; - } - return $sql; } diff --git a/zenario/modules/zenario_newsletter/tuix/admin_boxes/newsletter.yaml b/zenario/modules/zenario_newsletter/tuix/admin_boxes/newsletter.yaml index b5ae327d4..3f1fe9f50 100644 --- a/zenario/modules/zenario_newsletter/tuix/admin_boxes/newsletter.yaml +++ b/zenario/modules/zenario_newsletter/tuix/admin_boxes/newsletter.yaml @@ -184,6 +184,10 @@ zenario_newsletter: value: 1 readonly: true + exclude_recipients_with_no_consent: + label: Exclude recipients without consent to recieve newsletters + type: checkbox + readonly: true unsubscribe_link: label: 'Unsubscribe link:' diff --git a/zenario/modules/zenario_newsletter/tuix/admin_boxes/site_settings.yaml b/zenario/modules/zenario_newsletter/tuix/admin_boxes/site_settings.yaml index 9ed943271..203d5fa74 100644 --- a/zenario/modules/zenario_newsletter/tuix/admin_boxes/site_settings.yaml +++ b/zenario/modules/zenario_newsletter/tuix/admin_boxes/site_settings.yaml @@ -51,7 +51,35 @@ site_settings: empty_value: '-- Select --' validation: required: Please select the flag on the user/contact record that should be set when a recipient clicks an Unsubscribe link. - + + + zenario_newsletter__newsletter_consent_policy: + label: 'Consent policy:' + site_setting: + name: zenario_newsletter__newsletter_consent_policy + type: select + empty_value: '-- Select --' + values: + consent_required: + label: 'Users must consent to receiving newsletters (recommended)' + no_consent_required: + label: 'No consent required' + redraw_onchange: true + validation: + required: Please choose a consent policy for newsletters. + + zenario_newsletter__newsletter_consent_flag: + indent: 1 + visible_if: zenarioAB.value('zenario_newsletter__newsletter_consent_policy') == 'consent_required' + label: 'User consent flag:' + side_note: 'The flag that indicates a user has consented to receive newsletters' + site_setting: + name: zenario_newsletter__newsletter_consent_flag + type: select + empty_value: '-- Select --' + validation: + required_if_not_hidden: Please select the flag on the user/contact record that shows consent to receive newsletters. + zenario_newsletter__enable_opened_emails: label: 'Enable opened-email tracking' side_note: 'Check this option to enable tracking of opened emails.' diff --git a/zenario/modules/zenario_user_forms/module_code.php b/zenario/modules/zenario_user_forms/module_code.php index 6e1835bf5..24e1f36f7 100644 --- a/zenario/modules/zenario_user_forms/module_code.php +++ b/zenario/modules/zenario_user_forms/module_code.php @@ -57,7 +57,7 @@ public function init() { //This plugin must have a form selected if (!$formId) { if (ze\admin::id()) { - $this->data['form_HTML'] = '

' . ze\admin::phrase('You must select a form for this plugin.') . '

'; + $this->data['form_HTML'] = '

' . htmlspecialchars(ze\admin::phrase('You must select a form for this plugin.')) . '

'; } return true; } @@ -73,9 +73,9 @@ public function init() { if (isset($_GET['confirm_email']) && isset($_GET['hash'])) { $user = ze\row::get('users', ['id', 'email_verified'], ['hash' => $_GET['hash']]); if (!$user) { - $this->data['form_HTML'] = '

' . static::fPhrase('We are sorry, but we were unable to find your registration. Please check whether the verification link is correct.', [], $t) . '

'; + $this->data['form_HTML'] = '

' . htmlspecialchars(static::fPhrase('We are sorry, but we were unable to find your registration. Please check whether the verification link is correct.', [], $t)) . '

'; } elseif ($user['email_verified']) { - $this->data['form_HTML'] = '

' . static::fPhrase('This email address has already been verified.', [], $t) . '

'; + $this->data['form_HTML'] = '

' . htmlspecialchars(static::fPhrase('This email address has already been verified.', [], $t)) . '

'; } else { ze\row::update('users', ['email_verified' => 1, 'status' => 'active'], $user['id']); $this->sendWelcomeEmail($user['id']); @@ -115,7 +115,7 @@ public function init() { $user = ze\row::get('users', ['id'], ['email' => $value]); $this->sendVerificationEmail($user['id']); - $this->data['form_HTML'] = '

' . static::fPhrase('Your verification email has been resent. Please be sure to check your spam/bulk mail folder.', [], $t) . '

'; + $this->data['form_HTML'] = '

' . htmlspecialchars(static::fPhrase('Your verification email has been resent. Please be sure to check your spam/bulk mail folder.', [], $t)) . '

'; return true; } } @@ -125,22 +125,22 @@ public function init() { $html .= '
-
' . static::fPhrase('Email:', [], $t) . '
'; +
' . htmlspecialchars(static::fPhrase('Email:', [], $t)) . '
'; if ($error && !$this->form['show_errors_below_fields']) { $html .= ' -
' . static::fPhrase($error, [], $t) . '
'; +
' . htmlspecialchars(static::fPhrase($error, [], $t)) . '
'; } $html .= ' '; if ($error && $this->form['show_errors_below_fields']) { $html .= ' -
' . static::fPhrase($error, [], $t) . '
'; +
' . htmlspecialchars(static::fPhrase($error, [], $t)) . '
'; } $html .= '
'; $html .= '
'; - $html .= ''; + $html .= ''; $html .= '
'; $html .= $this->closeForm(); @@ -162,13 +162,13 @@ public function init() { $privacy = ze\row::get('translation_chains', 'privacy', ['equiv_id' => $equivId, 'type' => $this->cType]); if ($privacy == 'public') { if (ze\admin::id()) { - $this->data['form_HTML'] = '

' . ze\admin::phrase('This form has the "save and complete later" feature enabled and so must be placed on a password-protected page.') . '

'; + $this->data['form_HTML'] = '

' . htmlspecialchars(ze\admin::phrase('This form has the "save and complete later" feature enabled and so must be placed on a password-protected page.')) . '

'; } return true; } if (!$this->userId) { if (ze\admin::id()) { - $this->data['form_HTML'] = '

' . ze\admin::phrase('You must be logged in as an Extranet User to see this Plugin.') . '

'; + $this->data['form_HTML'] = '

' . htmlspecialchars(ze\admin::phrase('You must be logged in as an Extranet User to see this Plugin.')) . '

'; } return true; } @@ -212,7 +212,7 @@ public function init() { //Logged in user duplicate submission check if ($this->userId && $this->form['no_duplicate_submissions']) { if (ze\row::exists(ZENARIO_USER_FORMS_PREFIX . 'user_response', ['user_id' => $this->userId, 'form_id' => $formId])) { - $html = '

' . static::fPhrase($this->form['duplicate_submission_message'], [], $t) . '

'; + $html = '

' . htmlspecialchars(static::fPhrase($this->form['duplicate_submission_message'], [], $t)) . '

'; $html .= $this->getCloseButtonHTML(); $this->cssClass .= ' no_title'; $this->data['form_HTML'] = $html; @@ -437,27 +437,27 @@ protected function getExtranetLinksHTML($links) { $html .= ''; @@ -852,15 +852,15 @@ public static function getFormSummaryHTML($responseId, $formId = false, $data = $html .= '' . $field['description'] . ''; } } else { - $display = ''; + $displayHTML = ''; if (isset($field['value'])) { - $display = static::getFieldDisplayValue($field, $field['value'], true); + $displayHTML = static::getFieldDisplayValue($field, $field['value'], true, $includeDownloadLinks = 'visitor'); } if (isset($field['row']) && !empty($field['firstRepeatBlockField'])) { $rows = count($fields[$field['repeat_start_id']]['rows']); - $html .= '(' . $field['row'] . ' / ' . $rows . ')'; + $html .= '(' . (int)$field['row'] . ' / ' . (int)$rows . ')'; } - $html .= '' . htmlspecialchars($label) . '' . $display . ''; + $html .= '' . htmlspecialchars($label) . '' . $displayHTML . ''; } } } @@ -1245,7 +1245,7 @@ public static function getRepeatFieldId($fieldId, $row) { private function getFormHTML($pageId) { $t = $this->form['translate_text']; $html = ''; - $html .= '
containerId) . '_form_wrapper" class="form_wrapper'; if ($this->inFullScreen) { $html .= ' in_fullscreen'; } @@ -1271,18 +1271,18 @@ private function getFormHTML($pageId) { if ($printButtonPages) { $printButtonPages = explode(',', $printButtonPages); if (in_array($this->pages[$pageId]['ord'], $printButtonPages)) { - $topButtonsHTML .= ''; + $topButtonsHTML .= ''; } } } //Fullscreen if ($this->setting('show_fullscreen_button')) { - $topButtonsHTML .= '
containerId) . '_fullscreen" class="fullscreen_button"'; if ($this->inFullScreen) { $topButtonsHTML .= ' style="display:none;"'; } - $topButtonsHTML .= '>' . static::fPhrase('Fullscreen', [], $t) . '
'; + $topButtonsHTML .= '>' . htmlspecialchars(static::fPhrase('Fullscreen', [], $t)) . '
'; } } if ($topButtonsHTML) { @@ -1321,7 +1321,7 @@ private function getFormHTML($pageId) { } $hasPageVisibleOnSwitcher = true; - $switcherHTML .= '
  • getVisibleConditionDataValuesHTML($tPage, $pageId); $extraClasses .= ' visible_on_condition'; } - $switcherHTML .= 'class="step step_' . ($step++) . ' ' . $extraClasses . '">' . $tPage['name'] . '
  • '; + $switcherHTML .= 'class="step step_' . (int)($step++) . ' ' . htmlspecialchars($extraClasses) . '">' . htmlspecialchars($tPage['name']) . ''; } $switcherHTML .= ''; if ($hasPageVisibleOnSwitcher) { @@ -1362,21 +1362,21 @@ private function getFormHTML($pageId) { //Global errors and messages if (isset($this->errors['global_top'])) { - $html .= '
    ' . static::fPhrase($this->errors['global_top'], [], $t) . '
    '; + $html .= '
    ' . htmlspecialchars(static::fPhrase($this->errors['global_top'], [], $t)) . '
    '; } elseif (isset($this->messages['global_top'])) { - $html .= '
    ' . static::fPhrase($this->messages['global_top'], [], $t) . '
    '; + $html .= '
    ' . htmlspecialchars(static::fPhrase($this->messages['global_top'], [], $t)) . '
    '; } - $html .= '
    '; + $html .= '
    '; $html .= $this->openForm($onSubmit = '', $extraAttributes = 'enctype="multipart/form-data"', $action = false, $scrollToTopOfSlot = true); //Hidden input for SIMPLE_ACCESS cookie rediection if ($this->form['simple_access_cookie_override_redirect'] && isset($_REQUEST['rci'])) { - $html .= ''; + $html .= ''; } if ($this->form['partial_completion_get_request']) { $html .= ''; } - $html .= ''; + $html .= ''; //Hidden input to tell whether the form has been submitted $html .= ''; //Hidden input to tell whether the form is in fullscreen or not @@ -1403,7 +1403,7 @@ protected function getFieldsHTML($pageId, $readonly) { $t = $this->form['translate_text']; $isMultiPageForm = count($this->pages) > 1; if ($isMultiPageForm) { - $html .= '
    '; + $html .= '
    '; } $onLastPage = ($pageId == end($this->pages)['id']); @@ -1420,7 +1420,7 @@ protected function getFieldsHTML($pageId, $readonly) { $repeatFieldWrapDivOpen = false; if ($this->form['enable_summary_page'] && $onLastPage) { - $html .= '

    ' . static::fPhrase("You're nearly done, please check your details before submitting.", [], $t) . '

    '; + $html .= '

    ' . htmlspecialchars(static::fPhrase("You're nearly done, please check your details before submitting.", [], $t)) . '

    '; $data = []; foreach ($this->fields as $fieldId => $field) { $data[$fieldId] = $this->getFieldCurrentValue($fieldId); @@ -1434,12 +1434,12 @@ protected function getFieldsHTML($pageId, $readonly) { if ($this->form['enable_summary_page_required_checkbox']) { if (isset($this->errors['summary_required_checkbox']) && !$this->form['show_errors_below_fields']) { - $html .= '
    ' . $this->errors['summary_required_checkbox'] . '
    '; + $html .= '
    ' . htmlspecialchars($this->errors['summary_required_checkbox']) . '
    '; } $html .= '
    - - + +
    '; if (isset($this->errors['summary_required_checkbox']) && $this->form['show_errors_below_fields']) { $html .= '
    ' . $this->errors['summary_required_checkbox'] . '
    '; @@ -1451,7 +1451,7 @@ protected function getFieldsHTML($pageId, $readonly) { if ($field['type'] == 'repeat_start') { $html .= $this->getWrapperDivHTML($field, $wrapDivOpen, $currentDivWrapClass); //Repeat start div - $html .= '
    containerId) . '_repeat_block_' . (int)$fieldId . '" data-id="' . (int)$fieldId . '" class="repeat_block repeat_block_' . (int)$fieldId; if ($field['css_classes']) { $html .= ' ' . htmlspecialchars($field['css_classes']); } @@ -1466,11 +1466,11 @@ protected function getFieldsHTML($pageId, $readonly) { $html .= $this->getVisibleConditionDataValuesHTML($field, $pageId); } $html .= '>'; - $html .= ''; + $html .= ''; //Repeat start title if ($field['label']) { - $html .= '
    ' . static::fPhrase($field['label'], [], $t) . '
    '; + $html .= '
    ' . htmlspecialchars(static::fPhrase($field['label'], [], $t)) . '
    '; } $html .= '
    '; @@ -1507,7 +1507,7 @@ protected function getFieldsHTML($pageId, $readonly) { } $html .= '
    '; if (!empty($field['repeatBlockDeleteButton'])) { - $html .= '
    ' . static::fPhrase('Delete', [], $t) . '
    '; + $html .= '
    ' . static::fPhrase('Delete', [], $t) . '
    '; } $html .= '
    '; } @@ -1533,7 +1533,7 @@ protected function getFieldsHTML($pageId, $readonly) { $html .= '
    '; if (isset($this->errors['global_bottom'])) { - $html .= '
    ' . static::fPhrase($this->errors['global_bottom'], [], $t) . '
    '; + $html .= '
    ' . htmlspecialchars(static::fPhrase($this->errors['global_bottom'], [], $t)) . '
    '; } $html .= '
    '; @@ -1545,7 +1545,7 @@ protected function getFieldsHTML($pageId, $readonly) { //Previous page button if ($isMultiPageForm && $this->pages[$pageId]['ord'] > 1) { - $html .= ''; + $html .= ''; } $button = $this->getCustomButtons($pageId, $onLastPage, 'center'); @@ -1555,11 +1555,11 @@ protected function getFieldsHTML($pageId, $readonly) { //Next page button if ($isMultiPageForm && !$onLastPage) { - $html .= ''; + $html .= ''; } //Final submit button if ($this->showSubmitButton() && $onLastPage) { - $html .= ''; + $html .= ''; } $button = $this->getCustomButtons($pageId, $onLastPage, 'last'); @@ -1574,7 +1574,7 @@ protected function getFieldsHTML($pageId, $readonly) { $html .= '
    '; if ($isMultiPageForm) { - $html .= ''; + $html .= ''; $html .= ''; } return $html; @@ -1584,7 +1584,7 @@ private function getPartialSaveButtonHTML() { $html = ''; if ($this->form['allow_partial_completion'] && ($this->form['partial_completion_mode'] == 'button' || $this->form['partial_completion_mode'] == 'auto_and_button')) { $t = $this->form['translate_text']; - $html .= '
    '; + $html .= '
    '; } return $html; } @@ -1619,12 +1619,12 @@ private function getHoneypotHTML() { $t = $this->form['translate_text']; $html = ''; return $html; } @@ -1675,8 +1675,8 @@ private function getFieldHTML($fieldId, $pageId, $readonly) { if ($hidden) { $html .= ' autocomplete="hidden-field"'; } - $html .= ' name="' . $fieldName . '" id="' . $fieldElementId . '"/>'; - $html .= ''; + $html .= ' name="' . htmlspecialchars($fieldName) . '" id="' . htmlspecialchars($fieldElementId) . '"/>'; + $html .= ''; break; case 'restatement': @@ -1708,8 +1708,8 @@ private function getFieldHTML($fieldId, $pageId, $readonly) { } } - $html .= '