In Symfony 1.4, is it possible for one to define a custom config file (e.g. my_config.yml) that allows cascading; for instance, having a global custom config file and a module level analogue?
Yes.
Define a config handler in config_handlers.yml. It'll probably look like:
config/my_config.yml:
class: myConfigHandler
Write your config handler. You can look at many of the other config handlers in lib/config for examples. You'll likely want to extend sfYamlConfigHandler.
To access your config values:
sfContext::getInstance()->getConfigCache()->checkConfig('/config/my_config.yml');
Related
I have a line in a sample Symfony app that reads:
$seo = $this->get('sonata.seo.page');
However the config.yml file reads:
sonata_seo:
page:
metas:
property: ... etc ...
I've read http://symfony.com/doc/current/service_container.html but I'm not clear how exactly the get('sonata.seo.page') works. Does it somehow equate to the key / values in the config file? i.e. does the underscore in sonata_seo get magically changed to a period?
You cannot access values in config.yml direcly, like values in parameters.yml.
That file can store configuration values for bundles thought.
Read more here
What it is 'getting' in this instance, usually within a controller action, is a Symfony Service.
In this instance, sonata.seo.page is a reference to a service, setup in the sonata-project/seo-bundle, which returns an instance of the SeoPage class. Normally, this information is set within your local configuration file (config.yml, or a file that it includes), but the service returns the class that allows you to change the values at runtime.
No service are (directly) defined inside config.yml. It's the bundle that define the service. With $this->get('sonata.seo.page'); you get those.
The config.yml file it's just used to customize the bundles.
The SeoBundle defines the semantic configuration section sonata_seo from config.yml and registers the own Extension of DI container.
Extension implements the load() method. Configuration values from sonata_seo are passed as its first argument.
Method loads various resources including service definition from Resources/config/service.xml:
<parameter key="sonata.seo.page.default.class">Sonata\SeoBundle\Seo\SeoPage</parameter>
...
<service id="sonata.seo.page.default" class="%sonata.seo.page.default.class%"/>
Next, extension set up sonata.seo.page definition with given configuration parameters.
This process will be invoked during the container compilation, when the service definition and its settings will be embedded in the container. Result of this process you can find in the dumped container in the cache directory.
This is a typical scheme of work for the Symfony bundles: define the configuration structure, make an extension, set up the services.
I was wondering what order does Symfony use when loading config files, and I can't seem to find the answer. The config is later flattened using processConfiguration method from Extension class.
Symfony loads app/config/config.yml first;
config_{environment}.yml afterwards for it to be able to overwrite default settings;
afterwards all bundle configuration is loaded in the order of the bundles being registered in app/AppKernel.php.
Is it possible to define a different Auth config for a bundle ? application/config/auth.php is default for bundles as well but I need to use different auth modules for different bundles of the system.
Also, creating a new one on the BUNDLE/config/ folder doesn't affect anything. So, it loads the default one in any case.
The short answer is that you cannot... Neither Auth nor Config were designed to be extended per bundle.
The long answer is that you could use your bundle's start.php file to override each config setting, for example
// bundles/my-bundle/start.php
Config::set('auth.driver', 'fluent');
Config::set('auth.table', 'my_users');
how can I autoload my modules' lib folders in my Symfony 1.4 projects? Probably you know that problem:
If I create plugins, I store base-classes for my modules' actions in the lib folder. Each actions-class stored in actions/actions.class.php inherits from that base-class. This allows overriding the plugin-actions at project level:
myModule
actions
actions.class.php
lib
BasemyModuleActions.class.php
But unfortunately, Symfony doesn't autoload BasemyModuleActions and you have to include the respective file manually:
require_once(dirname(__FILE__) .'/lib/BasemyModuleActions.class.php');
class myModuleActions extends BasemyModuleActions
{
}
This works, but it is really annoying. Moreover I want to put more files in the modules' lib folders, e.g. forms.
Is there a way to add those directories to the autoloader?
Storing forms in their related modules would good for me, since I only reuse the same form for different modules in few cases.
Is your solution also compatible with the Doctrine form-generation task? I.e. is Symfony aware of the existing form, or will it be created again if it is moved out of lib/form/doctrine? (No problem, if you can't answer that. But it would be nice if you know a workaround in this case)
Take a look at this page:
http://www.symfony-project.org/reference/1_4/en/14-Other-Configuration-Files
It describes an autoload.yml file, which configures symfony to look for classes in different directories.
Symfony wouldn't autoload my /apps/app_name/lib/*.* classes, but does so after creating /config/autoload.yml file with the following content:
autoload:
# project
project:
name: project
path: %SF_LIB_DIR%
recursive: true
exclude: [model, symfony]
project_model:
name: project model
path: %SF_LIB_DIR%/model
recursive: true
# application
application:
name: application
path: %SF_APP_LIB_DIR%
recursive: true
modules:
name: module
path: %SF_APP_DIR%/modules/*/lib
prefix: 1
recursive: true
Which the above page describes as the default config.
As i understand it this is a chicken and egg issue with the autoloader and main controller flow.
The prefix: 1 in the default autoload.yml indicates that these classes are only available to be autoloaded if 'in' the current module.
The way the current module is determined is by looking at the actionStack.
The module/action is added to the actionStack after checking to see if it exists.
Unfortunately to determine if an action exists symfony loads the actions.class.php
Hence you need to have the explicit, require_once.
If you get rid of the prefix: 1 and your module is part of your application (not loaded from a plugin) you will not need the require once.
If the module is part of a plugin, you would need to mess with sfPluginConfiguration to have it load the appropriate classes without prefix.
Both methods are problematic as there could be clashes between class names in various modules.
Yii framework's config/main.php file can be overwritten by a local.php configuration file via an array_merge. This allows me to set different database connections and other parameters specific to production, QA, and development environments.
Yii also allows me to run commands in the command line. It uses a config/console.php file. Is there a way I can set up a local console config file in the same way that will override the main console config depending on the environment?
Hmm, that's an interesting way of doing overriding the config. But it looks like you could just modify console.php in the same way you did the main.php (add local_config function to console.php and point it to console-local.php).