Cleanup/Configuration

Cleanup: Configuration

See also: Configuration cleanup for Agavi 1.0.

As it stands, Agavi's configuration system is somewhat of a disaster internally. It's highly flexible in terms of what it can parse, but it lacks some important features and is organized poorly in the filesystem.

Directives

I've always thought the use of directives (%something% being replaced to the corresponding value in AgaviConfig) was a bit of a hack, and an ugly one at that. Rather than use a preg_replace-at-compile-time to replace these, why not simply provide a namespace to reference predefined directives, constants, and the like?

Some examples:

<agd:constant>PDO::ATTR_DEFAULT_FETCH_MODE</agd:constant>
<agd:directive>core.agavi_dir</agd:directive>
<agd:variable>module</agd:variable>
<!-- or -->
<agd:constant name="PDO::ATTR_DEFAULT_FETCH_MODE" />
<agd:directive name="core.agavi_dir" />
<agd:variable name="module" />

<!-- Alternate form for parameters, only necessary when the name of the
     parameter includes a directive/constant -->
<parameter>
  <name><agd:constant>PDO::ATTR_DEFAULT_FETCH_MODE</agd:constant></name>
  <value><agd:constant>PDO::FETCH_OBJ</agd:constant></value>
</parameter>

<parameter name="directory"><agd:directive>core.agavi_dir</agd:directive>/barbeque_hacks</parameter>

<!-- Not sure about these, since they're probably be common in attribute values
     they might not be a good idea -->
<agd:true /> <!-- or --> <agd:yes /> <!-- or --> <agd:on />
<agd:false /> <!-- or --> <agd:no /> <!-- or --> <agd:off />

This would also encourage taking large values out of attributes; attributes should always be short and to the point in my opinion.

I haven't studied this all that much, so if this isn't plausible, I'd love to know and possibly try to figure out something better. But seeing as it's all done at compile time, I don't really think it'd be a huge problem to implement, even if it required a second iteration over the config file.

Regarding Variables

Obviously, variables can't be resolved at compile time. However, we can also streamline that process by turning the input into a simple array of structs:

<parameter name="directory">
  <agd:directive name="core.template_dir" />/modules/<agd:variable name="module" />/hotness
</parameter>

would be represented as

array(
  0 => array(
    'type' => AgaviConfig::T_STRING,
    'value' => '/path/to/my/app/templates/modules/'
  ),
  1 => array(
    'type' => AgaviConfig::T_VARIABLE,
    'value' => 'module'
  ),
  2 => array(
    'type' => AgaviConfig::T_STRING,
    'value' => '/hotness'
  )
)

Easy enough, I think.

Caching

Agavi uses caching independently in both the execution filter and in the configuration system. These methods need to be abstracted to a common API, which for the future can be part of the storage system.

As such, a different organization for the storage system will be necessary. See Cleanup/Storage.

Since Agavi will need to be able to use the cache before it can fully initialize it with context support (the initialization procedures are generated from the configuration), an interface to identify a cache as being "standalone" is necessary. The consensus on the best way to handle this is via an AgaviIStandaloneCacheStorage interface. The unfortunate downside is the method by which the storage will have to be initialized:


$cache = new AgaviFilesystemCacheStorage();
$cache->setParameter('cache_directory', AgaviConfig::get('core.cache_dir') . '/config');
$cache->startup();

// Now the cache can be used normally:
$cache->write('somesuch', '...');
$data = $cache->read('somesuch');

All in all, this is much cleaner than the current static-method-based caching system used in the configuration system. For more information, see Feature/Caching.