| @@ -1,95 +1,199 @@ | ||
| 1 | 1 | <?php |
| 2 | +defined('ABSPATH') || die('Restricted Access'); | |
| 2 | 3 | |
| 3 | -function acym_modal($button, $data, $id = null, $attributesModal = '', $attributesButton = '', $isButton = true, $isLarge = true, $classesModal = ''): string | |
| 4 | -{ | |
| 4 | +/** | |
| 5 | + * Add the attribute data-open (should be the ID of the modal) to any element to make it open the modal. | |
| 6 | + */ | |
| 7 | +function acym_modal( | |
| 8 | + string $button, | |
| 9 | + string $data, | |
| 10 | + ?string $id = null, | |
| 11 | + array $attributesModal = [], | |
| 12 | + array $attributesButton = [], | |
| 13 | + bool $isButton = true, | |
| 14 | + bool $isLarge = true, | |
| 15 | + string $classesModal = '' | |
| 16 | +): void { | |
| 5 | 17 | if (empty($id)) { |
| 6 | - $id = 'acymodal_'.rand(1000, 9000); | |
| 18 | + $id = 'acymodal_'.acym_rand(1000, 9000); | |
| 7 | 19 | } |
| 8 | 20 | |
| 9 | - $buttonParams = ''; | |
| 10 | - if (is_array($attributesButton)) { | |
| 21 | + //TODO test with data-iframe param since it's a partial URL | |
| 22 | + $attributesButton['data-open'] = $id; | |
| 23 | + | |
| 24 | + $attributesModal['class'] = 'reveal '.$classesModal; | |
| 25 | + $attributesModal['id'] = $id; | |
| 26 | + $attributesModal['data-reveal'] = ''; | |
| 27 | + if ($isLarge) { | |
| 28 | + $attributesModal['data-reveal-larger'] = ''; | |
| 29 | + } | |
| 30 | + | |
| 31 | + if ($isButton) { | |
| 32 | + echo '<button type="button" '; | |
| 11 | 33 | foreach ($attributesButton as $oneAttribute => $oneValue) { |
| 12 | - $buttonParams .= ' '.$oneAttribute.'="'.acym_escape($oneValue).'"'; | |
| 34 | + if (is_array($oneValue) || is_object($oneValue)) { | |
| 35 | + $oneValue = json_encode($oneValue); | |
| 36 | + } elseif ($oneValue === true) { | |
| 37 | + $oneValue = $oneAttribute; | |
| 38 | + } | |
| 39 | + | |
| 40 | + echo ' '.esc_attr($oneAttribute).'="'.esc_attr($oneValue).'"'; | |
| 13 | 41 | } |
| 14 | - } else { | |
| 15 | - $buttonParams = $attributesButton; | |
| 42 | + echo '>'; | |
| 16 | 43 | } |
| 44 | + echo wp_kses( | |
| 45 | + $button, | |
| 46 | + [ | |
| 47 | + 'i' => [ | |
| 48 | + 'class' => true, | |
| 49 | + 'data-acy-elementid' => true, | |
| 50 | + 'data-open' => true, | |
| 51 | + 'data-ajax' => true, | |
| 52 | + 'data-iframe' => true, | |
| 53 | + 'data-iframe-class' => true, | |
| 54 | + 'id' => true, | |
| 55 | + 'acym-data-domain' => true, | |
| 56 | + ], | |
| 57 | + 'input' => [ | |
| 58 | + 'data-open' => true, | |
| 59 | + 'class' => true, | |
| 60 | + 'type' => true, | |
| 61 | + 'value' => true, | |
| 62 | + 'readonly' => true, | |
| 63 | + 'onchange' => true, | |
| 64 | + ], | |
| 65 | + 'span' => [ | |
| 66 | + 'class' => true, | |
| 67 | + ], | |
| 68 | + 'div' => [ | |
| 69 | + 'class' => true, | |
| 70 | + 'id' => true, | |
| 71 | + 'data-iframe' => true, | |
| 72 | + 'data-iframe-class' => true, | |
| 73 | + 'data-open' => true, | |
| 74 | + ], | |
| 75 | + ] | |
| 76 | + ); | |
| 77 | + if ($isButton) { | |
| 78 | + echo '</button>'; | |
| 79 | + } | |
| 17 | 80 | |
| 18 | - $modal = $isButton ? '<button type="button" data-open="'.$id.'" '.$buttonParams.'>'.$button.'</button>' : $button; | |
| 19 | - $modal .= '<div class="reveal '.$classesModal.'" '.($isLarge ? 'data-reveal-larger' : '').' id="'.$id.'" '.$attributesModal.' data-reveal>'; | |
| 20 | - $modal .= $data; | |
| 21 | - $modal .= '<button class="close-button" data-close aria-label="Close reveal" type="button">'; | |
| 22 | - $modal .= '<span aria-hidden="true">×</span>'; | |
| 23 | - $modal .= '</button></div>'; | |
| 81 | + echo '<div '; | |
| 82 | + foreach ($attributesModal as $oneAttribute => $oneValue) { | |
| 83 | + if (is_array($oneValue) || is_object($oneValue)) { | |
| 84 | + $oneValue = json_encode($oneValue); | |
| 85 | + } elseif ($oneValue === true) { | |
| 86 | + $oneValue = $oneAttribute; | |
| 87 | + } | |
| 24 | 88 | |
| 25 | - return $modal; | |
| 89 | + echo ' '.esc_attr($oneAttribute).'="'.esc_attr($oneValue).'"'; | |
| 90 | + } | |
| 91 | + echo '>'; | |
| 92 | + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped by the caller, too many cases. | |
| 93 | + echo $data; | |
| 94 | + echo '<button class="close-button" data-close aria-label="Close reveal" type="button">'; | |
| 95 | + echo '<span aria-hidden="true">×</span>'; | |
| 96 | + echo '</button></div>'; | |
| 26 | 97 | } |
| 27 | 98 | |
| 28 | -function acym_modal_include($button, $file, $id, $data, $attributes = '', $classModal = '', $containerAttributes = '') | |
| 29 | -{ | |
| 30 | - return acym_modalInclude($button, $file, $id, $data, $attributes = '', $classModal = '', $containerAttributes = ''); | |
| 31 | -} | |
| 32 | - | |
| 33 | -function acym_modalInclude($button, $file, $id, $data, $attributes = '', $classModal = '', $containerAttributes = '') | |
| 34 | -{ | |
| 99 | +function acym_modalInclude( | |
| 100 | + string $button, | |
| 101 | + string $file, | |
| 102 | + string $id, | |
| 103 | + array $data, | |
| 104 | + string $classModal = '', | |
| 105 | + array $containerAttributes = [] | |
| 106 | +): void { | |
| 35 | 107 | if (empty($id)) { |
| 36 | - $id = 'acymodal_'.rand(1000, 9000); | |
| 108 | + $id = 'acymodal_'.acym_rand(1000, 9000); | |
| 37 | 109 | } |
| 38 | 110 | |
| 111 | + // Both can be used in the included file | |
| 39 | 112 | $dataModal = $data; |
| 40 | 113 | |
| 41 | - $modal = '<div data-open="'.acym_escape($id).'" '.$containerAttributes.'>'.$button; | |
| 42 | - $modal .= '<div class="reveal '.$classModal.'" id="'.acym_escape($id).'" '.$attributes.' data-reveal>'; | |
| 43 | - ob_start(); | |
| 114 | + $containerAttributes['data-open'] = $id; | |
| 115 | + echo '<div '; | |
| 116 | + foreach ($containerAttributes as $oneAttribute => $oneValue) { | |
| 117 | + if (is_array($oneValue) || is_object($oneValue)) { | |
| 118 | + $oneValue = json_encode($oneValue); | |
| 119 | + } elseif ($oneValue === true) { | |
| 120 | + $oneValue = $oneAttribute; | |
| 121 | + } | |
| 122 | + | |
| 123 | + echo ' '.esc_attr($oneAttribute).'="'.esc_attr($oneValue).'"'; | |
| 124 | + } | |
| 125 | + echo '>'; | |
| 126 | + echo wp_kses( | |
| 127 | + $button, | |
| 128 | + [ | |
| 129 | + 'button' => [ | |
| 130 | + 'type' => true, | |
| 131 | + 'id' => true, | |
| 132 | + 'class' => true, | |
| 133 | + ], | |
| 134 | + 'span' => [ | |
| 135 | + 'class' => true, | |
| 136 | + ], | |
| 137 | + 'b' => [], | |
| 138 | + ] | |
| 139 | + ); | |
| 140 | + echo '<div class="reveal '.esc_attr($classModal).'" id="'.esc_attr($id).'" data-reveal>'; | |
| 44 | 141 | include $file; |
| 45 | - $modal .= ob_get_clean(); | |
| 46 | - $modal .= '<button type="button" class="close-button" data-close aria-label="Close reveal">'; | |
| 47 | - $modal .= '<span aria-hidden="true">×</span>'; | |
| 48 | - $modal .= '</button></div></div>'; | |
| 49 | - | |
| 50 | - return $modal; | |
| 142 | + echo '<button type="button" class="close-button" data-close aria-label="Close reveal">'; | |
| 143 | + echo '<span aria-hidden="true">×</span>'; | |
| 144 | + echo '</button></div></div>'; | |
| 51 | 145 | } |
| 52 | 146 | |
| 53 | -function acym_modalPaginationLists($inputEventId = '', $checkedLists = '[]', $needDisplaySubscribers = false, $attributesModal = '') | |
| 54 | -{ | |
| 55 | - $searchField = acym_filterSearch('', 'modal_search_lists'); | |
| 147 | +function acym_modalPaginationLists( | |
| 148 | + string $inputEventId, | |
| 149 | + string $checkedLists = '[]', | |
| 150 | + bool $needDisplaySubscribers = false | |
| 151 | +): void { | |
| 152 | + ?> | |
| 153 | + <input type="hidden" id="<?php echo esc_attr($inputEventId); ?>"> | |
| 56 | 154 | |
| 57 | - $data = ''; | |
| 58 | - if (!empty($inputEventId)) { | |
| 59 | - $data .= '<input type="hidden" id="'.$inputEventId.'">'; | |
| 60 | - } | |
| 61 | - if ($needDisplaySubscribers) { | |
| 62 | - $data .= '<input type="hidden" id="modal__pagination__need__display__sub">'; | |
| 63 | - } | |
| 155 | + <?php if ($needDisplaySubscribers) { ?> | |
| 156 | + <input type="hidden" id="modal__pagination__need__display__sub"> | |
| 157 | + <?php } ?> | |
| 64 | 158 | |
| 65 | - $data .= '<div class="cell grid-x" '.$attributesModal.'> | |
| 66 | - <input type="hidden" name="show_selected" value="false" id="modal__pagination__show-information"> | |
| 67 | - <input type="hidden" id="modal__pagination__search__lists"> | |
| 68 | - <input type="hidden" name="lists_selected" id="acym__modal__lists-selected" value="'.acym_escape($checkedLists).'"> | |
| 69 | - <div class="cell grid-x"> | |
| 70 | - <h4 class="cell text-center acym__title acym__title__secondary">'.acym_translation('ACYM_CHOOSE_LISTS').'</h4> | |
| 71 | - </div> | |
| 72 | - <div class="cell grid-x modal__pagination__search"> | |
| 73 | - '.$searchField.' | |
| 74 | - </div> | |
| 75 | - <div class="cell text-center padding-top-1" id="modal__pagination__search__spinner" style="display: none"> | |
| 76 | - <i class="acymicon-circle-o-notch acymicon-spin"></i> | |
| 77 | - </div> | |
| 78 | - <div class="cell medium-6 modal__pagination__show"> | |
| 79 | - <a href="#" class="acym__color__blue modal__pagination__show-selected modal__pagination__show-button selected">'.acym_translation('ACYM_SHOW_SELECTED_LISTS').'</a> | |
| 80 | - <a href="#" class="acym__color__blue modal__pagination__show-all modal__pagination__show-button">'.acym_translation('ACYM_SHOW_ALL_LISTS').'</a> | |
| 81 | - </div> | |
| 82 | - <div class="cell grid-x modal__pagination__listing__lists"> | |
| 83 | - <div class="cell modal__pagination__listing__lists__in-form"></div> | |
| 84 | - </div> | |
| 85 | - </div>'; | |
| 86 | - | |
| 87 | - return $data; | |
| 159 | + <div class="cell grid-x" style="display: none;" id="acym__popup__plugin__subscription__lists__modal"> | |
| 160 | + <input type="hidden" name="show_selected" value="false" id="modal__pagination__show-information"> | |
| 161 | + <input type="hidden" id="modal__pagination__search__lists"> | |
| 162 | + <input type="hidden" name="lists_selected" id="acym__modal__lists-selected" value="<?php echo esc_attr($checkedLists); ?>"> | |
| 163 | + <div class="cell grid-x"> | |
| 164 | + <h4 class="cell text-center acym__title acym__title__secondary"> | |
| 165 | + <?php echo esc_html(acym_translation('ACYM_CHOOSE_LISTS')); ?> | |
| 166 | + </h4> | |
| 167 | + </div> | |
| 168 | + <div class="cell grid-x modal__pagination__search"> | |
| 169 | + <?php acym_filterSearch('', 'modal_search_lists'); ?> | |
| 170 | + </div> | |
| 171 | + <div class="cell text-center padding-top-1" id="modal__pagination__search__spinner" style="display: none"> | |
| 172 | + <i class="acymicon-circle-o-notch acymicon-spin"></i> | |
| 173 | + </div> | |
| 174 | + <div class="cell medium-6 modal__pagination__show"> | |
| 175 | + <a href="#" class="acym__color__blue modal__pagination__show-selected modal__pagination__show-button selected"> | |
| 176 | + <?php echo esc_html(acym_translation('ACYM_SHOW_SELECTED_LISTS')); ?> | |
| 177 | + </a> | |
| 178 | + <a href="#" class="acym__color__blue modal__pagination__show-all modal__pagination__show-button"> | |
| 179 | + <?php echo esc_html(acym_translation('ACYM_SHOW_ALL_LISTS')); ?> | |
| 180 | + </a> | |
| 181 | + </div> | |
| 182 | + <div class="cell grid-x modal__pagination__listing__lists"> | |
| 183 | + <div class="cell modal__pagination__listing__lists__in-form"></div> | |
| 184 | + </div> | |
| 185 | + </div> | |
| 186 | + <?php | |
| 88 | 187 | } |
| 89 | 188 | |
| 90 | -function acym_frontModal($iframeSrc, $buttonText, $isButton, $identifier = null, $iframeClass = null, $additionalContent = '') | |
| 91 | -{ | |
| 189 | +function acym_frontModal( | |
| 190 | + string $iframeSrc, | |
| 191 | + string $buttonText, | |
| 192 | + bool $isButton, | |
| 193 | + ?string $identifier = null, | |
| 194 | + ?string $iframeClass = null | |
| 195 | +): string { | |
| 92 | 196 | static $loaded = false; |
| 93 | 197 | if (empty($loaded)) { |
| 94 | 198 | $loaded = true; |
| 95 | 199 | acym_addStyle(false, ACYM_CSS.'modal.min.css?v='.filemtime(ACYM_MEDIA.'css'.DS.'modal.min.css')); |
| @@ -96,9 +200,9 @@ | ||
| 96 | 200 | acym_addScript(false, ACYM_JS.'modal.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'modal.min.js')); |
| 97 | 201 | } |
| 98 | 202 | |
| 99 | 203 | if (empty($identifier)) { |
| 100 | - $identifier = 'identifier_'.rand(1000, 9000); | |
| 204 | + $identifier = 'identifier_'.acym_rand(1000, 9000); | |
| 101 | 205 | } |
| 102 | 206 | |
| 103 | 207 | if (empty($iframeClass)) { |
| 104 | 208 | $iframeClass = 'acym__modal__iframe'; |
| @@ -105,18 +209,16 @@ | ||
| 105 | 209 | } |
| 106 | 210 | |
| 107 | 211 | ob_start(); |
| 108 | 212 | ?> |
| 109 | - <a class="<?php echo $isButton ? 'btn ' : ''; ?>acym__modal__handle" data-acym-modal="<?php echo acym_escape($identifier); ?>" href="#"> | |
| 110 | - <?php echo acym_translation($buttonText); ?> | |
| 213 | + <a class="<?php echo $isButton ? 'btn ' : ''; ?>acym__modal__handle" data-acym-modal="<?php echo esc_attr($identifier); ?>" href="#"> | |
| 214 | + <?php echo esc_html(acym_translation($buttonText)); ?> | |
| 111 | 215 | </a> |
| 112 | - <div class="acym__modal" id="acym__modal__<?php echo $identifier; ?>" style="display: none;"> | |
| 216 | + <div class="acym__modal" id="acym__modal__<?php echo esc_attr($identifier); ?>" style="display: none;"> | |
| 113 | 217 | <div class="acym__modal__content"> |
| 114 | 218 | <div class="acym__modal__close"><span>×</span></div> |
| 115 | - <?php echo $additionalContent; ?> | |
| 116 | - <iframe class="<?php echo $iframeClass; ?>" src="<?php echo $iframeSrc; ?>"></iframe> | |
| 219 | + <iframe class="<?php echo esc_attr($iframeClass); ?>" src="<?php echo esc_url($iframeSrc); ?>"></iframe> | |
| 117 | 220 | </div> |
| 118 | 221 | </div> |
| 119 | 222 | <?php |
| 120 | - | |
| 121 | 223 | return ob_get_clean(); |
| 122 | 224 | } |