assign('msg', $feedback['mes']); if (! empty($feedback['errortype'])) { $smarty->assign('errortype', $feedback['errortype']); } $smarty->display(! empty($feedback['tpl']) ? $feedback['tpl'] : 'error.tpl'); die; } /** * Add note feedback * * This is a specific application of the add function below for notes. * * @param $feedback * @param bool $sendHeaders * @throws Exception */ public static function note($feedback, $sendHeaders = false) { $feedback = self::checkFeedback($feedback); $feedback['type'] = 'note'; $feedback['title'] = empty($feedback['title']) ? tr('Note') : $feedback['title']; $feedback['icon'] = empty($feedback['icon']) ? 'information' : $feedback['icon']; self::add($feedback, $sendHeaders); } /** * Add success feedback * * This is a specific application of the add function below for success feedback. * * @param $feedback * @param bool $sendHeaders * @throws Exception */ public static function success($feedback, $sendHeaders = false) { $feedback = self::checkFeedback($feedback); $feedback['type'] = 'feedback'; $feedback['title'] = empty($feedback['title']) ? tr('Success') : $feedback['title']; $feedback['icon'] = empty($feedback['icon']) ? 'success' : $feedback['icon']; self::add($feedback, $sendHeaders); } /** * Add warning feedback * * This is a specific application of the add function below for warnings. * * @param $feedback * @param bool $sendHeaders * @throws Exception */ public static function warning($feedback, $sendHeaders = false) { $feedback = self::checkFeedback($feedback); $feedback['type'] = 'warning'; $feedback['title'] = empty($feedback['title']) ? tr('Warning') : $feedback['title']; $feedback['icon'] = empty($feedback['icon']) ? 'warning' : $feedback['icon']; self::add($feedback, $sendHeaders); } /** * Add feedback to a global or smarty variable * * Adds feedback to either the PHP $_SESSION['tikifeedback'] global variable or to a Smarty {$tikifeedback} * variable. Typically one of the custom functions above that use this function and that are specific for errors, * warnings, notes and success feedback will be used in the individual php file where the error is generated. * * @param $feedback * - Must at least contain at least a string message * - Can be an array of messages too, in which case the array key 'mes' should be used * - Other array keys can be used that correspond to remarksbox parameters, such as 'type', 'title', * and 'icon' * - A custom smarty template can be indicated using the 'tpl' array key (otherwise * templates/feedback/default.tpl is used). The specified Smarty template will need to be added to the * templates/feedback directory. E.g., including 'tpl' => 'pref' in the $feedback array would cause * the templates/feedback/pref.tpl to be used * - Other custom array keys can be added for use on custom templates * @param bool $sendHeaders * @return void or bool * @throws Exception */ public static function add($feedback, $sendHeaders = false) { $feedback = self::checkFeedback($feedback); if (isset($_SESSION['tikifeedback'])) { if (! in_array($feedback, $_SESSION['tikifeedback'])) { $_SESSION['tikifeedback'][] = $feedback; } } else { $_SESSION['tikifeedback'][] = $feedback; } if ($sendHeaders) { self::sendHeaders(); } } /** * Clear local feedback storage */ public static function clear() { $_SESSION['tikifeedback'] = []; } /** * Utility to ensure $feedback parameter is in the right format * * @param $feedback * @return array|bool */ private static function checkFeedback($feedback) { if (empty($feedback)) { trigger_error(tr('Feedback class called with no feedback provided.'), E_USER_NOTICE); return false; } elseif (! is_array($feedback)) { $feedback = ['mes' => $feedback]; } else { if (empty($feedback['mes'])) { trigger_error(tr('Feedback class called with no feedback provided.'), E_USER_NOTICE); return false; } elseif (! is_array($feedback['mes'])) { $feedback['mes'] = [$feedback['mes']]; } } return $feedback; } /** * Gets feedback that has been added to either the global PHP $_SESSION['tikifeedback'] or Smarty {$tikifeedback} * variable * * This function is mainly used and already included in the Smarty {feedback} function included in the basic * layout_view templates to retrieve and display any feedback that has been added. Normally there isn't a need for * developers to use this function otherwise. * * @return array|bool */ public static function get() { $result = false; if (isset($_SESSION['tikifeedback'])) { //get feedback from session variable if (isset($_SESSION['tikifeedback'])) { $feedback = $_SESSION['tikifeedback']; unset($_SESSION['tikifeedback']); } else { $feedback = []; } //add default tpl if not set foreach ($feedback as $key => $item) { if (is_array($item)) { $feedback[$key] = array_merge([ 'tpl' => 'default', 'type' => 'feedback', 'icon' => '', 'title' => tr('Note') ], $item); } if (empty($item['tpl'])) { $feedback[$key]['tpl'] = 'default'; } } //make the tpl the first level array key $fbbytpl = []; foreach ($feedback as $key => $item) { $tplkey = $item['tpl']; unset($item['tpl']); $fbbytpl[$tplkey][] = $item; } if (! empty($fbbytpl)) { $result = $fbbytpl; } } return $result; } /** * Add feedback through ajax * * @throws Exception */ public static function sendHeaders() { require_once 'lib/smarty_tiki/function.feedback.php'; $feedback = rawurlencode(str_replace(["\n", "\r", "\t"], '', smarty_function_feedback( [], // Encode since HTTP headers are ASCII-only. Other characters can go through, but header()'s documentation has no word on their treatment. Chealer 2017-06-20 TikiLib::lib('smarty')->getEmptyInternalTemplate() ))); header('X-Tiki-Feedback: ' . $feedback); } /** * Print any feedback out to the command line * * @param \Symfony\Component\Console\Output\OutputInterface $output * @param bool $cron */ public static function printToConsole($output, $cron = false) { if ($output->isQuiet()) { return; } $errors = \Feedback::get(); if (is_array($errors)) { foreach ($errors as $type => $message) { if (is_array($message)) { if (is_array($message[0]) && ! empty($message[0]['mes'])) { $out = ''; foreach ($message as $msg) { $type = $msg['type']; $out .= $type . ': ' . str_replace('
', "\n", $msg['mes'][0]) . "\n"; } $message = $out; } elseif (! empty($message['mes'])) { $message = $type . ': ' . str_replace('
', "\n", $message['mes']); } if ($type === 'success' || $type === 'note') { if (! $output->isVeryVerbose()) { continue; } $type = 'info'; } elseif ($type === 'warning') { if (! $output->isVerbose()) { continue; } $type = 'comment'; } if (! $cron || $type === 'error') { $output->writeln("<$type>$message"); } } else { $output->writeln("$message"); } } } } /** * Print any feedback out to a log file * * @param \Laminas\Log\Logger $log * @param bool $clear - remove existing entries from the local storage after sending to log file */ public static function printToLog($log, $clear = false) { $errors = \Feedback::get(); if (is_array($errors)) { foreach ($errors as $type => $message) { if (is_array($message)) { if (is_array($message[0]) && ! empty($message[0]['mes'])) { $out = ''; foreach ($message as $msg) { $type = $msg['type']; $out .= $type . ': ' . str_replace('
', "\n", $msg['mes'][0]) . "\n"; } $message = $out; } elseif (! empty($message['mes'])) { $message = $type . ': ' . str_replace('
', "\n", $message['mes']); } switch ($type) { case 'error': $log->err($message); break; case 'warning': $log->warn($message); break; case 'feedback': case 'success': $log->info($message); break; case 'note': $log->notice($message); break; } } else { $log->err($message); } } } } /** * Get an array of error or warning messages only. */ public static function errorMessages() { $messages = []; $errors = \Feedback::get(); if (is_array($errors)) { foreach ($errors as $type => $message) { if (is_array($message)) { if (is_array($message[0]) && ! empty($message[0]['mes'])) { $out = ''; foreach ($message as $msg) { $type = $msg['type']; $out .= str_replace('
', "\n", $msg['mes'][0]) . "\n"; } $message = $out; } elseif (! empty($message['mes'])) { $message = str_replace('
', "\n", $message['mes']); } if ($type == 'error' || $type == 'warning') { $messages[] = $message; } } else { $messages[] = $message; } } } return $messages; } /** * Remove a specific message from feedback * @param callable $comparableFunction $item as param and should return a boolean */ public static function removeIf(callable $comparableFunction) { if (! isset($_SESSION['tikifeedback'])) { return; } foreach ($_SESSION['tikifeedback'] as $key => $value) { if ($comparableFunction($value)) { unset($_SESSION['tikifeedback'][$key]); } } } }