INDEX
Useful tips for KohanaPHP v. 2.x framework
Cet article est mis à jour régulièrement.
Dernière mise à jour : 27 août 2012.
Envoyer le résultat d’une requête ORM en JSON
Nous allons d’abord créer, dans libraries/MY_Controller.php
, une méthode qui envoie les bons headers et prépare la sortie :
public function send_json($items) { header('Cache-Control: no-cache, must-revalidate'); header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); header('Content-type: application/json'); echo json_encode( array_map( create_function( '$obj', 'return $obj->as_array();'), $items->as_array() ) ); exit(); }
On peut ensuite l’utiliser dans n’importe quel contrôleur de la sorte :
public function index() { $items = ORM::factory('brand')->find_all(); $this->send_json($items); }
Il est intéressant de noter que l’objet ORM reste utilisable pour d’autres usages, par exemple :
echo count($items); // 7
Astuce : il peut être nécessaire de désactiver le Profiler dans le contrôleur appelant la méthode send_json
:
public function __construct() { parent::__construct(); $this->profiler->disable(); }
Exemples et propriétés d’un Model
(Liste non exhaustive, remplie au fur et à mesure)
Un modèle simple, utilisant l’objet $db
(lire la doc des Models) :
<?php defined('SYSPATH') or die('No direct script access.'); class Brand_Model extends Model { protected $db = 'default'; public function __construct() { //load database library into $this->db (can be omitted if not required) parent::__construct(); } }
Un modèle utilisant l’ORM (lire la doc de l’ORM) :
<?php defined('SYSPATH') or die('No direct script access.'); class Brand_Model extends ORM { protected $db = 'default'; }
La syntaxe des variables des Models et de l’ORM
// Groupe d'appartenance de la table comme déclaré dans <code>/config/database.php</code> : protected $db = 'groupname'; // Modifier la clé primaire : protected $primary_key = 'id'; // Autres variables : protected $table_columns = array('id','username','last_login','anotherfield'); protected $sorting = array('last_login' => 'desc', 'username' => 'asc');
Customiser la page des erreurs
Il suffit de créer un fichier nommé kohana_error_page.php
à la racine du dossier views
.
Provoquer une erreur 404
Event::run('system.404');
Désactiver le buffer de sortie
Dans MY_Controller.php :
public function __construct() { parent::__construct(); Kohana::close_buffers(); }
Attention, si placé à cet endroit le buffer sera désactivé partout, ce qui provoquera la nullité de url::redirect
. Pour un usage ponctuel, placer simplement Kohana::close_buffers();
en tête de méthode, dans un contrôleur :
public function import() { Kohana::close_buffers(); ob_start(); (...)
Ajouter éventuellement :
public function before() { // empty the output buffer ob_end_flush(); // call parent before() just incase there's anything // in the parent before that you need/want to execute parent::before(); }
Et finalement dans votre script :
(...) ob_flush(); flush(); (...)
Sélectionner les users ayant un certain rôle
You want to do this:
$members = ORM::factory('role', 'member')->users;
You take the role and find it’s users, not the other way around.
Ajouter un option
vide en première position d’un form::dropdown
Dans le contrôleur :
public function getAllCategories() { $categories = ORM::factory('folder')->where('group_id', 56)->orderby('name', 'ASC')->select_list(); $categories[0] = ' '; asort($categories); return $categories; }
Dans la vue :
<label for="country_id" class="required">Country</label><br> <?php echo form::dropdown('country_id', $countries, '', 'class="required"') ?>
La première valeur (vide) sera sélectionnée. Cette syntaxe est compatible avec [jquery.validate->https://bassistance.de/jquery-plugins/jquery-plugin-validation/] !
Alternative :
$clients = ORM::factory('client')->orderby('name', 'asc')->select_list('id', 'name'); $clients[0] = 'Choisissez...'; $this->template->content->clients = $clients;
<?php echo form::label('client_id', 'Client*'); echo form::dropdown('client_id', $clients, 0); ?>
Variante plus simple :
$brands = ORM::factory('brand')->select_list('id', 'brand'); array_unshift($brands, 'Choisissez'); echo form::dropdown('brand_id', $brands);
Récupérer un unique résultat issue de l’objet $db
$max_numero = $this->db->query('SELECT MAX( numero ) as numero FROM folders WHERE folder_id ='.$project_id)->current(); echo $max_numero->numero;
Vérifier si un certain Role est affecté à un User
Check if a User has a certain Role
$user = ORM::factory('user', $this->input->post('email')); if ($user->has(ORM::factory('role', 'production'))) { // has the "production" role } else { // hasn't }
Outrepasser la boucle foreach() si vous savez que find_all ne renverra qu’un seul résultat
Avoid foreach() loop when you’re sure find_all() will return a single result
Controller
// use find() instead of find_all $this->template->content->citation = ORM::factory('production_field')->where('user_id', Auth::instance()->get_user()->id)->where('rubrique', 'citation')->find();
View
<?php // no need to loop through 1 result! echo ORM::factory('config')->where('key', 'site_theming-fr_FR')->find()->value; ?>
Variante
// pour afficher la valeur de la colonne nommée "USD" : $rates = ORM::factory('rate')->orderby('update','desc')->find_all(1,0); echo $rates->current()->USD;
Aucune vue pour la méthode d’un contrôleur
Set no view for a method in a controller
This one is really basic, but sometimes I just can’t remember the syntax (I get confused with CakePHP ‘s).
Method
$this->auto_render = false;
Récupérer les valeurs POST, GET, SERVER en contournant la configuration « global_xss_filtering »
Parfois en récupérant des données d’une première version d’un site, il arrive que certaines données ne soient pas des mieux formatées et on se retrouve alors avec des bouts de texte manquant lorsqu’on enregistre les données d’un formulaire avec les éléments fournis à disposition par kohana.
Par exemple, un textarea contenant le code suivant :
...<img src="https://www.italic.fr/image.jpg" alt="Le Lorem Ipsum est simplement du faux texte employé dans la composition..." width="417" height="600" />...
après validation se retrouvait avec le code suivant :
...<img src="https://www.italic.fr/image.jpg" alt="Le Lorem Ipsum />....
Ceci est dû au « nettoyage » xss fait par kohana. Pour récupérer la valeur d’un champ sans qu’il soit nettoyé, il suffit d’étendre la classe Input_Core en créant un fichier php nommé MY_Input.php dans le répertoire libraries.
Voici le code du fichier :
<?php defined('SYSPATH') or die('No direct script access.'); class Input extends Input_Core { public function __construct() { $use_xss_clean = (bool) Kohana::config('core.global_xss_filtering'); // Only run this once! if (self::$instance === NULL AND $use_xss_clean) { // Disable the xss cleaner and copy the data $this->use_xss_clean = FALSE; $this->raw_data['post'] = $_POST; $this->raw_data['get'] = $_GET; $this->raw_data['cookie'] = $_COOKIE; // Don't forget to turn it back on! $this->use_xss_clean = TRUE; } // don't for get to call the parent constructor! parent::__construct(); } /** * Fetch raw global data * * @param string global data name * @param string key to find * @param mixed default value * @return mixed */ public function raw($type = 'post', $key = array(), $default = NULL) { if (isset($this->raw_data[$type][$key])) : return stripslashes($this->search_array($this->raw_data[$type], $key, $default)); endif; } } ?>
On peut alors récupérer la valeur du champ en faisant :
$this->input->raw('post','body');
Créer une page 404 utilisant le template par défaut du site
Parfois, on doit personnaliser la page 404 d’un site tout en gardant le template par défaut qui lui même contient des données dynamique. Pour cela il suffit de créer une page comme on le fait d’habitude :
//controller pages.php public function print_404() { header('HTTP/1.1 404 File Not Found'); ... //paramètres du template ... $this->template->render(TRUE); //important pour l'affichage du template }
Ne surtout pas oublier le header indiquant qu’il s’agit d’une 404 et la ligne
$this->template->render(TRUE);
sinon le template ne sera pas affiché quand on utilisera cette méthode pour afficher le rendu du 404.
Pour surchager le 404 par défaut, nous allons utiliser les hooks, pour cela il faut vérifier qu’ils sont activés dans /application/config/config.php :
/** * Enable or disable hooks. */ $config['enable_hooks'] = TRUE;
On cré ensuite le fichier MY_404 dans le répertoire application/hooks et on y colle le code suivant :
<?php defined('SYSPATH') or die('No direct script access.'); /** * Le hook 404 permet de surcharger l'évenement 404 par défaut **/ class MY_404 { /** * Afficher l'erreur 404 **/ public static function show_404() { $page = new Pages_Controller(); $page->print_404(); exit(); } } // END class Coming_soon_Hook // Supprimer l'évenement 404 par défaut et utiliser le notre Event::clear('system.404', array('Kohana', 'show_404')); Event::add('system.404', array('MY_404', 'show_404'));
Avec ça les erreurs 404 seront personnalisées, néanmoins il reste une dernière chose à faire si vous voulez que les erreurs 404 générées depuis
throw new Kohana_404_Exception()
soient prises en compte. Pour cela il faut modifier le fichier(créer le s’il n’existe pas) application/view/kohana_error_page.php en lui mettant ceci :
Event::run('system.404');
This article will be updated from time to time…