Snippets tagged "symfony"
Générer automatiquement des liens internationnalisés avec symfony 1.2
Par exemple, dans le layout :
<ul> <li><?php echo link_to(__('French'), sprintf('@%s?sf_culture=fr', $r = $sf_context->getRouting()->getCurrentRouteName())) ?></li> <li><?php echo link_to(__('English'), sprintf('@%s?sf_culture=en', $r)) ?></li> </ul>
Autocomplétion au sein d'eclipse
Copier-coller le code suivant dans un fichier xml :
<?xml version="1.0" encoding="UTF-8" standalone="no"?><templates><template autoinsert="true" context="php" deleted="false" description="create a Symfony Action" enabled="true" name="action">public function execute${Action} { ${body} }</template><template autoinsert="true" context="php" deleted="false" description="Create a class controller" enabled="true" name="controller">class ${ControllerName}Actions extends sfActions { public function execute${action}() { ${body} } } </template><template autoinsert="true" context="php" deleted="false" description="criteria doSelect" enabled="true" name="doselect">$$c = new Criteria; $$${objects} = ${propelObject}Peer::doSelect($$c);</template></templates>
Installation au sein d'eclipse
- Dans eclipse allez dans Window > Preferences
- Choisir PHP dans la liste des préférences
- Choisir Template et cliquer sur Import
- Selectionner le fichier xml puis accepter
Note: Le mieux serait de s'inspirer des templates de texmate afin de se monter un système de templating complet pour Eclipse. Ajout également de commentaires compatibles phpdocumentor
[Symfony] Effacer partiellement le cache d'une application
Toujours utile depuis un contexte d'application différent de celui visé :
sfToolkit::clearGlob(sfConfig::get('sf_cache_dir').'/frontend/*/all/*/templates/toto.cache');
Cross apps url helper for symfony 1.0
Here's a helper that allow to generate cross apps urls in symfony 1.0
/** * Generates cross-apps urls in symfony 1.0 * * @param string the app we want to go to * @param string the route in the app. Must be valid * @param array the arguments required by the route. Optional * @return string */ function cross_app_url($app, $route, $args = null) { $host = sfContext::getInstance()->getRequest()->getHost() ; $env = sfConfig::get('sf_environment'); $appRoutingFile = SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.$app.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'routing.yml' ; $route = substr($route, 1, strlen($route)) ; if (file_exists($appRoutingFile)) { $yml = sfYaml::load($appRoutingFile) ; $routeUrl = $yml[$route]['url'] ; if ($args) { foreach ($args as $k => $v) { $routeUrl = str_replace(':' . $k, $v, $routeUrl) ; } } if (strrpos($routeUrl, '*') == strlen($routeUrl) - 1) { $routeUrl = substr($routeUrl, 0, strlen($routeUrl) - 2) ; } } return sprintf('http://%s/%s/%s', $host, ($env == 'dev' ? $app . '_dev.php' : ($app != $main_app) ? $app : ''), $routeUrl); }
Adapted from here
Symfony, trier aléatoirement les résultat avec Propel et MySQL
Attention, cela ne fonctionnera probablement qu'avec MySQL :
<?php $c = new criteria; $c->addAscendingOrderByColumn('rand()'); $results = TotoPeer::doSelect($c);
[Symfony 1.1 beta] Créer un test unitaire et initialiser Propel
Depuis l'apparition du nouveau système de configuration de Symfony 1.1, voici un boostrap type pour vos tests unitaires nécessitant l'accès à l'environnement Propel :
<?php require_once(dirname(__FILE__).'/../../config/ProjectConfiguration.class.php'); $configuration = ProjectConfiguration::getApplicationConfiguration('main', 'test', true); include($configuration->getSymfonyLibDir().'/vendor/lime/lime.php'); sfContext::createInstance($configuration);
Pensez cependant à remplacer main par le nom de votre application courante (par ex. frontend).
[Symfony] Utiliser sqlite pour stocker le cache des templates
D'abord, s'assurer d'avoir le module sqlite de php5 chargé et activé :
$ sudo apt-get install php5-sqlite
$ sudo /etc/init.d/apache2 restart
Dans le fichier factories.yml de l'application concernée :
view_cache:
class: sfSQLiteCache
param:
automaticCleaningFactor: 0
database: %SF_ROOT_DIR%/cache/cache.db
Et voilà, maintenant les symfony cc se feront en un éclair.
[Symfony] Un validateur de date qu'il est bien
Quelques fonctionnalités en plus par rapport à sfDateValidator (qu'il étend), notamment l'interdiction de date futures ou passées et l'évitement du traitement de la langue courante utilisateur (utile pour les formats de date figés).
/** * Custom date validator * */ class myDateValidator extends sfDateValidator { /** * Execute this validator. * * @param mixed A file or parameter value/array * @param error An error message reference * * @return bool true, if this validator executes successfully, otherwise false */ public function execute(&$value, &$error) { $culture = $this->getContext()->getUser()->getCulture(); // Validate the given date if ($this->getParameter('with_culture')) { $value1 = $this->getValidDate($value, $culture); } else { $value1 = strtotime($value); } if (!$value1 || -1 == $value1) // Before php 5.1, strtotime() returns -1 on fail { $error = $this->getParameter('date_error'); return false; } // Is there a compare to do? $compareDateParam = $this->getParameter('compare'); $compareDate = $this->getContext()->getRequest()->getParameter($compareDateParam); // If the compare date is given if ($compareDate) { $operator = trim($this->getParameter('operator', '=='), '\'" '); $value2 = $this->getValidDate($compareDate, $culture); // If the check date is valid, compare it. Otherwise ignore the comparison if ($value2) { $valid = false; switch ($operator) { case '>': $valid = $value1 > $value2; break; case '>=': $valid = $value1 >= $value2; break; case '==': $valid = $value1 == $value2; break; case '<=': $valid = $value1 <= $value2; break; case '<': $valid = $value1 < $value2; break; default: throw new sfValidatorException(sprintf('Invalid date comparison operator "%s"', $operator)); } if (!$valid) { $error = $this->getParameter('compare_error'); return false; } } } if (!$this->getParameter('allow_future') && $value1 > time()) { $error = $this->getParameter('future_error'); return false; } if (!$this->getParameter('allow_past') && $value1 < time()) { $error = $this->getParameter('past_error'); return false; } return true; } /** * Initializes the validator. * * @param sfContext The current application context * @param array An associative array of initialization parameters * * @return bool true, if initialization completes successfully, otherwise false */ public function initialize($context, $parameters = null) { // Initialize parent parent::initialize($context, $parameters); // Set defaults $this->getParameterHolder()->set('with_culture', true); $this->getParameterHolder()->set('allow_future', true); $this->getParameterHolder()->set('future_error', 'Future dates not allowed'); $this->getParameterHolder()->set('allow_past', true); $this->getParameterHolder()->set('past_error', 'Past dates not allowed'); $this->getParameterHolder()->add($parameters); return true; } }
[Symfony] [Validator] Valider une valeur en fonction d'une blacklist
Pour s'assurer qu'une valeur saisie par un utilisateur dans un formulaire Symfony ne fait pas partie d'une liste de valeurs interdites, on peut utiliser le validateur suivant :
Fichier sfBlacklistValidator.class.php :
<?php class sfBlacklistValidator extends sfValidator { public function initialize($context, $parameters = null) { // initialize parent parent::initialize($context); // set defaults $this->getParameterHolder()->set('blacklist_error', 'Value is not an allowed one'); $this->getParameterHolder()->set('case_sensitive', false); $this->getParameterHolder()->set('trim', true); $this->getParameterHolder()->add($parameters); return true; } public function execute(&$value, &$error) { // Forbidden names $blacklist = $this->getParameter('blacklist'); $casesensitive = $this->getParameter('case_sensitive'); $trim = $this->getParameter('trim'); if ($trim) { $value = trim($value); } if (is_array($blacklist) && count($blacklist) > 0) { if ($casesensitive) { $match = in_array($value, $blacklist); } else { $match = false; foreach ($blacklist as $item) { if (is_string($item) && strtolower($item) == strtolower($value)) { $match = true; break; } } } if ($match) { $error = $this->getParameterHolder()->get('blacklist_error'); return false; } } return true; } }
Dans un fichier de validation yml:
fields:
myfield:
sfBlacklistValidator:
blacklist: [admin, contact, info, infos, commercial, tech, support, sales, partnership, webmaster, business, owner]
case_sensitive: no
trim: yes
blacklist_error: The username you requested is not available
Les options sont assez explicites, mais en voici tout de même le détail :
- blacklist: tableau de valeurs prohibées au format YAML
- case_sensitive: effectuer les comparaisons en tenant compte de la casse
- trim: inclure les espaces en début et fin de chaînes
- blacklist_error: Message d'erreur à afficher en cas de valeur blacklistée
[Symfony] [Propel] Afficher la dernière requête effectuée
Pour afficher la dernière requête effectuée avec Propel :
echo Propel::getConnection()->getLastExecutedQuery();
C'est tout con, hein ?
Gérer les libellés et tris d'un selectbox avec Propel et les helpers objets Symfony
Pour gérer un joli combobox avec des valeurs textuelles représentatives choisies pour un objet Propel et éventuellement les trier, on peut faire :
<?php echo object_select_tag($produit, 'getTypeProduitId', array ( 'related_class' => 'TypeProduit', 'peer_method' => 'doSelectOrderByCode', )) ?>
ou bien dans un generator.yml
fields:
departement_id:
params: text_method=getNomCode peer_method=doSelectOrderByCode
[Symfony] Cacher simplement un fragment de code
Cacher le résultat d'un processus coûteux pour 24h :
<?php if (!cache('huge_process_of_the_death', 86400)): ?> <?php foreach ($stuff as $item): ?> // Your amazingly huge iteration processes here <?php endforeach; ?> <?php cache_save() ?> <?php endif; ?>
Pour le cacher pour un utilisateur spécifique :
<?php if (!cache('huge_process_of_the_death'.md5($user->getEmail()), 86400)): ?> <?php foreach ($stuff as $item): ?> // Your amazingly huge iteration processes here <?php endforeach; ?> <?php cache_save() ?> <?php endif; ?>
On s'assure juste de prendre l'empreinte md5 d'un attribut unique dans la table associée ;)
[Symfony] Chemins systèmes
Voici les chemins systèmes par défaut dans Symfony.
// root directory structure 'sf_cache_dir_name' => 'cache', 'sf_log_dir_name' => 'log', 'sf_lib_dir_name' => 'lib', 'sf_model_dir_name' => 'model', 'sf_web_dir_name' => 'web', 'sf_data_dir_name' => 'data', 'sf_config_dir_name' => 'config', 'sf_apps_dir_name' => 'apps', // global directory structure 'sf_app_dir' => $sf_root_dir.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.$sf_app, 'sf_model_dir' => $sf_root_dir.DIRECTORY_SEPARATOR.'model', 'sf_lib_dir' => $sf_root_dir.DIRECTORY_SEPARATOR.'lib', 'sf_web_dir' => $sf_root_dir.DIRECTORY_SEPARATOR.'web', 'sf_upload_dir' => $sf_root_dir.DIRECTORY_SEPARATOR.'web'.DIRECTORY_SEPARATOR.'uploads', 'sf_base_cache_dir' => $sf_root_dir.DIRECTORY_SEPARATOR.'cache'.DIRECTORY_SEPARATOR.$sf_app, 'sf_cache_dir' => $sf_root_dir.DIRECTORY_SEPARATOR.'cache'.DIRECTORY_SEPARATOR.$sf_app.DIRECTORY_SEPARATOR.$sf_environment, 'sf_log_dir' => $sf_root_dir.DIRECTORY_SEPARATOR.'log', 'sf_data_dir' => $sf_root_dir.DIRECTORY_SEPARATOR.'data', 'sf_config_dir' => $sf_root_dir.DIRECTORY_SEPARATOR.'config',
[Symfony] Autoloader toutes les classes d'un répertoire particulier
Il est très simple de charger automatiquement toutes les classes PHP définies dans un répertoire avec Symfony :
require_once($sf_symfony_lib_dir.'/util/sfCore.class.php'); sfCore::initSimpleAutoload('/path/to/libs');
[Symfony] Cacher un objet Propel sérialisé
Peut être utile pour les gros objets couteux et utilisés souvent.
$key = md5('myPropelObjectKey'); $cache = new sfProcessCache(); if ($cache->has($key)) { $obj = unserialize($cache->get($key)); } else { $obj = Table::doSelect(); $cache->set($key, serialize($obj)) }
[Symfony] Traiter les OR sql avec Propel
Voici comment gérer les "ou" SQL dans Propel :
$criteria = new Criteria(); $criteria->add(TotoPeer::NAME, 'Gérard Bouchard'); $criterion = $criteria->getNewCriterion ( TotoPeer::ID, 5 )->addOr($criteria->getNewCriterion ( TotoPeer::ID, 10 )); $criteria->addAnd($criterion); TotoPeer::doSelect($criteria);
Ceci donnera quelque chose comme :
SELECT * FROM toto WHERE toto.NAME = 'Gérard Bouchard' AND ( toto.ID = 5 OR toto.ID = 10 );
[Symfony] Executer une requête spécifique (custom query) avec Propel
$con = Propel::getConnection(); $stmt = $con->prepareStatement('SELECT foo, bar FROM baz WHERE name=? AND active=?'); $stmt->setString(1, 'MyName'); $stmt->setString(2, '1'); $rs = $stmt->executeQuery(ResultSet::FETCHMODE_NUM);
Ou encore plus con :
Propel::getConnection()->executeUpdate('SET FOREIGN_KEY_CHECKS=0');
[Symfony] Utiliser un helper dans une action
sfLoader::loadHelpers(array('First', 'Second'));
Simple !
