February 17, 2012
by sonius
0 comments
I had created I18n table set and all seemed to be working well until I tried to propel:build-schema.
I had lost my attribues:
isI18N: true, i18nTable: page_i18n & isCulture: true
This is how I want my schema to looked in the beginning:
cms:
_attributes: { phpName: Cms, isI18N: true, i18nTable: cms_i18n }
id:
handle: {type: varchar, size: 50}
created_at:
updated_at:
cms_i18n:
id: { type: integer, size: 11, foreignTable: cms, foreignReference: id, required: true, primaryKey: true }
culture: { type: varchar, size: 7, required: true, primaryKey: true, isCulture: true }
content: { phpName: Content, type: LONGVARCHAR, required: true }
Basically how the build-schema work flow works like this
- Execute symfony propel: build-schema
- The sfPropelBuildSchemaTask script will create an schema.xml file from the database
- Then sfPropelBuildSchemaTask will create a schema.yml from the newly created schema.xml before deleting it
The way to fix this problem is to modify the schema.xml before it transformed into the schema.yml
This is how I fixed the problem.
- You need to find and modify the sfPropelBuildSchemaTask.class.php file
- Find: protected function reverseDatabase()
- You will see where they define the yml and the xml path
$xmlSchemaPath = sfConfig::get('sf_config_dir') . '/' . $name . '.xml';
$ymlSchemaPath = sfConfig::get('sf_config_dir') . '/' . $name . '.yml';
- below this you should find an if block. There is no use modifying the xml if it doest exists
if (file_exists($xmlSchemaPath)) {
- Immediately at the start of the ‘if’ block added this code, you may need to modify to fit your situation…
$I18ntables = array();
$schema = file_get_contents($xmlSchemaPath);
$xml = simplexml_load_file($xmlSchemaPath);
//iterate once to get all i18n tables
foreach ($xml->table as $table) {
foreach ($table->attributes() as $attributeskey0 => $attributesvalue1) {
if ($attributeskey0 == 'name') {
if (preg_match("/_i18n/", $attributesvalue1)) {
$I18ntables[] = str_replace('_i18n', '', $attributesvalue1);
}
}
}
}
//iterate again because we dont know the order of the tables
//grab the sister tables and add the new attributes
foreach ($xml->table as $table) {
foreach ($table->attributes() as $attributeskey0 => $attributesvalue1) {
if ($attributeskey0 == 'name') {
if (in_array($attributesvalue1, $I18ntables)) {
$table->addAttribute('isI18N', "true");
$table->addAttribute('i18nTable', strtolower($attributesvalue1 . '_i18n'));
}
//as we are scrolling through the tables again, grab the i18n table
//find the column called 'culture' and add a new attribut to that
if (preg_match("/_i18n/", $attributesvalue1)) {
foreach ($table->children() as $columnkey0 => $columnvalue1) {
if ($columnkey0 == 'column') {
foreach ($columnvalue1->attributes() as $collAttrKey0 => $collAttrValue1) {
if ($collAttrKey0 == 'name') {
if ($collAttrValue1 == 'culture') {
$columnvalue1->addAttribute('isCulture', 'true');
}
}
}
}
}
}
}
}
}
//the schema has changed now so assign it here
$schema = $xml->asXML();
There are a couple of rules you need to know to use my code
- the 2 I18N tables must be named the same , except for the ‘_i18n’ appendment of course
- The column where you set the culture must be named ‘culture’