Development

Changeset 8065

You must first sign up to be able to contribute.

Changeset 8065

Show
Ignore:
Timestamp:
03/24/08 22:20:29 (5 years ago)
Author:
naholyr
Message:

[sfPropelActAsSignableBehaviorPlugin]
- refactoring (better use of getPeer() method)
- check isModifiedColumn() and added options to customize this behavior

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • plugins/sfPropelActAsSignableBehaviorPlugin/trunk/README

    r8057 r8065  
    1515      symfony plugin-install http://plugins.symfony-project.com/sfPropelActAsSignableBehaviorPlugin 
    1616    }}} 
     17     
     18    Like any other plugin, you can either extract one of the attached archives, or use Subversion. 
    1719   
    1820  * Add the desired columns to your schema.yml for the tables you want to be signed. You can use a string or  
     
    6668         
    6769        sfPropelBehavior::add('ForumPost', array( 
    68           'sfPropelActAsSluggableBehavior' => array( 
     70          'sfPropelActAsSignableBehavior' => array( 
    6971            'columns' => $columns_map 
    7072          ) 
    7173        );  
    7274    }}} 
    73      
    74     The `columns map` is used by the behavior to know which columns hold information it needs : 
    75  
    76       * created : Model column holding the creator of the object, default is `created_by`. 
    77       * updated : Model column holding the last user who updated the object, default is `updated_by`. 
    78       * deleted : Model column holding the user who deleted the object, default is `deleted_by`. 
    79  
    80     The `user methods` is used by the behavior to know what method of the `myUser` class must be called 
    81     to retrieve the wanted information. 
    82      
    83       * id :     Method called to retrieve the user's ID, to fill integer `*_by` columns, default is `getId()`. 
    84       * string : Method called to retrieve the string representation of the user, to fill string `*_by` columns, default is `__toString()`. 
    8575     
    8676  * Add the needed methods to your `myUser` class (file located in `apps/myApp/lib/myUser.class.php`) : 
     
    9888      } 
    9989    }}} 
     90     
     91    You can use different names for those methods, you can even use different methods for each 
     92    of your "signable" tables : See next section (options). 
     93 
     94=== Options === 
     95 
     96The generic way to add the behavior to your table is  
     97 
     98{{{ 
     99  sfPropelBehavior::add('MyClass', array( 
     100    'sfPropelActAsSignableBehavior' => $options 
     101  );  
     102}}} 
     103     
     104The `$options` array represents the options passed to customize the behavior to your needs.  
     105 
     106The __`columns`__ index represents the columns mapping, which is used by the behavior to know which columns  
     107hold information it needs : 
     108 
     109  * __`created`__ : Model column holding the creator of the object, default is `created_by`. 
     110  * __`updated`__ : Model column holding the last user who updated the object, default is `updated_by`. 
     111  * __`deleted`__ : Model column holding the user who deleted the object, default is `deleted_by`. 
     112 
     113The __`userMethods`__ index is used by the behavior to know what method of the `myUser` class must be called 
     114to retrieve the wanted information. 
     115 
     116  * __`id`__ :     Method called to retrieve the user's ID, to fill integer `*_by` columns, default is `getId()`. 
     117  * __`string`__ : Method called to retrieve the string representation of the user, to fill string `*_by` columns, default is `__toString()`. 
     118 
     119The __`updateModifiedColumn`__ is set to true if you want the behavior to overwrite the value of columns 
     120even if they are already marked as modified (i.e. if you set this option to true, you will not be able to 
     121customize the value of those columns in your auto-generated admin modules). Default value is false. 
     122 
     123The __`updateEmptyColumn`__ is set to true if you want the behavior to set the value of empty columns, even 
     124if they are already marked sas modified (i.e. if you set this option to true, your username will be stored 
     125if you let the field empty in your auto-generated admin modules). Default value is true. 
     126 
     127The full options are represented here with their default values : 
     128 
     129{{{ 
     130  array( 
     131    'columns' => array( 
     132      'created' => 'created_by', 
     133      'updated' => 'updated_by', 
     134      'deleted' => 'deleted_by', 
     135    ), 
     136    'userMethods' => array( 
     137      'string' => '__toString', 
     138      'id'     => 'getId', 
     139    ), 
     140    'updateModifiedColumn' => false, 
     141    'updateEmptyColumn' => true, 
     142  ) 
     143}}} 
     144 
    100145 
    101146== Dependencies == 
  • plugins/sfPropelActAsSignableBehaviorPlugin/trunk/lib/sfPropelActAsSignableBehavior.class.php

    r8057 r8065  
    1212/** 
    1313 * This behavior automates the handling of "created_by" and "updated_by" columns 
     14 *  
     15 * Full options array (every option is optional) : 
     16 *  
     17 * sfPropelBehavior::add('Dummy', array( 
     18 *   'sfPropelActAsSignableBehavior' => array( 
     19 *     'columns' => array( // columns map 
     20 *       'created' => DummyPeer::CREATED_BY, 
     21 *       'updated' => DummyPeer::UPDATED_BY, 
     22 *       'deleted' => DummyPeer::DELETED_BY, 
     23 *     ), 
     24 *     'userMethods' => array( // user's methods to get string or int representation 
     25 *       'string' => '__toString', 
     26 *       'id'     => 'getId', 
     27 *     ), 
     28 *     'updateModifiedColumn' => false, 
     29 *     'updateEmptyColumn' => true, 
     30 *   ) 
     31 * )); 
     32 *  
    1433 * 
    1534 * @author  Nicolas Chambrier <naholyr@yahoo.fr> 
     
    1837class sfPropelActAsSignableBehavior 
    1938{ 
    20  
     39   
     40  /** 
     41   * If set to true, the *_by columns will be set, even if they're already 
     42   * marked as modified. 
     43   *  
     44   * @see sfPropelActAsSignableBehavior::$default_updateEmptyColumn 
     45   * 
     46   * @var boolean 
     47   */ 
     48  public static $default_updateModifiedColumn = false; 
     49   
     50  /** 
     51   * If set to true, the *_by columns will be set if they're empty, even if 
     52   * they're marked as modified. 
     53   *  
     54   * @see sfPropelActAsSignableBehavior::$default_updateModifiedColumn 
     55   *  
     56   * @var boolean 
     57   */ 
     58  public static $default_updateEmptyColumn = true; 
     59   
    2160  /** 
    2261   * Is behavior enabled ? 
     
    4281   * @var array 
    4382   */ 
    44   private static $default_user_methods = array( 
     83  private static $default_userMethods = array( 
    4584    'id'     => 'getId',  
    4685    'string' => '__toString' 
     
    82121  public function preSave(BaseObject $object) 
    83122  { 
     123    // Automaticaly re-enable behavior 
    84124    if (!self::enabled()) { 
    85125      self::enable(); 
     
    87127    } 
    88128     
     129    // Get user from context, if available 
    89130    $user = sfContext::getInstance()->getUser(); 
    90131     
     132    // Created by... 
    91133    if ($object->isNew()) { 
    92134      self::setSomethingBy($object, 'created', $user); 
    93135    } 
    94136     
     137    // Updated by... 
    95138    if ($object->isModified()) { 
    96139      self::setSomethingBy($object, 'updated', $user); 
     
    105148  public function preDelete(BaseObject $object) 
    106149  { 
     150    // Automaticaly re-enable behavior 
    107151    if (!self::enabled()) { 
    108152      self::enable(); 
     
    110154    } 
    111155     
     156    // Get user from context 
    112157    $user = sfContext::getInstance()->getUser(); 
    113158     
     159    // Deleted by... 
    114160    self::setSomethingBy($object, 'deleted', $user); 
    115161  } 
     
    126172    $class = get_class($object); 
    127173     
    128     switch (self::getColumnType($class, $what)) { 
     174    // Check if the column is authorized to be updated, depending on the behavior options 
     175    $column = self::getColumnConstant($object, $what); 
     176    $updateModifiedColumn = sfConfig::get('propel_behavior_sfPropelActAsSignableBehavior_' . $class . '_updateModifiedColumn', self::$default_updateModifiedColumn); 
     177    if (!$updateModifiedColumn && $object->isColumnModified($column)) { 
     178      // we're not allowed to update modified column, and this one is modified 
     179      $updateEmptyColumn = sfConfig::get('propel_behavior_sfPropelActAsSignableBehavior_' . $class . '_updateEmptyColumn', self::$default_updateEmptyColumn); 
     180      if (!$updateEmptyColumn) { 
     181        // we don't check if the column is empty, let's stop here 
     182        return false; 
     183      } else { 
     184        // we skip only if the column is not empty 
     185        $getter = self::forgeMethodName($object, 'get', $what); 
     186        $value = call_user_func(array($object, $getter)); 
     187        if (!empty($value)) { 
     188          return false; 
     189        } 
     190      } 
     191    } 
     192     
     193    // Retrieve column's type and get the corresponding user's value 
     194    switch (self::getColumnType($object, $what)) { 
    129195      case null:       // Column not found : ignore 
    130196        return false; 
     
    139205    } 
    140206     
     207    // Set the value 
    141208    $setter = self::forgeMethodName($object, 'set', $what); 
    142209     
     
    155222  private static function getUserInfo($class, myUser $user, $info) 
    156223  { 
    157     $methods = sfConfig::get('propel_behavior_sfPropelActAsSignableBehavior_' . $class . '_user_methods', self::$default_user_methods); 
    158     $method = $methods[$info]; 
     224    $methods = sfConfig::get('propel_behavior_sfPropelActAsSignableBehavior_' . $class . '_userMethods', array()); 
     225     
     226    if (array_key_exists($info, $methods)) { 
     227      $method = $methods[$info]; 
     228    } else { 
     229      $method = self::$default_userMethods[$info]; 
     230    } 
    159231     
    160232    return call_user_func(array($user, $method)); 
     
    164236   * Returns the appropriate column name. 
    165237   *  
    166    * @param   string   $class                    Propel model class 
    167    * @param   string   $column                   Column name 
    168    *  
    169    * @return  string   Column's name 
    170    */ 
    171   private static function getColumnConstant($class, $column) 
    172   { 
    173     $columns = sfConfig::get('propel_behavior_sfPropelActAsSignableBehavior_' . $class . '_columns', self::$default_columns); 
    174      
    175     $column = $columns[$column]; 
     238   * @param   BaseObject   $object                   Propel object 
     239   * @param   string       $column                   Column name 
     240   *  
     241   * @return  string       Column's name 
     242   */ 
     243  private static function getColumnConstant(BaseObject $object, $column) 
     244  { 
     245    $class = get_class($object); 
     246     
     247    $columns = sfConfig::get('propel_behavior_sfPropelActAsSignableBehavior_' . $class . '_columns', array()); 
     248     
     249    if (array_key_exists($column, $columns)) { 
     250      $column = $columns[$column]; 
     251    } else { 
     252      $column = self::$default_columns[$column]; 
     253    } 
    176254     
    177255    // Check that the column is prefixed, if not, prefix it with table name 
    178     $table_name = constant($class . 'Peer::TABLE_NAME'); 
     256    $table_name = $object->getPeer()->getTableMap()->getName(); 
    179257    if (substr($column, 0, strlen($table_name)+1) != $table_name . '.') { 
    180258      $column = $table_name . '.' . strtoupper($column); 
     
    187265   * Returns type for one column of the given class 
    188266   * 
    189    * @param string       $class                 Propel model class 
     267   * @param BaseObject   $object                Propel object 
    190268   * @param string       $column                Column name 
    191269   *  
    192270   * @return string 
    193271   */ 
    194   private static function getColumnType($class, $column) 
    195   { 
    196     $mapBuilderClass = $class . 'MapBuilder'; 
    197      
    198     $mapBuilder = new $mapBuilderClass; 
    199     $mapBuilder->doBuild(); 
    200     $map = $mapBuilder->getDatabaseMap(); 
    201      
    202     $table = $map->getTable(constant($class . 'Peer::TABLE_NAME')); 
     272  private static function getColumnType(BaseObject $object, $column) 
     273  { 
     274    $table = $object->getPeer()->getTableMap(); 
    203275     
    204276    try { 
    205       $column = $table->getColumn(self::getColumnConstant($class, $column)); 
     277      $column = $table->getColumn(self::getColumnConstant($object, $column)); 
    206278      $type = $column->getType(); 
    207279    } catch (PropelException $e) { 
     
    221293  private static function forgeMethodName(BaseObject $object, $prefix, $column) 
    222294  { 
    223     $column_constant = self::getColumnConstant(get_class($object), $column); 
     295    $column_constant = self::getColumnConstant($object, $column); 
    224296    $method_name = $prefix . $object->getPeer()->translateFieldName($column_constant, BasePeer::TYPE_COLNAME, BasePeer::TYPE_PHPNAME); 
    225297     
  • plugins/sfPropelActAsSignableBehaviorPlugin/trunk/package.xml

    r8058 r8065  
    1414  <active>yes</active> 
    1515 </lead> 
    16  <date>2008-03-23</date> 
     16 <date>2008-03-24</date> 
    1717 <version> 
    18    <release>0.1</release> 
    19    <api>0.1</api> 
     18   <release>0.2</release> 
     19   <api>0.2</api> 
    2020 </version> 
    2121 <stability>