Outils personnels
Vous êtes ici : Accueil Symfony Trucs et astuces Symfony
Actions sur le document
  • Send this page to somebody
  • Print this page
  • Add Bookmarklet

Trucs et astuces Symfony

Par Pierre-Yves Landuré - Dernière modification 23/11/2008 16:56

Quelques bouts de codes intéressants si vous utilisez le framework de développement PHP Symfony.

En savoir plus sur les objets de Symfony

Si vous voulez plonger plus loin dans Symfony que ce qui est documenté dans le livre dedié à ce framework, vous pouvez utiliser l'API Symfony qui est une source d'informations très techniques sur le fonctionnement de ce framework.

En savoir plus sur la classe Criteria

La classe Criteria est à la base de toute requête complexe dans Symfony. Elle permet beaucoup de chose, cependant, sa documentation est relativement complexe à trouver. Je vous conseille pour en savoir plus sur l'utilisation des Criteria de lire la documentation de la classe Criteria (et de l'API Propel).

Accéder à l'utilisateur identifié en dehors des templates et des actions

Pour obtenir l'objet représentant l'utilisateur identifié, utilisez la ligne de code suivante :

$sf_user = sfContext::getInstance()->getUser();

Utiliser un Helper ailleurs que dans les templates

Si vous avez besoin d'utiliser les fonctions d'un Helper dans vos actions, ou dans un de vos objets, voici l'équivalent de la fonction "use_helper". Par exemple, pour le helper Form :

 sfLoader::loadHelpers('Form', sfContext::getInstance()->getModuleName());

Obtenir une date dans un format utilisable en PHP

Par défaut, le format des dates de Symfony est "Y-m-d", c'est à dire "2008-02-11" pour 11 février 2008. Cela n'est pas facilement utilisable pour faire des calculs avec PHP. Pour obtenir la date au format standard de PHP (cad. en nombre de secondes depuis le 1er janvier 1970), il vous suffit de donner la valeur null comme argument à votre récupération de date :

$date = $object->getCreatedAt(null);

Afficher les retours à la ligne du contenu saisi dans un textarea

Si vous souhaitez préserver les retours chariot d'un contenu saisi dans un textarea, utilisez le code suivant, ou $comment contient la saisie.

<?php echo nl2br(htmlspecialchars($comment)) ?>

Source: Merci à Heidy pour son aide.

Obtenir le chemin relatif vers la "racine de l'application"

Si votre application Symfony n'est pas hébergée directement à la racine de votre hôte virtuel, cela peut poser problème dans certains cas. Si c'est le cas pour vous, voici comment obtenir l'url relative de la racine de votre application Symfony. Dans l'exemple, il s'agit du code nécessaire à l'affichage d'une favicon:

<link rel="shortcut icon" href="<?php echo $sf_request->getRelativeUrlRoot() ?>/favicon.ico" />

Récupérer un tableau associatif de résultats avec doSelectRS

Par défaut, doSelectRS ne renvoie pas des données associatives. Pour que ce soit le cas, il vous faut utiliser le code suivant:

$rs = MyObjectPeer::doSelectRS($criteria);
$rs->setFetchMode(ResultSet::FETCHMODE_ASSOC);

$results = array();
while($rs->next())
{
$results[] = $rs->getRow();
}

Vérifier que votre critère ne contient pas déjà Distinct

Si vous utilisez des critères de requête complexes, vous avez pu constaté que Propel n'aime pas quand vous utilisez deux fois de suite setDistinct sur le même Criteria. Ce morceau de code vous permet d'utiliser setDistinct uniquement si c'est nécessaire :

  if(!in_array(Criteria::DISTINCT, $criteria->getSelectModifiers()))
{
$criteria->setDistinct();
  }

Exécuter une requête UPDATE avec Propel

Dans le cas où vous souhaitez exécuter une requête UPDATE sans passer par le modèle objet de Symfony, mais en restant dans l'environnement Propel, voici un bout de code qui peut vous intéresser :

$criteria = new Criteria();
$criteria->add(MyObjectPeer::ID,123);

$criteria->add(MyObjectPeer::NAME,'ola');
$criteria->add(MyObjectPeer::CITY,'pepito');

MyObjectPeer::doUpdate($criteria);

Attention: Cela ne fonctionne que si la clef primaire est le seul élément de la clause WHERE.

Source: Update according to the primary key using Propel.

Afficher le code SQL de la dernière requête exécutée.

Deux méthodes pour ce faire. La première fournit un code SQL incomplet :

echo $criteria->toString();

Plus complexe, mais le code SQL est exact :

$criteria = new Criteria();
$criteria->add(MyObjectPeer::ID_USER, $this->getAttribute('id'));
$this->connection = Propel::getConnection();
$this->groupes = MyObjectPeer::doSelect($criteria,$this->connection);
echo $connection->getLastExecutedQuery();

Source: Afficher requête MySQL générée par Propel.

Utiliser TinyMCE dans un formulaire Ajax

Pour que les modifications effectuées dans un champ riche "TinyMCE" soit disponible pour la requête Ajax, il faut ajouter la ligne suivante à vos paramètres Ajax :

'before' => 'if(typeof(tinyMCE) !== \'undefined\') { tinyMCE.triggerSave(); }'

Par exemple :

<?php echo submit_to_remote('ajax_submit', 'Post', array(
                                'update'   => 'forumpost_area',
                                'url'      => '@forumpost_add_ajax',
                                'before' => 'if(typeof(tinyMCE) !== \'undefined\') { tinyMCE.triggerSave(); }',
                                'loading'  => "Element.show('indicator')",
                                'complete' => "Element.hide('indicator')",
                        )
                        ,' class=submit_button ') ?>

Source: Rich textareas in AjaxForms.

Remarque: Si vous utilisez Ajax pour faire disparaître des éditeurs TinyMCE de votre page, vous pouvez rencontrer des problèmes avec triggerSave. Une solution pour contourner ce problème est d'utiliser le code suivant en lieu et place de celui ci-avant:

'before' => 'if(typeof(tinyMCE) !== \'undefined\') { for(e in tinyMCE.editors) { if(e.getElement()) e.save(); } }',

Remarque: Si votre champ TinyMCE est affiché via une requête Ajax, et que vous utilisez TinyMCE 3, vous rencontrerez probablement un problème d'initialisation de TinyMCE. Ce problème est dû à un plugin manquant dans TinyMCE 3 : le plugin Flash. Ce plugin est obsolète et remplacé par le plugin Média. Pour corriger ce problème d'initialisation, il suffit de créer un faux plugin Flash:

/bin/mkdir web/js/tiny_mce/plugins/flash
/bin/echo "// Fake plugin to avoid TinyMCE bug" > web/js/tiny_mce/plugins/flash/editor_plugin.js

Tester la présence d'une méthode dans un objet

Si vous avez besoin de savoir si une méthode est présente ou non dans un objet donné, vous pouvez utiliser la syntaxe suivante :

$methode_presente = is_callable(array($objet, 'maMethode'));

Il est cependant préférable d'utiliser la fonction method_exists:

$methode_presente = method_exists($objet, 'maMethode');

Si vous souhaitez appeler la méthode ainsi détectée, vous pouvez le faire grâce à la fonction call_user_func_array:

call_user_func_array(array($objet, 'maMethode'), array($param_1, $param_2));

Source: Vérifier l'existence de fonctions / méthodes en PHP.

Ne pas inclure certaines colonne dans l'hydratation d'un objet

Si vous utilisez des colonnes LOB de grande taille dans vos table, vous pouvez évitez leur récupération automatique à chaque fois que vous instanciez un objet de la classe associée. Pour ce faire, utilisez l'attribut lazyLoad dans votre fichier schema.xml :
    <column name="data" type="CLOB" lazyLoad="true" />

Source: Astuse Symfony : ne pas charger une colonne lors de "l'hydratation" d'un objet.

Code dépendant de la base de donnée, avec Propel

Il est parfois nécessaire de créer des requêtes complexes qui contiennent du code dépendant de la base de donnée. Propel fourni quelques fonctions pour ce faire :

  • toUpperCase($in) : Mettre en majuscule.
  • getStringDelimiter() : Renvoie le délimiteur de chaînes (en générale, un guillemet simple).
  • concatString($s1, $s2) : Concatène deux chaînes de caractères.
  • subString($s, $pos, $len) : extrait un morceau d'une chaîne de caractères.
  • strLength($s) : Calcule la longueur d'une chaîne de caractère.

Utilisation

Vous pouvez utiliser ces élements dans deux conditions :

  • Dans le résultat :
    $database_adapter = Propel::getDB($criteria->getDbName());
    $criteria->addAsColumn('column_alias', $database_adapter->toUpperCase(MyTablePeer::COLUMN));
  • Dans la clause WHERE :
    $database_adapter = Propel::getDB($criteria->getDbName());
    $criteria->add(MyTablePeer::COLUMN, sprintf('%s LIKE %s',
    MyTablePeer::COLUMN,
    $database_adapter->concatString(MyOtherTablePeer::COLUMN,
    $database_adapter->getStringDelimiter() . '%' . $database_adapter->getStringDelimiter()),
    ), Criteria::CUSTOM);

merci!

Posté par morganistic le 18/04/2008 12:54
merci pour tout çà, çà va vraiment me servir tous les jours!!

merci pour le coup de pouce

Posté par language kompis le 22/08/2008 12:36
Cela fait plusieurs fois, que Google m'amène sur ce site pour résoudre mes énigmes de débutant. Chapeau, j'en repars à chaque fois avec un bug de moins. Merci lone wolf d'avoir consigner ces astuces, elles me donnent un vrai coup de pousse. h.

Suggestion pour afficher les sauts de ligne

Posté par Heidy le 18/09/2008 12:00
Plutôt que:
<?php echo str_replace(array("\r\n", "\n", "\r"), '<br/>', htmlspecialchars($comment)) ?>

On peut écrire
<?php echo nl2br(htmlspecialchars($comment)) ?>


Réalisé avec Plone

Ce site respecte les normes suivantes :

Wikio