Index: /plugins/sfDoctrineActAsSignablePlugin/trunk/LICENSE =================================================================== --- /plugins/sfDoctrineActAsSignablePlugin/trunk/LICENSE (revision 31039) +++ /plugins/sfDoctrineActAsSignablePlugin/trunk/LICENSE (revision 31039) @@ -0,0 +1,7 @@ +Copyright (c) 2009-2010 Vitaliy Tverdokhlib, Tomasz Ducin + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Index: /plugins/sfDoctrineActAsSignablePlugin/trunk/lib/listener/Signable.php =================================================================== --- /plugins/sfDoctrineActAsSignablePlugin/trunk/lib/listener/Signable.php (revision 31039) +++ /plugins/sfDoctrineActAsSignablePlugin/trunk/lib/listener/Signable.php (revision 31039) @@ -0,0 +1,116 @@ + + * @author Tomasz Ducin + */ +class Doctrine_Template_Listener_Signable extends Doctrine_Record_Listener +{ + + /** + * Array of Signable options + * + * @var array + */ + protected $_options = array(); + + /** + * __construct + * + * @param array $options + * @return void + */ + public function __construct(array $options) + { + $this->_options = $options; + } + + /** + * preInsert + * + * @param object $Doctrine_Event. + * @return void + */ + public function preInsert(Doctrine_Event $event) + { + if (!$this->_options['created']['disabled']) + { + $createdName = $this->_options['created']['name']; + $event->getInvoker()->$createdName = $this->getUserId('created'); + } + + if (!$this->_options['updated']['disabled'] && $this->_options['updated']['onInsert']) + { + $updatedName = $this->_options['updated']['name']; + $event->getInvoker()->$updatedName = $this->getUserId('updated'); + } + } + + /** + * preUpdate + * + * @param object $Doctrine_Event. + * @return void + */ + public function preUpdate(Doctrine_Event $event) + { + if (!$this->_options['updated']['disabled']) + { + $updatedName = $this->_options['updated']['name']; + $event->getInvoker()->$updatedName = $this->getUserId('updated'); + } + } + + /** + * getUserId + * + * Gets the userid or username depending on field format + * + * @param string $type. + * @return void + */ + public function getUserId($type) + { + // В режиме CLI возвращает null + if (0 != strncasecmp(PHP_SAPI, 'cli', 3)) + { + $options = $this->_options[$type]; + if ($options['expression'] !== false && is_string($options['expression'])) + { + return new Doctrine_Expression($options['expression']); + } + elseif (!class_exists("pakeApp")) + { + switch ($options['type']) + { + case 'integer': + if (class_exists('sfGuardUser')) + { + return sfContext::getInstance()->getUser()->getAttribute('user_id', null, 'sfGuardSecurityUser'); + } + else + { + return sfContext::getInstance()->getUser()->getId(); + } + break; + case 'string': + return sfContext::getInstance()->getUser()->getUsername(); + break; + default: + return 'n/a'; + break; + } + } + } + else + { + return null; + } + } +} Index: /plugins/sfDoctrineActAsSignablePlugin/trunk/lib/template/Signable.php =================================================================== --- /plugins/sfDoctrineActAsSignablePlugin/trunk/lib/template/Signable.php (revision 31039) +++ /plugins/sfDoctrineActAsSignablePlugin/trunk/lib/template/Signable.php (revision 31039) @@ -0,0 +1,77 @@ + + * @author Tomasz Ducin + */ +class Doctrine_Template_Signable extends Doctrine_Template +{ + + /** + * Array of Signable options + * + * @var string + */ + protected $_options = array( + 'created' => array( + 'name' => 'created_by', + 'type' => 'integer', + 'disabled' => false, + 'expression' => false, + 'options' => array() + ), + 'updated' => array( + 'name' => 'updated_by', + 'type' => 'integer', + 'disabled' => false, + 'expression' => false, + 'onInsert' => true, + 'options' => array() + ), + ); + + /** + * __construct + * + * @param string $array + * @return void + */ + public function __construct(array $options = array()) + { + $this->_options = Doctrine_Lib::arrayDeepMerge($this->_options, $options); + } + + /** + * Set table definition for signable behavior. + * + * @return void + */ + public function setTableDefinition() + { + if (!$this->_options['created']['disabled']) + { + $this->hasColumn( + $this->_options['created']['name'], + $this->_options['created']['type'], + null, + $this->_options['created']['options'] + ); + } + if (!$this->_options['updated']['disabled']) + { + $this->hasColumn( + $this->_options['updated']['name'], + $this->_options['updated']['type'], + null, + $this->_options['updated']['options'] + ); + } + $this->addListener(new Doctrine_Template_Listener_Signable($this->_options)); + } +} Index: /plugins/sfDoctrineActAsSignablePlugin/trunk/package.xml =================================================================== --- /plugins/sfDoctrineActAsSignablePlugin/trunk/package.xml (revision 31039) +++ /plugins/sfDoctrineActAsSignablePlugin/trunk/package.xml (revision 31039) @@ -0,0 +1,108 @@ + + + sfDoctrineActAsSignablePlugin + plugins.symfony-project.org + sfDoctrineActAsSignablePlugin provides Signable behavior to your models ("created_by" and "updated_by"columns defining user who created/updated a record) + sfDoctrineActAsSignablePlugin provides Signable behavior to your models ("created_by" and "updated_by"columns defining user who created/updated a record) + + Vitaliy Tverdokhlib + new2 + new2@ua.fm + yes + + + Tomasz Ducin + tkoomzaaskz + tomasz.ducin@gmail.com + yes + + 2010-10-03 + + + 1.1.0 + 1.1.0 + + + stable + stable + + MIT license + - + + + + + + + + + + + + + + + + + + + + + 5.0.0 + + + 1.4.1 + + + symfony + pear.symfony-project.com + 1.2.0 + 1.5.0 + 1.5.0 + + + + + + + + + + + + 1.1.0 + 1.1.0 + + + stable + stable + + MIT license + 2010-10-03 + MIT + + * tkoomzaaskz: provided support for symfony 1.3, 1.4 + * tkoomzaaskz: improved docs + + + + + + 1.0.0 + 1.0.0 + + + stable + stable + + MIT license + 2009-07-12 + MIT + + * new2: first version + + + + + + Index: /plugins/sfDoctrineActAsSignablePlugin/trunk/README =================================================================== --- /plugins/sfDoctrineActAsSignablePlugin/trunk/README (revision 31039) +++ /plugins/sfDoctrineActAsSignablePlugin/trunk/README (revision 31039) @@ -0,0 +1,85 @@ +sfDoctrineActAsSignablePlugin +============================= + +The `sfDoctrineActAsSignablePlugin` plugin automates the handling of `created_by` +and `updated_by` columns. Each time a __Signable__ object is inserted or updated, +those columns are automatically updated accordingly to the user who saved the +changes. + +Instalation +=========== + +Install the plugin: + + $ ./symfony plugin-install http://plugins.symfony-project.com/sfDoctrineActAsSignablePlugin + +or download the package and install it from the archive. + +Usage +===== + +Add the desired columns to your schema.yml for the tables you want to be signed. +You can use a string or an int type, the behavior will automatically detect the +type and store the corresponding information depending on this type (for a +string the username is stored, and for an integer it's the user's ID). + + # You can either set the type of a column to a string (will store the username) or an integer (will store the user ID) + + actAs: + Signable: + created: + name: created_by + type: integer + options: + notnull: true + default: 1 + updated: + name: updated_by + type: string + +Also you may use global behavior in your doctrine schema (default field value is +integer): + + actAs: [Timestampable, Signable] + +Example use cases +================= + +Here are some example cases when you may find this plugin useful: + +string user reference +--------------------- + +The project includes a blog or a forum system. Each blog/forum post page needs +to display the user who posted it (or modified it last time). The symfony forum +screenshot last column shows LAST POST, user name is highlighted in red +(__Singable__ behavior) and the timestamp is highlighted in green +(__Timestampable__ behavior): + +![symfony forum](http://img191.imageshack.us/img191/9010/forummg.png "symfony forum") + +integer user reference +---------------------- + +The more advanced technique is to use an integer created_by/updated_by column +(the default) to store the user's ID (need to have appropriate user table, e.g. +[sfDoctrineGuardPlugin](http://www.symfony-project.org/plugins/sfDoctrineGuardPlugin)). +In this case you may use relations and fetch User object at runtime (which is +very difficult if you store user name as a string). + +This option is very useful when developing a CRM or ERP system where data +modification is important (could be combined with data versioning). + +Dependencies +============ + +There is no required dependency, although : + + * [sfDoctrineGuardPlugin](http://www.symfony-project.org/plugins/sfDoctrineGuardPlugin) + will provide you basic but flexible and robust user management. + +Thanks to +--------- + +Thomas Boerger, Michael Klein, Kary Leong, geoffrey: +[The snippet this plugin is based on](http://snippets.symfony-project.org/snippet/281 "Snippet").