Dans un site on doit pouvoir surcharger : assets, action, view, model, lib, DSN, Config:
<note important>Pour des classes qui porteraient le même nom mais seraient dans différents sites : Quid du cache de l'op-code ??</note>
From there, all you need is a filter, or maybe a preExecute() section in your action (or parent action) to analyse the URI and to read something from your DB or your FS depending on that value. The URI can be pulled out of the sfRequest instance, or failing that just use PHP environment vars.
A filter subdomainFilter
http://forum.symfony-project.org/index.php/m/80813/
Comment stocker le siteId dans la sfConfig ou sfContext ?
javascript, css, images, …
AssetHelper::_compute_public_path(…) utilise $request→getRelativeUrlRoot() pour calculer la base du chemin.
Peut-on hacker ce RelativeUrlRoot() ? Bof, ce hack n'est pas suffisant puisque le fichier dans le siteId est optionel, il faut donc chercher le fichier au 2 endroits.
AssetHelper::_compute_public_path(…) est utilisé par :
1) En fait tout ce boulot est initié dans sfCommonFilter, qui ne fait que ça d'ailleurs.
Il suffit donc de remplacer ce Filter par le notre, et y ajouter les méthodes remplaçant
2) Ou bien c'est à la charge de l'intégrateur de faire le bon lien (/site/$siteId/main.css) mais c'est dommage, et puis si l'on ne veut pas surcharger le template mais seulement le css ça ne fonctionne plus, pareils pour du javascript.
3) Ou encore créer des Helpers genre use_multiSites_stylesheet, use_multiSites_javascript, …
Et on voudrait aussi pouvoir modifier du javascript, du css dynamiquement.
Use routing to serve localized and dynamic JavaScript
Voir doc et code source:
Pour les actions c'est la meme chose que pour les views (sf_module_dirs) sauf que dans un Filter c'est trop tard. Effectivement, Symfony construit l'action avant la chaîne de filtres.
Du coup j'ai déplacé le code du multiSitesFilter dans le multiSitesController avant l'appel à dispatch()…
<note>TODO Avec cette technique c'est la classe sfAction toute entière que l'on surcharge, au lieu de simplement certaines actions… Il me semble avoir lu dans la doc que l'on pouvait découper les actions dans des fichiers individuels et voir aussi sfController→controllerExists(…)</note>
Permettre de surcharger les vues dans un site. Si le site ne surcharge pas la vue, alors celle située dans l'application qui est utilisée.
Le faire pour les vues des modules et aussi pour l'application (layout.php).
Bon, j'ai essayé pas mal de chose, mais il manquait toujours une données… Par exemple dans le filter il n'y a pas le viewName. En gros toutes les données ne sont pas calculées avant d'être dans les classes de View, par exemple il y a aussi le format de sortie qui influ sur le nom du fichier de template.
http://forum.symfony-project.org/index.php/m/81149/#msg_81149
Du coup, il faut plutôt agir sur la configuration.
J'ai trouvé sfApplicationConfiguration→getTemplateDirs($moduleName) qui construit un tableau avec plein de chemin pour les templates. En 1er il regarde dans la config “sf_module_dirs”.
Du coup, j'ai ajouté le sfFilter “multiSitesFilter” qui calcule le chemin de l'éventuel template pour le siteId demandé, et hop !
La Symfony est moins souple, il n'y a pas de tableaux.
Si un site est défini et qu'il contient un folder app/template alors remplacement de la config 'sf_app_template_dir'.
Les “Templates Shortcuts” de SF ($sf_context, $sf_user, …) sont rendus disponibles dans les vues au travers du système d'events. Dans sfViewParameterHolder→toArray() il y a firing de l'event 'template.filter_parameters'. sfContext est abonné à cet event (voir sfContext→initialize()) et y répond via sa méthode filterTemplateParameters(…).
Du coup je fais pareils : dans multiSitesController→dispatch() je l'abonne
sfContext::getInstance()->getEventDispatcher()->connect('template.filter_parameters', array($this, 'getSiteId'));
et la callback getSiteId(…) fournira l'information :
public function getSiteId(sfEvent $event, $parameters) { $parameters['siteId'] = $this->siteId; return $parameters; }
Un peu complexe: les classes des modèles sont liées au schéma de données.
Dans le cas où il suffit d'ajouter des méthodes, c'est simple, il suffit de créer une classe héritière du model de base. Et ajouter dans l'autoload le chemin des modèles pour le site_id.
Par contre s'il y a changement du schéma … ???? - Regénération code ORM dans folder du site ?
Aucun intérêt de surcharger une librairie.
On doit juste ajouter à l'autoloader le répertoire de librairies sur site en cours.
Pas besoin de surcharge pour la config de base.
Par contre pour la configuration du site et les données, un site à son ou ses propres DSN. Ou bien toutes les tables doivents avoir un lien avec le site_id, ce qui me semble bien compliqué.
Il faut mieux étudier le schéma pour voir ce qui est commun et ne l'ai pas.
<note important>
Par contre :
Certains models doivent pouvoir utiliser telles ou telles BdD (emargement, urne, autre…)
</note>
La surcharge de config doit fonctionner comme dans Symfony avec juste un level supplémentaire et dynamique : le site_id.
Je ne sais pas si ça va être possible…
Read :
As far as I know, the i18n:extract still doesn't extract strings for translation inside of the form classes. This is a real limitation for large projects with a lot of different languages.
look at A task to extract i18n labels from a form