sfActsAsVersionablePlugin: sfPropelVersionableBehaviorPlugin.patch

File sfPropelVersionableBehaviorPlugin.patch, 32.4 kB (added by piers.warmers, 10 months ago)
  • sfPropelVersionableBehaviorPlugin/test/unit/PropelVersionableBehaviorTest.php

    old new  
    5656$test_class_version_column = sfConfig::get('app_sfPropelVersionableBehaviorPlugin_test_version_column', 'version'); 
    5757$test_class_title_column = sfConfig::get('app_sfPropelVersionableBehaviorPlugin_test_title_column', 'title'); 
    5858 
     59$titleSetMethod = forgeMethodName('set', $test_class_title_column); 
     60$titleGetMethod = forgeMethodName('get', $test_class_title_column); 
    5961 
     62$versionSetMethod = forgeMethodName('set', $test_class_version_column); 
     63$versionGetMethod = forgeMethodName('get', $test_class_version_column); 
     64 
     65$createdBySetMethod = forgeMethodName('set', 'created_by'); 
     66$createdByGetMethod = forgeMethodName('get', 'created_by'); 
     67 
     68$commentSetMethod = forgeMethodName('set', 'comment'); 
     69$commentGetMethod = forgeMethodName('get', 'comment'); 
     70 
     71 
    6072// create a new test browser 
    6173$browser = new sfTestBrowser(); 
    6274$browser->initialize(); 
     
    7789  'version'  => $test_class_version_column 
    7890)))); 
    7991 
    80 $t = new lime_test(49, new lime_output_color()); 
     92$t = new lime_test(53, new lime_output_color()); 
    8193 
    8294// save() 
    8395$t->diag('save()'); 
    8496 
    8597$r = _create_resource(); 
    86 $r->setByName($test_class_title_column, 'V1', BasePeer::TYPE_FIELDNAME); 
     98$r->$titleSetMethod('V1'); 
    8799$r->save(); 
    88 $t->is($r->getByName($test_class_version_column, BasePeer::TYPE_FIELDNAME), 1, 'save() initializes the version number to 1 for new objects'); 
     100$t->is($r->$versionGetMethod(), 1, 'save() initializes the version number to 1 for new objects'); 
    89101 
    90102$c = new Criteria(); 
    91103$c->add(ResourceVersionPeer::RESOURCE_ID, $r->getPrimaryKey()); 
    92104$c->add(ResourceVersionPeer::RESOURCE_NAME, get_class($r)); 
    93 $c->add(ResourceVersionPeer::NUMBER, $r->getByName($test_class_version_column, BasePeer::TYPE_FIELDNAME)); 
     105$c->add(ResourceVersionPeer::NUMBER, $r->$versionGetMethod()); 
    94106$version = ResourceVersionPeer::doSelectOne($c); 
    95107$t->isnt($version, null, 'save() creates a new version of resource in database'); 
    96108foreach ($version->getResourceAttributeVersions() as $attrib_version) 
     
    98110  $getter = sprintf('get%s', $attrib_version->getAttributeName()); 
    99111  $t->is($attrib_version->getAttributeValue(), $r->$getter(), 'save() creates a new version of resource in database with appropriate parameters'); 
    100112} 
    101 $r->setByName($test_class_title_column, 'V2', BasePeer::TYPE_FIELDNAME); 
     113$r->$titleSetMethod('V2'); 
    102114$r->save(); 
    103 $t->is($r->getByName($test_class_version_column, BasePeer::TYPE_FIELDNAME), 2, 'save() increments the version number'); 
     115$t->is($r->$versionGetMethod(), 2, 'save() increments the version number'); 
    104116 
     117 
     118 
    105119// getLastResourceVersion() and getCurrentResourceVersion() 
    106120$t->diag('getLastResourceVersion() and getCurrentResourceVersion()'); 
    107121 
    108 $t->is($r->getLastResourceVersion()->getResourceInstance()->getByName($test_class_title_column, BasePeer::TYPE_FIELDNAME), 'V2', 'getLastResourceVersion() returns last version of resource'); 
    109 $t->is($r->getCurrentResourceVersion()->getResourceInstance()->getByName($test_class_title_column, BasePeer::TYPE_FIELDNAME), 'V2', 'getCurrentResourceVersion() returns current version of resource'); 
     122$t->is($r->getLastResourceVersion()->getResourceInstance()->$titleGetMethod(), 'V2', 'getLastResourceVersion() returns last version of resource'); 
     123$t->is($r->getCurrentResourceVersion()->getResourceInstance()->$titleGetMethod(), 'V2', 'getCurrentResourceVersion() returns current version of resource'); 
    110124$r->toVersion(1); 
    111 $t->is($r->getLastResourceVersion()->getResourceInstance()->getByName($test_class_title_column, BasePeer::TYPE_FIELDNAME), 'V2', 'getLastResourceVersion() returns last version of resource'); 
    112 $t->is($r->getCurrentResourceVersion()->getResourceInstance()->getByName($test_class_title_column, BasePeer::TYPE_FIELDNAME), 'V1', 'getCurrentResourceVersion() returns current version of resource'); 
     125$t->is($r->getLastResourceVersion()->getResourceInstance()->$titleGetMethod(), 'V2', 'getLastResourceVersion() returns last version of resource'); 
     126$t->is($r->getCurrentResourceVersion()->getResourceInstance()->$titleGetMethod(), 'V1', 'getCurrentResourceVersion() returns current version of resource'); 
    113127$r->toVersion(2); 
    114128 
    115129// setVersionComment() and setVersionUpdatedBy 
    116130$t->diag('setVersionComment() and setVersionCreatedBy'); 
    117131 
    118132$r2 = _create_resource(); 
    119 $r2->setByName($test_class_title_column, 'v0', BasePeer::TYPE_FIELDNAME); 
     133$r2->$titleSetMethod('v0'); 
    120134$r2->setVersionCreatedBy('foo'); 
    121135$r2->setVersionComment('bar'); 
    122136$r2->save(); 
     137 
    123138$r3 = call_user_func(array(_create_resource()->getPeer(), 'retrieveByPk'), $r2->getPrimaryKey()); 
    124139$t->is($r2->getCurrentResourceVersion()->getCreatedBy(), 'foo', 'setVersionCreatedBy() defines the author name to be saved in the ResourceVersion object'); 
    125140$t->is($r2->getVersionCreatedBy(), 'foo', 'getVersionCreatedBy() returns the creation date of the revision'); 
     
    127142$t->is($r2->getCurrentResourceVersion()->getComment(), 'bar', 'setVersionComment() defines the comment to be saved in the ResourceVersion object'); 
    128143$t->is($r2->getVersionComment(), 'bar', 'getVersionComment() is a proxy method for getCurrentResourceVersion()->getComment()'); 
    129144$t->is($r3->getVersionComment(), 'bar', 'getVersionComment() is a proxy method for getCurrentResourceVersion()->getComment()'); 
    130 $r2->setByName($test_class_title_column, 'v0', BasePeer::TYPE_FIELDNAME); 
     145$r2->$titleSetMethod('v0'); 
    131146$r2->save(); 
    132147$resourceVersion = $r2->getCurrentResourceVersion(); 
    133148$t->is($resourceVersion->getCreatedBy(), '', 'setVersionCreatedBy() only affects the next version saved'); 
     
    135150 
    136151// conditional versioning 
    137152$t->diag('conditional versioning'); 
    138 $r->setByName($test_class_title_column, 'do not version me', BasePeer::TYPE_FIELDNAME); 
     153$r->$titleSetMethod('do not version me'); 
    139154$r->save(); 
    140 $t->is($r->getByName($test_class_version_column, BasePeer::TYPE_FIELDNAME), 2, 'save() hooks can be deactivated by a versionConditionMet() method'); 
     155$t->is($r->$versionGetMethod(), 2, 'save() hooks can be deactivated by a versionConditionMet() method'); 
    141156 
    142157sfConfig::set('app_sfPropelVersionableBehaviorPlugin_auto_versioning', false); 
    143 $r->setByName($test_class_title_column, 'do not version me either, but for another reason', BasePeer::TYPE_FIELDNAME); 
     158$r->$titleSetMethod('do not version me either, but for another reason'); 
    144159$r->save(); 
    145 $t->is($r->getByName($test_class_version_column, BasePeer::TYPE_FIELDNAME), 2, 'save() hooks can be deactivated by changing app_sfPropelVersionableBehaviorPlugin_auto_versioning to off'); 
     160$t->is($r->$versionGetMethod(), 2, 'save() hooks can be deactivated by changing app_sfPropelVersionableBehaviorPlugin_auto_versioning to off'); 
    146161sfConfig::set('app_sfPropelVersionableBehaviorPlugin_auto_versioning', true); 
    147162 
    148163// addVersion() 
    149164$t->diag('addVersion()'); 
    150165sfConfig::set('app_sfPropelVersionableBehaviorPlugin_auto_versioning', false); 
    151 $r->setByName($test_class_title_column, 'this time, please version me, but manually', BasePeer::TYPE_FIELDNAME); 
     166$r->$titleSetMethod('this time, please version me, but manually'); 
    152167$r->addVersion(); 
    153168$r->save(); 
    154 $t->is($r->getByName($test_class_version_column, BasePeer::TYPE_FIELDNAME), 3, 'addVersion() creates a new version even when app_sfPropelVersionableBehaviorPlugin_auto_versioning is set to off'); 
     169$t->is($r->$versionGetMethod(), 3, 'addVersion() creates a new version even when app_sfPropelVersionableBehaviorPlugin_auto_versioning is set to off'); 
    155170 
    156171$r2 = _create_resource(); 
    157172try 
    158173{ 
    159   $r2->setByName($test_class_title_column, 'v0', BasePeer::TYPE_FIELDNAME); 
     174  $r2->$titleSetMethod('v0'); 
    160175  $r2->addVersion(); 
    161176  $r2->save(); 
    162177  $t->pass('calling addVersion() on an unsaved object does not throw an exception'); 
    163178} catch (Exception $e) { 
    164179  $t->fail('calling addVersion() on an unsaved object does not throw an exception'); 
    165180} 
    166 $t->is($r2->getLastResourceVersion()->getNumber(), 1, 'addVersion() creates a version object even on unsaved objects'); 
     181$t->is($r2->getLastResourceVersion()->getNumber(), 1, 'getLastResourceVersion() returns the correct version'); 
    167182 
    168 $r2->setByName($test_class_title_column, 'v1', BasePeer::TYPE_FIELDNAME); 
     183$r2->$titleSetMethod('v1'); 
    169184$r2->setVersionCreatedBy('author2'); 
    170185$r2->setVersionComment('baz'); 
    171186$r2->addVersion(); 
     
    174189$t->is($resourceVersion->getCreatedBy(), 'author2', 'addVersion() allows for use of setVersionCreatedBy()'); 
    175190$t->is($resourceVersion->getComment(), 'baz', 'addVersion() allows for use of setVersionComment()'); 
    176191 
    177 $r2->setByName($test_class_title_column, 'v2', BasePeer::TYPE_FIELDNAME); 
     192$r2->$titleSetMethod('v2'); 
    178193$r2->addVersion('author3', 'bazz'); 
    179194$r2->save(); 
    180195$resourceVersion = $r2->getCurrentResourceVersion(); 
    181196$t->is($resourceVersion->getCreatedBy(), 'author3', 'addVersion() accepts a version author name as first parameter'); 
    182197$t->is($resourceVersion->getComment(), 'bazz', 'addVersion() accepts a version comment as second parameter'); 
    183198 
    184  
    185199sfConfig::set('app_sfPropelVersionableBehaviorPlugin_auto_versioning', true); 
    186200try 
    187201{ 
     
    195209$t->diag('toVersion()'); 
    196210 
    197211$r->toVersion(1); 
    198 $t->is($r->getByName($test_class_version_column, BasePeer::TYPE_FIELDNAME), 1, 'toVersion() sets resource version to appropriate values'); 
    199 $t->is($r->getByName($test_class_title_column, BasePeer::TYPE_FIELDNAME), 'V1', 'toVersion() sets resource attributes to appropriate values'); 
     212$t->is($r->$versionGetMethod(), 1, 'toVersion() sets resource version to appropriate values'); 
     213$t->is($r->$titleGetMethod(), 'V1', 'toVersion() sets resource attributes to appropriate values'); 
    200214$r->save(); 
    201 $t->is($r->getByName($test_class_version_column, BasePeer::TYPE_FIELDNAME), 4, 'save() correctly increments version number after toVersion() call'); 
     215$t->is($r->$versionGetMethod(), 4, 'save() correctly increments version number after toVersion() call'); 
    202216try 
    203217{ 
    204218  $r->toVersion(0); 
     
    210224// getAllResourceVersions() 
    211225$t->diag('getAllResourceVersions()'); 
    212226 
    213 $r->setByName($test_class_title_column, 'V5', BasePeer::TYPE_FIELDNAME); 
     227$r->$titleSetMethod('V5'); 
    214228$r->save(); 
    215229$all_versions = $r->getAllResourceVersions(); 
    216230$target_versions = array('V1', 'V2', 'this time, please version me, but manually', 'V1', 'V5'); 
     
    218232$versions_titles = array(); 
    219233foreach($all_versions as $v) 
    220234{ 
    221   $versions_titles[] = $v->getResourceInstance()->getByName($test_class_title_column, BasePeer::TYPE_FIELDNAME); 
     235  $versions_titles[] = $v->getResourceInstance()->$titleGetMethod(); 
    222236} 
    223237$t->is($versions_titles, $target_versions, 'getAllResourceVersions() returns the right versions'); 
    224238 
     239 
     240 
    225241// getAllVersions() 
    226242$t->diag('getAllVersions()'); 
    227243$all_object_versions = $r->getAllVersions(); 
     
    230246$versions_versions = array(); 
    231247foreach($all_object_versions as $obj) 
    232248{ 
    233   $versions_titles[] = $obj->getByName($test_class_title_column, BasePeer::TYPE_FIELDNAME); 
     249  $versions_titles[] = $obj->$titleGetMethod(); 
    234250  $versions_versions[] = $obj->getVersion(); 
    235251} 
    236252$t->is($versions_titles, $target_versions, 'getAllVersions() returns the right versions'); 
     
    263279 
    264280sfConfig::set('app_sfPropelVersionableBehaviorPlugin_auto_versioning', false); 
    265281$r = _create_resource(); 
    266 $r->setByName($test_class_title_column, 'v1', BasePeer::TYPE_FIELDNAME); 
     282$r->$titleSetMethod('v1'); 
    267283$r->addVersion('author1'); 
    268284$r->save(); 
    269 $r->setByName($test_class_title_column, 'v2', BasePeer::TYPE_FIELDNAME); 
     285$r->$titleSetMethod('v2'); 
    270286$r->addVersion(null, 'because you\'re worth it'); 
    271287$r->save(); 
    272 $r->setByName($test_class_title_column, 'v3', BasePeer::TYPE_FIELDNAME); 
     288$r->$titleSetMethod('v3'); 
    273289$r->addVersion('author2', 'minor corrections'); 
    274290$r->save(); 
    275 $r->setByName($test_class_title_column, 'v4', BasePeer::TYPE_FIELDNAME); 
     291$r->$titleSetMethod('v4'); 
    276292$r->addVersion(); 
    277293$r->save(); 
    278294$versionAuthors = array(); 
     
    293309$t->diag('#1563 : sfPropelVersionableBehaviorPlugin does not create a version if YourClass::versionConditionMet() is not found'); 
    294310 
    295311$r = _create_resource(); 
    296 $r->setByName($test_class_title_column, 'v1', BasePeer::TYPE_FIELDNAME); 
     312$r->$titleSetMethod('v1'); 
    297313$r->save(); 
    298314sfPropelVersionableBehavior::setVersionConditionMethod('nonExistentMethod'); 
    299 $r->setByName($test_class_title_column, 'do not version me', BasePeer::TYPE_FIELDNAME); 
     315$r->$titleSetMethod('do not version me'); 
    300316$r->save(); 
    301317$t->is($r->getLastResourceVersion()->getNumber(), 2, 'save() creates a version even if YourClass::versionConditionMet() is not found'); 
    302318 
     
    307323try 
    308324{ 
    309325  $r->save(); 
    310   $r->setByName($test_class_title_column, '#1564', BasePeer::TYPE_FIELDNAME); 
     326  $r->$titleSetMethod('#1564'); 
    311327  $r->save(); 
    312328  $t->pass('save() does not crash when creating a new version if no prior version exists and object is not new'); 
    313329} catch (Exception $e) { 
    314   $t->fail('save() does not crash when creating a new version if no prior version exists and object is not new'); 
     330  $t->fail('save() crashes when creating a new version if no prior version exists and object is not new'); 
    315331} 
    316332 
     333 
     334$r5 = _create_resource(); 
     335 
     336if(method_exists($r5, "setCulture")) 
     337{ 
     338 
     339  $r5->setCulture('en'); 
     340  $r5->$titleSetMethod('V1 C-EN'); 
     341   
     342  $r5->setCulture('fr'); 
     343  $r5->$titleSetMethod('V1 C-FR'); 
     344  $r5->save(); 
     345   
     346  $r5->setCulture('en'); 
     347  $r5->$titleSetMethod('V2 C-EN'); 
     348   
     349  $r5->setCulture('fr'); 
     350  $r5->$titleSetMethod('V2 C-FR'); 
     351  $r5->save(); 
     352   
     353  $r5->toVersion(1); 
     354  $r5->setCulture('en'); 
     355  $t->is($r5->$titleGetMethod(), 'V1 C-EN', 'toVersion() sets resource attributes to appropriate values'); 
     356   
     357   
     358} 
     359 
     360 
     361 
     362 
     363 
     364 
    317365// Helper functions 
    318366 
    319367/** 
     368 * Return an accessor or setter method name 
     369 *  
     370 * @return  string 
     371 */ 
     372function forgeMethodName($prefix, $column) 
     373{ 
     374  return sprintf('%s%s', $prefix, sfInflector::camelize($column)); 
     375} 
     376 
     377/** 
    320378 * Resource creation "abstraction". 
    321379 *  
    322380 * @return  BaseObject 
  • sfPropelVersionableBehaviorPlugin/config/schema.yml

    old new  
    1414 
    1515  resource_attribute_version: 
    1616    id: 
     17    culture:            { type: varchar(7), default: "" } 
    1718    resource_version_id:  { type: integer, size: 11, required: true, foreignTable: resource_version, foreignReference: id, onDelete: cascade } 
    1819    attribute_name:       { type: varchar, size: 255, required: true } 
    1920    attribute_value:      { type: longvarchar } 
  • sfPropelVersionableBehaviorPlugin/lib/model/ResourceVersion.php

    old new  
    11<?php 
    22/* 
    33 * This file is part of the sfPropelActAsNestedSetBehavior package. 
    4  *  
     4 * 
    55 * (c) 2006-2007 Tristan Rivoallan <tristan@rivoallan.net> 
    6  *  
     6 * 
    77 * For the full copyright and license information, please view the LICENSE 
    88 * file that was distributed with this source code. 
    99 */ 
    10   
     10 
    1111/** 
    1212 * Subclass for representing a row from the 'resource_version' table. 
    1313 * 
    1414 *  * @package plugins.sfPropelVersionableBehaviorPlugin.lib.model 
    15  */  
     15 */ 
    1616class ResourceVersion extends BaseResourceVersion 
    1717{ 
    1818 
    1919  /** 
    2020   * Populates version properties and creates necessary entries in the resource_attribute_version table. 
    21    *  
     21   * 
    2222   * @param      BaseObject    $resource 
    2323   */ 
    2424  public function populateFromObject(BaseObject $resource) 
     
    2626    $this->setResourceId($resource->getPrimaryKey()); 
    2727    $this->setResourceName(get_class($resource)); 
    2828    $this->setNumber($resource->getVersion()); 
    29      
     29    //$this->setCreatedBy($resource->getVersionCreatedBy()); 
     30    //$this->setComment($resource->getVersionComment()); 
     31 
    3032    foreach ($resource->getPeer()->getFieldNames() as $attribute_name) 
    3133    { 
    3234      $getter = sprintf('get%s', $attribute_name); 
     
    3537      $attribute_version->setAttributeValue($resource->$getter()); 
    3638      $this->addResourceAttributeVersion($attribute_version); 
    3739    } 
     40 
     41    // Handle any i18n data 
     42    if(method_exists($resource, "getCulture")) 
     43    { 
     44      $resourcePeer = $resource->getPeer()->retrieveByPk($resource->getId()); 
     45       
     46      if($resourcePeer) 
     47      { 
     48        $getI18ns = sprintf('get%si18ns', get_class($resource)); 
     49        $localizations = $resourcePeer->$getI18ns(); 
     50        foreach ($localizations as $l) 
     51        { 
     52          $resource->setCulture($l->getCulture()); 
     53          foreach ($l->getPeer()->getFieldNames() as $attribute_name) 
     54          { 
     55            $getter = sprintf('get%s', $attribute_name); 
     56            $attribute_version = new ResourceAttributeVersion(); 
     57            $attribute_version->setCulture($l->getCulture()); 
     58            $attribute_version->setAttributeName($attribute_name); 
     59            $attribute_version->setAttributeValue($resource->$getter()); 
     60            $this->addResourceAttributeVersion($attribute_version); 
     61          } 
     62        } 
     63      } 
     64    } 
    3865  } 
    3966 
    4067  /** 
    4168   * Returns resource instance corresponding to version. 
    42    *  
     69   * 
    4370   * @return   BaseObject 
    4471   */ 
    4572  public function getResourceInstance() 
     
    4976  } 
    5077 
    5178} 
     79 
     80// $change_columns = array('created_details' => ResourceVersionPeer::NOTES, 'updated_details' => ResourceVersionPeer::NOTES); 
     81 
     82// sfPropelBehavior::add('ResourceVersion', array('changeNotes' => array('columns' => $change_columns))); 
  • sfPropelVersionableBehaviorPlugin/lib/sfPropelVersionableBehavior.class.php

    old new  
    11<?php 
    22/* 
    33 * This file is part of the sfPropelVersionableBehaviorPlugin package. 
    4  *  
     4 * 
    55 * (c) 2006-2007 Tristan Rivoallan <tristan@rivoallan.net> 
    6  *  
     6 * 
    77 * For the full copyright and license information, please view the LICENSE 
    88 * file that was distributed with this source code. 
    99 */ 
    1010 
    1111/** 
    1212 * This behavior adds versioning capabilities to any Propel object. 
    13  *  
     13 * 
    1414 * To enable this behavior add this after Propel stub class declaration : 
    15  *  
     15 * 
    1616 * <code> 
    1717 *   $columns_map = array('version'  => MyClassPeer::VERSION); 
    18  *  
     18 * 
    1919 *   sfPropelBehavior::add('MyClass', array('versionable' => array('columns' => $columns_map))); 
    2020 * </code> 
    21  *  
     21 * 
    2222 * Column map values signification : 
    23  *  
     23 * 
    2424 *  - version : Model column holding resource's current version number 
    25  *  
     25 * 
    2626 * @author Tristan Rivoallan <tristan@rivoallan.net> 
    2727 * @author Francois Zaninotto <francois.zaninotto@symfony-project.com> 
    2828 */ 
     
    3131 
    3232  /** 
    3333   * Holds name of the method used for conditional versioning. 
    34    *  
     34   * 
    3535   * @var string 
    3636   */ 
    3737  protected static $condition_method; 
     38   
     39  /** 
     40   * Holds holds the propel save count for i18n objects. 
     41   * 
     42   * @var string 
     43   */ 
     44  protected $i18n_save_count = 0; 
    3845 
    39 # ---- PUBLIC API 
     46  # ---- PUBLIC API 
    4047 
    4148  /** 
    4249   * Sets resource properties to their value for requested version. 
    43    *  
     50   * 
    4451   * @param      BaseObject    $resource 
    4552   * @param      integer       $version_num 
    4653   * @throws     Exception     When requested version does not exist 
    4754   */ 
    48   public function toVersion(BaseObject $resource, $version_num
     55  public function toVersion(BaseObject $resource, $version_num, $cultures = array()
    4956  { 
    5057    $c = new Criteria(); 
    5158    $c->add(ResourceVersionPeer::RESOURCE_ID, $resource->getPrimaryKey()); 
    5259    $c->add(ResourceVersionPeer::RESOURCE_NAME, get_class($resource)); 
    5360    $c->add(ResourceVersionPeer::NUMBER, $version_num); 
    5461    $version = ResourceVersionPeer::doSelectOne($c); 
    55      
     62 
    5663    if (is_null($version)) 
    5764    { 
    5865      $msg = sprintf('Resource "%s" has no version "%d"', $resource->getPrimaryKey(), $version_num); 
    5966      throw new Exception($msg); 
    6067    } 
    61      
    62     $resource = self::populateResourceFromVersion($resource, $version); 
     68 
     69    $resource = self::populateResourceFromVersion($resource, $version, $cultures); 
    6370  } 
    64   
     71 
    6572  /** 
    6673   * Returns last version of resource. 
    67    *  
     74   * 
    6875   * @param      BaseObject    $resource 
    6976   * @return     ResourceVersion 
    7077   */ 
     
    7481    $c->add(ResourceVersionPeer::RESOURCE_ID, $resource->getPrimaryKey()); 
    7582    $c->add(ResourceVersionPeer::RESOURCE_NAME, get_class($resource)); 
    7683    $c->addDescendingOrderByColumn(ResourceVersionPeer::NUMBER); 
    77      
     84 
    7885    return ResourceVersionPeer::doSelectOne($c); 
    7986  } 
    8087 
    8188  /** 
    8289   * Returns current version of resource. 
    83    *  
     90   * 
    8491   * @param      BaseObject    $resource 
    8592   * @return     ResourceVersion 
    8693   */ 
     
    9097    $c->add(ResourceVersionPeer::RESOURCE_ID, $resource->getPrimaryKey()); 
    9198    $c->add(ResourceVersionPeer::RESOURCE_NAME, get_class($resource)); 
    9299    $c->add(ResourceVersionPeer::NUMBER, $resource->getVersion()); 
    93      
     100 
    94101    return ResourceVersionPeer::doSelectOne($c); 
    95102  } 
    96103    
    97104  /** 
    98105   * Returns all ResourceVersion instances related to the object, ordered by version asc. 
    99    *  
     106   * 
    100107   * @param      BaseObject   $resource 
    101108   * @return     array        List of ResourceVersion objects 
    102109   */ 
     
    106113    $c->add(ResourceVersionPeer::RESOURCE_ID, $resource->getPrimaryKey()); 
    107114    $c->add(ResourceVersionPeer::RESOURCE_NAME, get_class($resource)); 
    108115    $c->addAscendingOrderByColumn(ResourceVersionPeer::NUMBER); 
    109      
     116 
    110117    return ResourceVersionPeer::doSelect($c); 
    111118  } 
    112119 
    113120  /** 
    114121   * Returns all ResourceVersion instances related to the object, ordered by version asc. 
    115    *  
     122   * 
    116123   * @param      BaseObject   $resource 
    117124   * @return     array        List of BaseObject objects 
    118125   */ 
     
    124131    $c->addAscendingOrderByColumn(ResourceVersionPeer::NUMBER); 
    125132    $c->addJoin(ResourceAttributeVersionPeer::RESOURCE_VERSION_ID, ResourceVersionPeer::ID); 
    126133    $attributes = ResourceAttributeVersionPeer::doSelect($c); 
    127      
     134 
    128135    $objects = array(); 
    129136    $object = null; 
    130137    $class= get_class($resource); 
     
    142149      } 
    143150      $attrib_name = $attribute->getAttributeName(); 
    144151      $setter = sprintf('set%s', $attrib_name); 
    145        
     152 
    146153      if (!method_exists($resource, $setter)) 
    147154      { 
    148         $msg = sprintf('Impossible to set attribute "%s" on resource "%s"',  
    149                       $attrib_name, get_class($resource)); 
     155        $msg = sprintf('Impossible to set attribute "%s" on resource "%s"', 
     156        $attrib_name, get_class($resource)); 
    150157        throw new Exception($msg); 
    151158      } 
    152159      $object->$setter($attribute->getAttributeValue()); 
    153        
     160 
    154161    } 
    155162    $objects[] = $object; 
    156      
     163 
    157164    return $objects; 
    158165  } 
    159    
     166 
    160167  /** 
    161168   * Increments the object's version number (without saving it) and creates a new ResourceVersion record. 
    162169   * To be used when versionConditionMet() is false 
    163    *  
     170   * 
    164171   * @param      BaseObject   $resource 
    165172   * @param      string   Optional name of the revision author 
    166173   * @param      string   Optional comment about the revision 
     
    185192    self::createResourceVersion($resource, $createdBy, $comment); 
    186193  } 
    187194 
    188 # ---- GETTERS & SETTERS 
     195  # ---- GETTERS & SETTERS 
    189196 
    190197  /** 
    191198   * Returns resource version number. Proxy method to real getter. 
    192    *  
     199   * 
    193200   * @param      BaseObject    $resource 
    194201   * @return     integer 
    195202   */ 
     
    201208 
    202209  /** 
    203210   * Sets resource version number. Proxy method to real setter. 
    204    *  
     211   * 
    205212   * @param      BaseObject    $resource 
    206213   * @param      integer       $version_number 
    207214   */ 
    208215  public function setVersion(BaseObject $resource, $version_number) 
    209216  { 
    210217    $setter = self::forgeMethodName($resource, 'set', 'version'); 
    211     return $resource->$setter($version_number);     
     218    return $resource->$setter($version_number); 
    212219  } 
    213    
     220 
    214221  /** 
    215222   * Sets resource version comment. Temporarily stored in the resource itself. 
    216    *  
     223   * 
    217224   * @param      BaseObject    $resource 
    218225   * @param      string        $comment 
    219226   */ 
     
    224231 
    225232  /** 
    226233   * Gets resource version comment. 
    227    *  
     234   * 
    228235   * @param      BaseObject    $resource 
    229236   * 
    230237   * @return     string 
     
    243250 
    244251  /** 
    245252   * Sets resource version author. Temporarily stored in the resource itself 
    246    *  
     253   * 
    247254   * @param      BaseObject    $resource 
    248255   * @param      string        $createdBy 
    249256   */ 
     
    255262 
    256263  /** 
    257264   * Gets resource version author. 
    258    *  
     265   * 
    259266   * @param      BaseObject    $resource 
    260267   * 
    261268   * @return     string 
     
    275282  /** 
    276283   * Proxy method for getting resource version creation date. 
    277284   * But you'd better define an 'updated_at' column directly in the resource 
    278    *  
     285   * 
    279286   * @param      BaseObject    $resource 
    280287   * 
    281288   * @return     string 
     
    284291  { 
    285292    return $resource->getCurrentResourceVersion()->getCreatedAt($format); 
    286293  } 
    287    
    288 # ---- HOOKS 
    289294 
     295  # ---- HOOKS 
     296 
    290297  /** 
    291298   * This hook is called before object is saved. 
    292    *  
     299   * 
    293300   * @param      BaseObject    $resource 
    294301   */ 
    295302  public function preSave(BaseObject $resource) 
     
    299306      self::incrementVersion($resource); 
    300307    } 
    301308  } 
    302    
     309 
    303310  /** 
    304    * This hook is called juste after object is saved. It takes care of creating a new version of resource. 
    305    *  
     311   * This hook is called just after object is saved. It takes care of creating a new version of resource. 
     312   * 
    306313   * @param      BaseObject    $resource 
    307314   */ 
    308315  public function postSave(BaseObject $resource) 
    309   { 
     316  {     
    310317    if (self::versionConditionMet($resource)) 
    311318    { 
    312319      $createdBy = ''; 
     
    314321      if(isset($resource->versionCreatedBy) && $resource->versionCreatedBy != '') 
    315322      { 
    316323        $createdBy = $resource->versionCreatedBy; 
    317         $resource->versionCreatedBy = ''; 
     324        if((method_exists($resource, "setCulture") && isset($resource->passedInitialI18nSave)) || !method_exists($resource, "setCulture")) 
     325        { 
     326          $resource->versionCreatedBy = ''; 
     327        } 
    318328      } 
    319329      if(isset($resource->versionComment) && $resource->versionComment != '') 
    320330      { 
    321331        $comment = $resource->versionComment; 
    322         $resource->versionComment = ''; 
     332        if((method_exists($resource, "setCulture") && isset($resource->passedInitialI18nSave)) || !method_exists($resource, "setCulture")) 
     333        { 
     334          $resource->versionComment = ''; 
     335        } 
    323336      } 
    324337      self::createResourceVersion($resource, $createdBy, $comment); 
     338      $this->cleanVersioningStore($resource); 
    325339    } 
    326340    if(isset($resource->resourceVersion) && $resource->resourceVersion instanceOf ResourceVersion) 
    327341    { 
    328342      $resource->resourceVersion->setResourceId($resource->getPrimaryKey()); 
     343      //if((method_exists($resource, "setCulture") && isset($resource->passedInitialI18nSave)) || !method_exists($resource, "setCulture")) 
    329344      $resource->resourceVersion->save(); 
    330345      $resource->resourceVersion = null; 
    331346    } 
     347    $resource->passedInitialI18nSave = true; 
     348    self::cleanVersioningStore($resource); 
    332349  } 
    333    
     350 
    334351  /** 
    335352   * This hook is called just after a resource is deleted and takes care of deleting its version history. 
    336353   */ 
     
    342359    ResourceVersionPeer::doDelete($c); 
    343360  } 
    344361 
    345 # ---- HELPER METHODS 
     362  # ---- HELPER METHODS 
    346363 
    347364  /** 
    348365   * Increments the version number of the current object or initializes it 
     
    378395    if(!$resource->isNew()) 
    379396    { 
    380397      $version->save(); 
     398      self::cleanVersioningStore($resource); 
    381399    } 
    382400    else 
    383401    { 
     
    385403      // And leave it to the postSave() to save the version with the resource 
    386404    } 
    387405  } 
    388    
     406 
    389407  /** 
     408   * An ugly hack, we know :D 
     409   * 
     410   * Here's the run-down. It seems that there is a behavior of propel i18n objects which makes the post 
     411   * save method run twice. This left us with the a difficult bug... 2 version with the same version number, 
     412   * and twice the attribute items. 
     413   * 
     414   * TODO: Find more elegant solution to i18n versioning bug 
     415   * 
     416   * @param      BaseObject    $resource 
     417   */ 
     418  private static function cleanVersioningStore(BaseObject $resource) 
     419  { 
     420    $c = new Criteria(); 
     421    $c->add(ResourceVersionPeer::RESOURCE_NAME,get_class($resource)); 
     422    $c->add(ResourceVersionPeer::NUMBER, $resource->getVersion()); 
     423    $c->add(ResourceVersionPeer::RESOURCE_ID, $resource->getID()); 
     424    $c->addDescendingOrderByColumn(ResourceVersionPeer::ID); 
     425     
     426    $versionInstances = ResourceVersionPeer::doSelect($c); 
     427     
     428    if(count($versionInstances) > 1) 
     429    { 
     430      $c->clear(); 
     431      $versionLatest = $versionInstances[0]; 
     432      $c->add(ResourceVersionPeer::ID, $versionLatest->getId(), Criteria::NOT_EQUAL); 
     433      $c->add(ResourceVersionPeer::RESOURCE_ID, $resource->getID()); 
     434      $c->add(ResourceVersionPeer::NUMBER, $resource->getVersion()); 
     435      ResourceVersionPeer::doDelete($c); 
     436    } 
     437  } 
     438 
     439  /** 
    390440   * Returns a resource populated with attribute values of given version. 
    391    *  
     441   * 
    392442   * @param      BaseObject    $resource 
    393443   * @param      BaseObject    $version 
     444   * @param      array         $cultures An optional list of cultures to roll-back to 
    394445   * @return     BaseObject 
    395446   */ 
    396   public static function populateResourceFromVersion(BaseObject $resource, BaseObject $version
     447  public static function populateResourceFromVersion(BaseObject $resource, BaseObject $version, $cultures = array()
    397448  { 
    398449    foreach ($version->getResourceAttributeVersions() as $attrib_version) 
    399450    { 
    400451      $attrib_name = $attrib_version->getAttributeName(); 
    401452      $setter = sprintf('set%s', $attrib_name); 
    402        
     453   
    403454      if (!method_exists($resource, $setter)) 
    404455      { 
    405         $msg = sprintf('Impossible to set attribute "%s" on resource "%s"',  
    406                       $attrib_name, get_class($resource)); 
     456        $msg = sprintf('Impossible to set attribute "%s" on resource "%s"', 
     457        $attrib_name, get_class($resource)); 
    407458        throw new Exception($msg); 
    408459      } 
     460       
     461      if($attrib_version->getCulture() != '' && method_exists($resource, 'setCulture')) 
     462      { 
     463        $resource->setCulture($attrib_version->getCulture()); 
     464      } 
     465       
    409466      $resource->$setter($attrib_version->getAttributeValue()); 
    410467    } 
    411  
    412      
    413468    return $resource; 
    414469  } 
    415470 
    416471  /** 
    417472   * Returns getter / setter name for requested column. 
    418    *  
     473   * 
    419474   * @param     BaseObject    $resource 
    420475   * @param     string        $prefix     Usually 'get' or 'set' 
    421476   * @param     string        $column     version 
    422477   */ 
    423478  private static function forgeMethodName($resource, $prefix, $column) 
    424479  { 
    425     $method_name = sprintf('%s%s', $prefix,  
    426                                    $resource->getPeer()->translateFieldName(self::getColumnConstant(get_class($resource), $column),  
    427                                                                         BasePeer::TYPE_FIELDNAME,  
    428                                                                         BasePeer::TYPE_PHPNAME)); 
     480    $method_name = sprintf('%s%s', $prefix, 
     481    $resource->getPeer()->translateFieldName(self::getColumnConstant(get_class($resource), $column), 
     482    BasePeer::TYPE_FIELDNAME, 
     483    BasePeer::TYPE_PHPNAME)); 
    429484    return $method_name; 
    430485  } 
    431486 
    432487  /** 
    433488   * Returns constant value for requested column. 
    434    *  
     489   * 
    435490   * @param     string      $resource_class 
    436491   * @param     string      $column 
    437492   * @return    string 
     
    441496    $conf_directive = sprintf('propel_behavior_versionable_%s_columns', $resource_class); 
    442497    $columns = sfConfig::get($conf_directive); 
    443498 
    444     return $columns[$column];     
     499    return $columns[$column]; 
    445500  } 
    446501 
    447502  /** 
    448503   * Used to decide wether or not a new version of resource should be created. 
    449    *  
     504   * 
    450505   * @param   BaseObject   $resource 
    451506   * @return  bool 
    452507   */ 
     
    456511    { 
    457512      return false; 
    458513    } 
    459      
     514 
    460515    if (!$method = self::$condition_method) 
    461516    { 
    462517      $conf_directive = sprintf('propel_behavior_versionable_%s_conditional', get_class($resource)); 
     
    464519    } 
    465520 
    466521    $has_condition_method = method_exists($resource, $method); 
    467      
    468     return !$has_condition_method || ($has_condition_method && $resource->$method());  
     522 
     523    return !$has_condition_method || ($has_condition_method && $resource->$method()); 
    469524  } 
    470525 
    471526  /** 
    472527   * Sets object method used to decide if a new version should be created 
    473    *  
     528   * 
    474529   * @param   string 
    475530   */ 
    476531  public static function setVersionConditionMethod($method_name) 
    477532  { 
    478533    $previous_method = self::$condition_method; 
    479534    self::$condition_method = $method_name; 
    480      
     535 
    481536    return $previous_method; 
    482537  } 
    483    
     538 
    484539  /** 
    485    *  
     540   * 
    486541   */ 
    487542  public static function getVersionConditionMethod() 
    488543  {