| @@ -1,9 +1,14 @@ | ||
| 1 | 1 | <?php |
| 2 | +defined('ABSPATH') || die('Restricted Access'); | |
| 2 | 3 | |
| 3 | 4 | use AcyMailing\Classes\ConfigurationClass; |
| 5 | +use AcyMailing\Helpers\SecurityHelper; | |
| 4 | 6 | |
| 5 | -function acydump($arg, $ajax = false, array $options = []) | |
| 7 | +/** | |
| 8 | + * @param ?mixed $arg | |
| 9 | + */ | |
| 10 | +function acym_dump($arg, bool $ajax = false, array $options = []): void | |
| 6 | 11 | { |
| 7 | 12 | $indent = $options['indent'] ?? true; |
| 8 | 13 | $htmlentities = $options['htmlentities'] ?? true; |
| 9 | 14 | |
| @@ -10,23 +15,29 @@ | ||
| 10 | 15 | ob_start(); |
| 11 | 16 | if (is_object($arg) && isset($arg->config)) { |
| 12 | 17 | $safeArg = clone $arg; |
| 13 | 18 | unset($safeArg->config); |
| 19 | + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_var_dump -- For debug during support only. | |
| 14 | 20 | var_dump($safeArg); |
| 15 | 21 | } else { |
| 22 | + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_var_dump -- For debug during support only. | |
| 16 | 23 | var_dump($arg); |
| 17 | 24 | } |
| 18 | 25 | $result = ob_get_clean(); |
| 19 | 26 | |
| 20 | 27 | if ($ajax) { |
| 28 | + $logsPath = ACYM_ROOT.ACYM_LOGS_FOLDER.'debug.log'; | |
| 29 | + acym_createDir(dirname($logsPath), true, true); | |
| 30 | + | |
| 21 | 31 | if (($options['clear_file'] ?? false) === true) { |
| 22 | - file_put_contents(ACYM_ROOT.'acydebug.txt', ''); | |
| 32 | + file_put_contents($logsPath, ''); | |
| 23 | 33 | } |
| 24 | 34 | |
| 25 | - file_put_contents(ACYM_ROOT.'acydebug.txt', $result, FILE_APPEND); | |
| 35 | + file_put_contents($logsPath, $result, FILE_APPEND); | |
| 26 | 36 | } else { |
| 27 | 37 | $style = $indent ? 'margin-left: 220px;' : ''; |
| 28 | - echo '<pre style="'.$style.'">'; | |
| 38 | + echo '<pre style="'.esc_attr($style).'">'; | |
| 39 | + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- For debug during support only. | |
| 29 | 40 | echo $htmlentities ? htmlentities($result) : $result; |
| 30 | 41 | echo '</pre>'; |
| 31 | 42 | } |
| 32 | 43 | } |
| @@ -32,8 +43,9 @@ | ||
| 32 | 43 | } |
| 33 | 44 | |
| 34 | 45 | function acym_debug(bool $file = false, bool $indent = true) |
| 35 | 46 | { |
| 47 | + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace -- Debug for support tickets. | |
| 36 | 48 | $debug = debug_backtrace(); |
| 37 | 49 | $takenPath = []; |
| 38 | 50 | foreach ($debug as $step) { |
| 39 | 51 | if (empty($step['file']) || empty($step['line'])) continue; |
| @@ -38,9 +50,9 @@ | ||
| 38 | 50 | foreach ($debug as $step) { |
| 39 | 51 | if (empty($step['file']) || empty($step['line'])) continue; |
| 40 | 52 | $takenPath[] = $step['file'].' => '.$step['line']; |
| 41 | 53 | } |
| 42 | - acydump(implode("\n", $takenPath), $file, ['indent' => $indent]); | |
| 54 | + acym_dump(implode("\n", $takenPath), $file, ['indent' => $indent]); | |
| 43 | 55 | } |
| 44 | 56 | |
| 45 | 57 | function acym_config(bool $reload = false): ConfigurationClass |
| 46 | 58 | { |
| @@ -52,9 +64,14 @@ | ||
| 52 | 64 | |
| 53 | 65 | return $configClass; |
| 54 | 66 | } |
| 55 | 67 | |
| 56 | -function acym_display($messages, $type = 'success', $close = true) | |
| 68 | +/** | |
| 69 | + * @param mixed $messages The messages displayed, either a string or an array or strings | |
| 70 | + * @param string $type Type of the message: success, error, warning, info | |
| 71 | + * @param bool $close Allow or not to close the message zone | |
| 72 | + */ | |
| 73 | +function acym_display($messages, string $type = 'success', bool $close = true): void | |
| 57 | 74 | { |
| 58 | 75 | if (empty($messages)) return; |
| 59 | 76 | if (!is_array($messages)) $messages = [$messages]; |
| 60 | 77 | $config = acym_config(); |
| @@ -60,36 +77,43 @@ | ||
| 60 | 77 | $config = acym_config(); |
| 61 | 78 | $remindme = json_decode($config->get('remindme', '[]'), true); |
| 62 | 79 | foreach ($messages as $id => $message) { |
| 63 | 80 | if (strpos($message, 'acym__do__not__remindme') !== false) { |
| 64 | - preg_match('/title="(.*)"/Ui', $message, $matches); | |
| 65 | - if (in_array($matches[1], $remindme)) continue; | |
| 81 | + if (preg_match('/title="(.*)"/Ui', $message, $matches) && in_array($matches[1], $remindme)) { | |
| 82 | + continue; | |
| 83 | + } | |
| 66 | 84 | } |
| 67 | 85 | |
| 68 | - echo '<div class="acym__message grid-x acym__message__'.$type.'">'; | |
| 86 | + echo '<div class="acym__message grid-x acym__message__'.esc_attr($type).'">'; | |
| 69 | 87 | |
| 70 | 88 | if (is_array($message)) $message = implode('</div><div>', $message); |
| 71 | 89 | |
| 72 | - echo '<div class="cell auto"><div>'.$message.'</div></div>'; | |
| 90 | + echo '<div class="cell auto"><div>'.wp_kses($message, SecurityHelper::ALLOWED_HTML_MESSAGE).'</div></div>'; | |
| 73 | 91 | |
| 74 | 92 | if ($close && strpos($message, 'acym__do__not__remindme') === false) { |
| 75 | - echo '<i data-id="'.acym_escape($id).'" class="cell shrink acym__message__close acymicon-close"></i>'; | |
| 93 | + echo '<i data-id="'.esc_attr($id).'" class="cell shrink acym__message__close acymicon-close"></i>'; | |
| 76 | 94 | } |
| 77 | 95 | echo '</div>'; |
| 78 | 96 | } |
| 79 | 97 | } |
| 80 | 98 | |
| 81 | -function acym_increasePerf() | |
| 99 | +function acym_increasePerf(): int | |
| 82 | 100 | { |
| 83 | - $maxExecutionTime = ini_get('max_execution_time'); | |
| 84 | - if ($maxExecutionTime < 600) { | |
| 85 | - @ini_set('max_execution_time', 600); | |
| 101 | + // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- This is for big regex, the default value is 100 000. | |
| 102 | + @ini_set('pcre.backtrack_limit', 1000000); | |
| 103 | + | |
| 104 | + // Increase the max exec time to be able to handle long processes such as the send process | |
| 105 | + $maxExecutionTime = (int)ini_get('max_execution_time'); | |
| 106 | + | |
| 107 | + if (empty($maxExecutionTime) || $maxExecutionTime < 600) { | |
| 108 | + // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- Needed for long processes like email sending. | |
| 109 | + return set_time_limit(600) ? 600 : $maxExecutionTime; | |
| 86 | 110 | } |
| 87 | 111 | |
| 88 | - @ini_set('pcre.backtrack_limit', 1000000); | |
| 112 | + return $maxExecutionTime; | |
| 89 | 113 | } |
| 90 | 114 | |
| 91 | -function acym_session() | |
| 115 | +function acym_session(): void | |
| 92 | 116 | { |
| 93 | 117 | if (empty(session_id()) || session_status() !== PHP_SESSION_ACTIVE) { |
| 94 | 118 | @session_start(); |
| 95 | 119 | } |
| @@ -107,25 +131,27 @@ | ||
| 107 | 131 | |
| 108 | 132 | return intval($oneResult); |
| 109 | 133 | } |
| 110 | 134 | |
| 111 | -function acym_header($header, $replace = true) | |
| 135 | +function acym_header(string $header, bool $replace = true): void | |
| 112 | 136 | { |
| 113 | - if (headers_sent()) return; | |
| 137 | + if (headers_sent()) { | |
| 138 | + return; | |
| 139 | + } | |
| 140 | + | |
| 114 | 141 | header($header, $replace); |
| 115 | 142 | } |
| 116 | 143 | |
| 117 | -function acym_getSocialMedias() | |
| 144 | +function acym_getSocialMedias(): array | |
| 118 | 145 | { |
| 119 | 146 | return json_decode(ACYM_SOCIAL_MEDIA, true); |
| 120 | 147 | } |
| 121 | 148 | |
| 122 | -function acym_isAcyCheckerInstalled() | |
| 149 | +function acym_isAcyCheckerInstalled(): bool | |
| 123 | 150 | { |
| 124 | 151 | $installed = ACYM_CMS === 'joomla' && acym_isExtensionActive('com_acychecker'); |
| 125 | - $installed = $installed || (ACYM_CMS === 'wordpress' && acym_isExtensionActive('acychecker/acychecker.php')); | |
| 126 | 152 | |
| 127 | - return $installed; | |
| 153 | + return $installed || (ACYM_CMS === 'wordpress' && acym_isExtensionActive('acychecker/acychecker.php')); | |
| 128 | 154 | } |
| 129 | 155 | |
| 130 | 156 | function acym_getErrorLogFilename(string $prefix = ''): string |
| 131 | 157 | { |
| @@ -155,9 +181,9 @@ | ||
| 155 | 181 | FILE_APPEND |
| 156 | 182 | ); |
| 157 | 183 | } |
| 158 | 184 | |
| 159 | -function acym_isLogFileErrorExist($prefix = ''): bool | |
| 185 | +function acym_isLogFileErrorExist(string $prefix = ''): bool | |
| 160 | 186 | { |
| 161 | 187 | $reportPath = acym_getLogPath(acym_getErrorLogFilename($prefix)); |
| 162 | 188 | |
| 163 | 189 | return file_exists($reportPath); |
| @@ -170,9 +196,9 @@ | ||
| 170 | 196 | |
| 171 | 197 | return empty($decodedData) ? [] : $decodedData; |
| 172 | 198 | } |
| 173 | 199 | |
| 174 | -function displayFreeTrialMessage() | |
| 200 | +function acym_displayFreeTrialMessage(): void | |
| 175 | 201 | { |
| 176 | 202 | if (!acym_isAdmin()) { |
| 177 | 203 | return; |
| 178 | 204 | } |
| @@ -201,9 +227,8 @@ | ||
| 201 | 227 | } |
| 202 | 228 | acym_enqueueMessage('<div class="cell grid-x acym_vcenter">'.$message.$buttonFullAccess.'</div>', $type, false); |
| 203 | 229 | } |
| 204 | 230 | |
| 205 | - | |
| 206 | 231 | function acym_removeDashboardNotification(string $name): void |
| 207 | 232 | { |
| 208 | 233 | $config = acym_config(); |
| 209 | 234 | $existingNotifications = json_decode($config->get('dashboard_notif', '[]'), true) ?? []; |
| @@ -213,6 +238,6 @@ | ||
| 213 | 238 | unset($existingNotifications[$key]); |
| 214 | 239 | } |
| 215 | 240 | } |
| 216 | 241 | |
| 217 | - $config->save(['dashboard_notif' => json_encode($existingNotifications)], false); | |
| 242 | + $config->saveConfig(['dashboard_notif' => json_encode($existingNotifications)], false); | |
| 218 | 243 | } |