From 34d7450d3c13342715e90ec21bceaa13e1baa876 Mon Sep 17 00:00:00 2001 From: Frédéric Guillot Date: Sun, 28 Dec 2014 11:28:50 -0500 Subject: Template helpers refactoring --- app/Core/Helper.php | 629 ++++++++++++++++++++++++++++++++++++++++++++++++++ app/Core/Session.php | 50 ++-- app/Core/Template.php | 12 +- 3 files changed, 670 insertions(+), 21 deletions(-) create mode 100644 app/Core/Helper.php (limited to 'app/Core') diff --git a/app/Core/Helper.php b/app/Core/Helper.php new file mode 100644 index 00000000..86034692 --- /dev/null +++ b/app/Core/Helper.php @@ -0,0 +1,629 @@ +container = $container; + } + + /** + * Load automatically models + * + * @access public + * @param string $name Model name + * @return mixed + */ + public function __get($name) + { + return $this->container[$name]; + } + + /** + * Return the user full name + * + * @param array $user User properties + * @return string + */ + public function getFullname(array $user = array()) + { + return $this->user->getFullname(empty($user) ? $_SESSION['user'] : $user); + } + + /** + * HTML escaping + * + * @param string $value Value to escape + * @return string + */ + public function e($value) + { + return htmlspecialchars($value, ENT_QUOTES, 'UTF-8', false); + } + + /** + * Add a Javascript asset + * + * @param string $filename Filename + * @return string + */ + public function js($filename) + { + return ''; + } + + /** + * Add a stylesheet asset + * + * @param string $filename Filename + * @return string + */ + public function css($filename) + { + return ''; + } + + /** + * Display the form error class + * + * @param array $errors Error list + * @param string $name Field name + * @return string + */ + public function errorClass(array $errors, $name) + { + return ! isset($errors[$name]) ? '' : ' form-error'; + } + + /** + * Display a list of form errors + * + * @param array $errors List of errors + * @param string $name Field name + * @return string + */ + public function errorList(array $errors, $name) + { + $html = ''; + + if (isset($errors[$name])) { + + $html .= ''; + } + + return $html; + } + + /** + * Get an escaped form value + * + * @param mixed $values Values + * @param string $name Field name + * @return string + */ + public function formValue($values, $name) + { + if (isset($values->$name)) { + return 'value="'.$this->e($values->$name).'"'; + } + + return isset($values[$name]) ? 'value="'.$this->e($values[$name]).'"' : ''; + } + + /** + * Hidden CSRF token field + * + * @return string + */ + public function formCsrf() + { + return ''; + } + + /** + * Display a hidden form field + * + * @param string $name Field name + * @param array $values Form values + * @return string + */ + public function formHidden($name, array $values = array()) + { + return 'formValue($values, $name).'/>'; + } + + /** + * Display a select field + * + * @param string $name Field name + * @param array $options Options + * @param array $values Form values + * @param array $errors Form errors + * @param string $class CSS class + * @return string + */ + public function formSelect($name, array $options, array $values = array(), array $errors = array(), $class = '') + { + $html = ''; + $html .= $this->errorList($errors, $name); + + return $html; + } + + /** + * Display a radio field group + * + * @param string $name Field name + * @param array $options Options + * @param array $values Form values + * @return string + */ + public function formRadios($name, array $options, array $values = array()) + { + $html = ''; + + foreach ($options as $value => $label) { + $html .= $this->formRadio($name, $label, $value, isset($values[$name]) && $values[$name] == $value); + } + + return $html; + } + + /** + * Display a radio field + * + * @param string $name Field name + * @param string $label Form label + * @param string $value Form value + * @param boolean $selected Field selected or not + * @param string $class CSS class + * @return string + */ + public function formRadio($name, $label, $value, $selected = false, $class = '') + { + return ''; + } + + /** + * Display a checkbox field + * + * @param string $name Field name + * @param string $label Form label + * @param string $value Form value + * @param boolean $checked Field selected or not + * @param string $class CSS class + * @return string + */ + public function formCheckbox($name, $label, $value, $checked = false, $class = '') + { + return ''; + } + + /** + * Display a form label + * + * @param string $name Field name + * @param string $label Form label + * @param array $attributes HTML attributes + * @return string + */ + public function formLabel($label, $name, array $attributes = array()) + { + return ''; + } + + /** + * Display a textarea + * + * @param string $name Field name + * @param array $values Form values + * @param array $errors Form errors + * @param array $attributes HTML attributes + * @param string $class CSS class + * @return string + */ + public function formTextarea($name, $values = array(), array $errors = array(), array $attributes = array(), $class = '') + { + $class .= $this->errorClass($errors, $name); + + $html = ''; + $html .= $this->errorList($errors, $name); + + return $html; + } + + /** + * Display a input field + * + * @param string $type HMTL input tag type + * @param string $name Field name + * @param array $values Form values + * @param array $errors Form errors + * @param array $attributes HTML attributes + * @param string $class CSS class + * @return string + */ + public function formInput($type, $name, $values = array(), array $errors = array(), array $attributes = array(), $class = '') + { + $class .= $this->errorClass($errors, $name); + + $html = 'formValue($values, $name).' class="'.$class.'" '; + $html .= implode(' ', $attributes).'/>'; + if (in_array('required', $attributes)) $html .= '*'; + $html .= $this->errorList($errors, $name); + + return $html; + } + + /** + * Display a text field + * + * @param string $name Field name + * @param array $values Form values + * @param array $errors Form errors + * @param array $attributes HTML attributes + * @param string $class CSS class + * @return string + */ + public function formText($name, $values = array(), array $errors = array(), array $attributes = array(), $class = '') + { + return $this->formInput('text', $name, $values, $errors, $attributes, $class); + } + + /** + * Display a password field + * + * @param string $name Field name + * @param array $values Form values + * @param array $errors Form errors + * @param array $attributes HTML attributes + * @param string $class CSS class + * @return string + */ + public function formPassword($name, $values = array(), array $errors = array(), array $attributes = array(), $class = '') + { + return $this->formInput('password', $name, $values, $errors, $attributes, $class); + } + + /** + * Display an email field + * + * @param string $name Field name + * @param array $values Form values + * @param array $errors Form errors + * @param array $attributes HTML attributes + * @param string $class CSS class + * @return string + */ + public function formEmail($name, $values = array(), array $errors = array(), array $attributes = array(), $class = '') + { + return $this->formInput('email', $name, $values, $errors, $attributes, $class); + } + + /** + * Display a number field + * + * @param string $name Field name + * @param array $values Form values + * @param array $errors Form errors + * @param array $attributes HTML attributes + * @param string $class CSS class + * @return string + */ + public function formNumber($name, $values = array(), array $errors = array(), array $attributes = array(), $class = '') + { + return $this->formInput('number', $name, $values, $errors, $attributes, $class); + } + + /** + * Display a numeric field (allow decimal number) + * + * @param string $name Field name + * @param array $values Form values + * @param array $errors Form errors + * @param array $attributes HTML attributes + * @param string $class CSS class + * @return string + */ + public function formNumeric($name, $values = array(), array $errors = array(), array $attributes = array(), $class = '') + { + return $this->formInput('text', $name, $values, $errors, $attributes, $class.' form-numeric'); + } + + /** + * Link + * + * a('link', 'task', 'show', array('task_id' => $task_id)) + * + * @param string $label Link label + * @param string $controller Controller name + * @param string $action Action name + * @param array $params Url parameters + * @param boolean $csrf Add a CSRF token + * @param string $class CSS class attribute + * @param boolean $new_tab Open the link in a new tab + * @return string + */ + public function a($label, $controller, $action, array $params = array(), $csrf = false, $class = '', $title = '', $new_tab = false) + { + return ''.$label.''; + } + + /** + * URL query string + * + * u('task', 'show', array('task_id' => $task_id)) + * + * @param string $controller Controller name + * @param string $action Action name + * @param array $params Url parameters + * @param boolean $csrf Add a CSRF token + * @return string + */ + public function u($controller, $action, array $params = array(), $csrf = false) + { + $html = '?controller='.$controller.'&action='.$action; + + if ($csrf) { + $params['csrf_token'] = Security::getCSRFToken(); + } + + foreach ($params as $key => $value) { + $html .= '&'.$key.'='.$value; + } + + return $html; + } + + /** + * Pagination links + * + * @param array $pagination Pagination information + * @return string + */ + public function paginate(array $pagination) + { + extract($pagination); + + if ($pagination['offset'] === 0 && ($total - $pagination['offset']) <= $limit) { + return ''; + } + + $html = ''; + + return $html; + } + + /** + * Column sorting (work with pagination) + * + * @param string $label Column title + * @param string $column SQL column name + * @param array $pagination Pagination information + * @return string + */ + public function order($label, $column, array $pagination) + { + extract($pagination); + + $prefix = ''; + + if ($order === $column) { + $prefix = $direction === 'DESC' ? '▼ ' : '▲ '; + $direction = $direction === 'DESC' ? 'ASC' : 'DESC'; + } + + $order = $column; + + return $prefix.$this->a($label, $controller, $action, $params + compact('offset', 'order', 'direction')); + } + + /** + * Markdown transformation + * + * @param string $text Markdown content + * @param array $link Link parameters for replacement + * @return string + */ + public function markdown($text, array $link = array('controller' => 'task', 'action' => 'show', 'params' => array())) + { + $html = Parsedown::instance() + ->setMarkupEscaped(true) # escapes markup (HTML) + ->text($text); + + // Replace task #123 by a link to the task + $html = preg_replace_callback('!#(\d+)!i', function($matches) use ($link) { // TODO: Fix that + return a( + $matches[0], + $link['controller'], + $link['action'], + $link['params'] + array('task_id' => $matches[1]) + ); + }, $html); + + return $html; + } + + /** + * Get the current URL without the querystring + * + * @return string + */ + public function getCurrentBaseUrl() + { + $url = Request::isHTTPS() ? 'https://' : 'http://'; + $url .= $_SERVER['SERVER_NAME']; + $url .= $_SERVER['SERVER_PORT'] == 80 || $_SERVER['SERVER_PORT'] == 443 ? '' : ':'.$_SERVER['SERVER_PORT']; + $url .= dirname($_SERVER['PHP_SELF']) !== '/' ? dirname($_SERVER['PHP_SELF']).'/' : '/'; + + return $url; + } + + /** + * Dispplay the flash session message + * + * @param string $html HTML wrapper + * @return string + */ + public function flash($html) + { + $data = ''; + + if (isset($_SESSION['flash_message'])) { + $data = sprintf($html, $this->e($_SESSION['flash_message'])); + unset($_SESSION['flash_message']); + } + + return $data; + } + + /** + * Display the flash session error message + * + * @param string $html HTML wrapper + * @return string + */ + public function flashError($html) + { + $data = ''; + + if (isset($_SESSION['flash_error_message'])) { + $data = sprintf($html, $this->e($_SESSION['flash_error_message'])); + unset($_SESSION['flash_error_message']); + } + + return $data; + } + + /** + * Format a file size + * + * @param integer $size Size in bytes + * @param integer $precision Precision + * @return string + */ + public function formatBytes($size, $precision = 2) + { + $base = log($size) / log(1024); + $suffixes = array('', 'k', 'M', 'G', 'T'); + + return round(pow(1024, $base - floor($base)), $precision).$suffixes[(int)floor($base)]; + } + + /** + * Truncate a long text + * + * @param string $value Text + * @param integer $max_length Max Length + * @param string $end Text end + * @return string + */ + public function summary($value, $max_length = 85, $end = '[...]') + { + $length = strlen($value); + + if ($length > $max_length) { + return substr($value, 0, $max_length).' '.$end; + } + + return $value; + } + + /** + * Return true if needle is contained in the haystack + * + * @param string $haystack Haystack + * @param string $needle Needle + * @return boolean + */ + public function contains($haystack, $needle) + { + return strpos($haystack, $needle) !== false; + } + + /** + * Return a value from a dictionary + * + * @param mixed $id Key + * @param array $listing Dictionary + * @param string $default_value Value displayed when the key doesn't exists + * @return string + */ + public function inList($id, array $listing, $default_value = '?') + { + if (isset($listing[$id])) { + return $this->e($listing[$id]); + } + + return $default_value; + } +} diff --git a/app/Core/Session.php b/app/Core/Session.php index 3305eca3..0e5f7426 100644 --- a/app/Core/Session.php +++ b/app/Core/Session.php @@ -2,13 +2,15 @@ namespace Core; +use ArrayAccess; + /** * Session class * * @package core * @author Frederic Guillot */ -class Session +class Session implements ArrayAccess { /** * Sesion lifetime @@ -59,7 +61,7 @@ class Session ini_set('session.entropy_length', '32'); ini_set('session.hash_bits_per_character', 6); - // If session was autostarted with session.auto_start = 1 in php.ini destroy it + // If the session was autostarted with session.auto_start = 1 in php.ini destroy it if (isset($_SESSION)) { session_destroy(); } @@ -88,19 +90,17 @@ class Session $_SESSION = array(); // Destroy the session cookie - if (ini_get('session.use_cookies')) { - $params = session_get_cookie_params(); - - setcookie( - session_name(), - '', - time() - 42000, - $params['path'], - $params['domain'], - $params['secure'], - $params['httponly'] - ); - } + $params = session_get_cookie_params(); + + setcookie( + session_name(), + '', + time() - 42000, + $params['path'], + $params['domain'], + $params['secure'], + $params['httponly'] + ); // Destroy session data session_destroy(); @@ -127,4 +127,24 @@ class Session { $_SESSION['flash_error_message'] = $message; } + + public function offsetSet($offset, $value) + { + $_SESSION[$offset] = $value; + } + + public function offsetExists($offset) + { + return isset($_SESSION[$offset]); + } + + public function offsetUnset($offset) + { + unset($_SESSION[$offset]); + } + + public function offsetGet($offset) + { + return isset($_SESSION[$offset]) ? $_SESSION[$offset] : null; + } } diff --git a/app/Core/Template.php b/app/Core/Template.php index da61f579..9688c2a5 100644 --- a/app/Core/Template.php +++ b/app/Core/Template.php @@ -10,7 +10,7 @@ use LogicException; * @package core * @author Frederic Guillot */ -class Template +class Template extends Helper { /** * Template path @@ -20,18 +20,18 @@ class Template const PATH = 'app/Template/'; /** - * Load a template + * Render a template * * Example: * - * $template->load('template_name', ['bla' => 'value']); + * $template->render('template_name', ['bla' => 'value']); * * @access public * @params string $__template_name Template name * @params array $__template_args Key/Value map of template variables * @return string */ - public function load($__template_name, array $__template_args = array()) + public function render($__template_name, array $__template_args = array()) { $__template_file = self::PATH.$__template_name.'.php'; @@ -57,9 +57,9 @@ class Template */ public function layout($template_name, array $template_args = array(), $layout_name = 'layout') { - return $this->load( + return $this->render( $layout_name, - $template_args + array('content_for_layout' => $this->load($template_name, $template_args)) + $template_args + array('content_for_layout' => $this->render($template_name, $template_args)) ); } } -- cgit v1.2.3