Details
-
Type:
Bug
-
Status:
Closed
-
Priority:
Major
-
Resolution: Fixed
-
Affects Version/s: 1.2.0-BETA2
-
Fix Version/s: 1.2.0-BETA3
-
Component/s: Schema Files
-
Labels:None
-
Environment:(independent from specific env)
Description
Doctrine allows schema files (schema.yml in my case as symfony user) to define global settings that shall be valid for each class (within the same schema file) to be taken as default unless specified otherwise within the class.
However, once an individual class does specify (even only) one single option, none of the global options are being used anymore at all. This is the current implementation as of in Doctrine_Import_Schema::parseSchema(), line 330.
IMHO this implementation makes the feature of rather little benefit for users, particularly because 'options' is an array, even a nested one since symfony 1.3 did introduce their own options therein ('forms' and 'filters').
Following example:
# global settings, as default for all classes detect_relations: false options: type: innodb collate: utf8_unicode_ci charset: utf8 symfony: form: true filter: true DocumentSource: tableName: dk_doc_source abstract: 'Possible sources for documents (code set)' options: symfony: { filter: false } actAs: Timestampable: ~ columns: name: { type: string(63), notnull: true } description: { type: string(255) } DocumentType: tableName: dk_doc_type abstract: 'Allowed types for documents' options: symfony: { form: false, filter: false } actAs: Timestampable: ~ columns: name: { type: string(63), notnull: true } description: { type: string(255) } DocumentTag: tableName: dk_doc_tag abstract: 'Tags for documents' actAs: Timestampable: ~ columns: name: { type: string(63), notnull: true } description: { type: string(255) }
After an import with the current implementation, the classes end up having the following options:
- DocumentSource:
options: # taken from the specific class, no global setting was taken over symfony: { filter: false } - DocumentType:
options: # taken from the specific class , again no global setting was taken over symfony: { form: false, filter: false } - DocumentTag:
options: # taken from the globals type: innodb collate: utf8_unicode_ci charset: utf8 symfony: form: true filter: true
As a developer I originally understood the feature in that DocumentSource and DocumentType would still get the global option settings like collate, charset etc without having to repeat them again and again.
- Like e.g. for DocumentSource:
options: # global and class specific options brought together type: innodb collate: utf8_unicode_ci charset: utf8 symfony: form: true filter: false
--> is the effect of the current implementation is intentional?
I.e. I wish to raise the question: shall globals...
- only be applicable to an individual class if the latter doesn't specifiy any option at all? (principle of XOR), or
- complement the class' individual options, i.e. the developer defines the desired default options as globals, and specifies any difference from that in the individual class? (principle of inheritance).
IMHO as a user of Doctrine & Symfony, I cleary prefer the inheritance principle (2).
A thinkable solution is to use array_replace_recursive() or a similar function instead of a simple assignment:
CURRENT:
// Apply the globals to each table if it does not have a custom value set already
foreach ($array as $className => $table) {
foreach ($globals as $key => $value) {
if ( !isset($array[$className][$key])) {
$array[$className][$key] = $value;
}
}
}
PATCH:
// Apply the globals to each table if it does not have a custom value set already
foreach ($array as $className => $table) {
foreach ($globals as $key => $value) {
$array[$className][$key] = array_replace_recursive($value, $array[$className][$key]); // do inherit the global settings
}
}
I haven't yet tried out this patch nor even tested it, since anything first depends from a clarification on the common expectations from the feature of globals in schema files.
Cheers, RAPHAEL
PS. update: I created a corresponding issue in Symfony trac.