2017-01-22 4 views
1

Je veux avoir un fichier ou une liste que je peux facilement mettre à jour avec des valeurs qui pourraient changer dans mon application.Quel est le meilleur moyen de réutiliser des valeurs dans toute l'application de Symfony 3?

Je ne veux pas vraiment coder les valeurs de texte dans les modèles. Je préfère avoir toutes ces valeurs au même endroit et étiquetées correctement.

Des exemples de valeurs qui pourraient se mises à jour sont:

  • Titre de la page
  • Logo texte
  • Marque ou nom société

J'ai pensé à deux options:

  1. Ajoutez-les à la configuration twig dans config.ym l. C'est un peu brouillon et cela ne semble pas organisé si je décide d'y mettre beaucoup de valeurs.
  2. Créer une table de base de données pour ceux-ci et inclure l'entité dans chaque contrôleur où j'ai besoin d'utiliser les valeurs. Cela pourrait créer trop de travail.

Y a-t-il d'autres options ou est-ce que l'une de ces options est plus appropriée?

Merci.

+0

qu'en est-il des paramètres: http://symfony.com/doc/current/configuration.html#the-parameters-key-parameters-variables – lordrhodos

+0

Jetez un oeil aux extensions de twig: http://symfony.com/doc/current/templating/twig_extension.html Une fois l'installation terminée, vous pouvez faire {page_title()} ou {logo()} à partir de n'importe quel modèle. Cela dit, assurez-vous que vous avez vraiment l'exigence pour ce genre de chose. Peut-être serait-il préférable de faire fonctionner votre application avant de s'inquiéter beaucoup de ce genre de chose. – Cerad

+0

sonne comme si vous recherchez des variables globales: http://symfony.com/doc/current/templating/global_variables.html – craigh

Répondre

2

Vous devez créer une fonction brindille et l'utiliser pour renvoyer la valeur souhaitée. Par exemple:

namespace AppBundle\Twig; 

use Symfony\Component\DependencyInjection\ContainerAwareInterface; 
use Symfony\Component\DependencyInjection\ContainerAwareTrait; 
use Symfony\Component\DependencyInjection\ContainerInterface; 

class TwigExtension extends \Twig_Extension implements ContainerAwareInterface 
{ 

    use ContainerAwareTrait; 

    /** 
    * @var ContainerInterface 
    */ 
    protected $container; 

    public function getFunctions() 
    { 
     return array(
      new \Twig_SimpleFunction('parameter', function($name) 
      { 
       try { 
        return $this->container->getParameter($name); 
       } catch(\Exception $exception) { 
        return ""; 
       } 
      }) 
     ); 
    } 

    /** 
    * Returns the name of the extension. 
    * 
    * @return string The extension name 
    */ 
    public function getName() 
    { 
     return 'app.twig.extension'; 
    } 
} 

Cela va créer une fonction appelée parameter et une fois que vous l'appelez dans brindille {{ parameter('my.parameter') }} il retournera le paramètre. Vous devez le charger en tant que service, que vous pouvez faire en ajoutant ce qui suit à votre fichier services.yml:

app.twig.extension: 
    class: AppBundle\Twig\TwigExtension 
    calls: 
     - [setContainer, ["@service_container"]] 
    tags: 
     - { name: twig.extension } 

Des personnes d'expérience personnelle veulent généralement être en mesure de changer certains paramètres. Voilà pourquoi je préfère habituellement pour créer une entité Setting ou Parameter qui ressemblerait à quelque chose comme ceci:

/** 
* Setting 
* 
* @ORM\Table(name="my_parameters") 
* @ORM\Entity(repositoryClass="AppBundle\Repository\ParameterRepository") 
*/ 
class Parameter 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Id 
    * @ORM\Column(name="parameter_id", type="integer") 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="name", type="string", length=255) 
    */ 
    private $name; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="value", type="text", nullable=true) 
    */ 
    private $value; 

    /** 
    * @param string|null $name 
    * @param string|null $value 
    */ 
    public function __construct($name = null, $value = null) 
    { 
     $this->setName($name); 
     $this->setValue($value); 
    } 

    /** 
    * Get id 
    * 
    * @return integer 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * Set name 
    * 
    * @param string $name 
    * 
    * @return Parameter 
    */ 
    public function setName($name) 
    { 
     $this->name = $name; 

     return $this; 
    } 

    /** 
    * Get name 
    * 
    * @return string 
    */ 
    public function getName() 
    { 
     return $this->name; 
    } 

    /** 
    * Set value 
    * 
    * @param string $value 
    * 
    * @return Parameter 
    */ 
    public function setValue($value = null) 
    { 
     $this->value = serialize($value); 

     return $this; 
    } 

    /** 
    * Get value 
    * 
    * @return string 
    */ 
    public function getValue() 
    { 
     $data = @unserialize($this->value); 

     return $this->value === 'b:0;' || $data !== false ? $this->value = $data : null; 
    } 
} 

Puis j'ajouter un CompilerPass qui contribuera à obtenir tous les paramètres de la base de données et de les mettre en cache afin que votre L'application ne génère pas de requêtes SQL inutiles dans la base de données. Cela pourrait ressembler à quelque chose semblable à la classe suivante:

// AppBundle/DependencyInjection/Compiler/ParamsCompilerPass.php 
namespace AppBundle\DependencyInjection\Compiler; 

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; 
use Symfony\Component\DependencyInjection\ContainerBuilder; 

class ParamsCompilerPass implements CompilerPassInterface 
{ 
    public function process(ContainerBuilder $container) 
    { 
     $em  = $container->get('doctrine.orm.default_entity_manager'); 
     $settings = $em->getRepository('AppBundle:Parameter')->findAll(); 

     foreach($settings as $setting) { 
      // I like to prefix the parameters with "app." 
      // to avoid any collision with existing parameters. 
      $container->setParameter('app.'.strtolower($setting->getName()), $setting->getValue()); 
     } 
    } 
} 

Et enfin, dans votre classe de bundle (c.-à-src/AppBundle/AppBundle.php) vous ajoutez le passage du compilateur:

namespace AppBundle; 

use AppBundle\DependencyInjection\Compiler\ParamsCompilerPass; 
use Symfony\Component\DependencyInjection\Compiler\PassConfig; 
use Symfony\Component\DependencyInjection\ContainerBuilder; 
use Symfony\Component\HttpKernel\Bundle\Bundle; 

class AppBundle extends Bundle 
{ 
    public function build(ContainerBuilder $builder) 
    { 
     parent::build($builder); 
     $builder->addCompilerPass(new ParamsCompilerPass(), , PassConfig::TYPE_AFTER_REMOVING); 
    } 
} 

Maintenant, vous pouvez créer un modèle DoctrineFixture pour charger les paramètres que vous utilisez tout le temps. Avec le TwigExtension, vous pourrez toujours appeler le paramètre à partir du modèle de brindille et vous pouvez créer une interface Web pour modifier certains paramètres/paramètres.

+0

Cela semble être la meilleure solution. Avoir les informations stockées dans une base de données serait important pour éditer des valeurs sans changer de code. Je vais mettre en œuvre cette méthode. Je vous remercie. – Daniel

+0

N'oubliez pas d'effacer le cache lorsque vous modifiez une valeur dans la base de données. Avec le 'ParamsCompilerPass' vos paramètres de base de données seront mis en cache. Amusez-vous à coder! :) – tftd