Author: bshaffer
Date: 2010-05-04 16:08:43 +0200 (Tue, 04 May 2010)
New Revision: 29345

Added:
   plugins/csDoctrineActAsSortablePlugin/branches/1.4/
   plugins/csDoctrineActAsSortablePlugin/branches/1.4/LICENSE
   plugins/csDoctrineActAsSortablePlugin/branches/1.4/README
   plugins/csDoctrineActAsSortablePlugin/branches/1.4/lib/
   plugins/csDoctrineActAsSortablePlugin/branches/1.4/lib/listener/
   plugins/csDoctrineActAsSortablePlugin/branches/1.4/lib/listener/Sortable.php
   plugins/csDoctrineActAsSortablePlugin/branches/1.4/lib/template/
   plugins/csDoctrineActAsSortablePlugin/branches/1.4/lib/template/Sortable.php
   plugins/csDoctrineActAsSortablePlugin/branches/1.4/package.xml
   plugins/csDoctrineActAsSortablePlugin/branches/1.4/web/
   plugins/csDoctrineActAsSortablePlugin/branches/1.4/web/css/
   plugins/csDoctrineActAsSortablePlugin/branches/1.4/web/css/sortable.css
   plugins/csDoctrineActAsSortablePlugin/branches/1.4/web/images/
   plugins/csDoctrineActAsSortablePlugin/branches/1.4/web/images/sortable/
   plugins/csDoctrineActAsSortablePlugin/branches/1.4/web/images/sortable/icons/
   
plugins/csDoctrineActAsSortablePlugin/branches/1.4/web/images/sortable/icons/demote.png
   
plugins/csDoctrineActAsSortablePlugin/branches/1.4/web/images/sortable/icons/promote.png
Log:
creating 1.4 branch

Added: plugins/csDoctrineActAsSortablePlugin/branches/1.4/README
===================================================================
--- plugins/csDoctrineActAsSortablePlugin/branches/1.4/README                   
        (rev 0)
+++ plugins/csDoctrineActAsSortablePlugin/branches/1.4/README   2010-05-04 
14:08:43 UTC (rev 29345)
@@ -0,0 +1,123 @@
+csDoctrineActAsSortablePlugin
+=============================
+
+The `csDoctrineActAsSortablePlugin` is a symfony plugin that allows use of the 
doctrine behavior actAsSortable.
+
+This behavior provides methods on your model for setting display 
order/position.
+
+This plugin also contains images to implement for ordering.
+
+Installation
+------------
+
+  * Install the plugin
+
+        $ symfony plugin:install csDoctrineActAsSortablePlugin
+
+  * Apply the behavior to your model in your schema file 
`config/doctrine/schema.yml`, ie:
+
+        [yml]
+        model:
+          actAs: [Sortable]
+    Optionally accepts a UniqueBy attribute which will be used on a model with 
a one-to-many relationship
+    
+          model:
+            actAs: [Sortable]
+            uniqueBy: [parent_id]
+
+  * Rebuild your models and database
+  
+        $ symfony doctrine:build-all-reload
+    
+    alternatively you could build the models, the sql, then run the sql 
manually
+        
+  * Publish your assets
+
+        $ symfony plugin:publish-assets
+
+  * Clear your cache
+
+        $ symfony cc
+
+
+Available Record Methods
+------------------------
+
+  * promote
+
+        [php]
+        $record->promote();
+      
+  * demote
+  
+        [php]
+        $record->demote();
+      
+  * moveToFirst
+  
+        [php]
+        $record->moveToFirst();
+      
+  * moveToLast
+  
+        [php]
+        $record->moveToLast();
+      
+  * moveToPosition
+  
+        [php]
+        $record->moveToPosition($newPosition);
+        
+
+Available Table Methods
+------------------------
+
+  * sort - accepts the array created by the symfony/prototype sortableElement 
tag
+
+        [php]
+        Doctrine::getTable('Model')->sort($order);
+
+  * findAllSorted - Accepts sort order (asc, desc)
+
+        [php]
+        Doctrine::getTable('Model')->findAllSorted('ASCENDING');
+
+  * findAllSortedWithParent - accepts the parent column name, the value, and 
sort order (asc, desc)
+
+        [php]
+        Doctrine::getTable('Model')->findAllSortedWithParent($fk_value, 
$fk_name, 'ASCENDING');
+
+
+Example Usage With Admin Generator
+----------------------------------
+
+  * In your module, edit `config/generator.yml`, and under list, object 
actions, add:
+
+        [yml]
+        object_actions:
+          promote:
+            action: promote
+          demote:
+            action: demote
+          _edit:        -
+          _delete:      -
+          
+  * In your module, edit ``, Add the following actions:
+  
+        [php]
+        public function executePromote()
+        {
+          
$object=Doctrine::getTable('MyModel')->findOneById($this->getRequestParameter('id'));
+
+
+          $object->promote();
+          $this->redirect("@moduleIndexRoute");
+        }
+
+        public function executeDemote()
+        {
+          
$object=Doctrine::getTable('MyModel')->findOneById($this->getRequestParameter('id'));
+
+          $object->demote();
+          $this->redirect("@moduleIndexRoute");
+        }
\ No newline at end of file

Added: 
plugins/csDoctrineActAsSortablePlugin/branches/1.4/lib/listener/Sortable.php
===================================================================
--- 
plugins/csDoctrineActAsSortablePlugin/branches/1.4/lib/listener/Sortable.php    
                            (rev 0)
+++ 
plugins/csDoctrineActAsSortablePlugin/branches/1.4/lib/listener/Sortable.php    
    2010-05-04 14:08:43 UTC (rev 29345)
@@ -0,0 +1,76 @@
+<?php
+
+
+/**
+ * Easily sort each record based on position
+ *
+ * @package     csDoctrineSortablePlugin
+ * @subpackage  listener
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.phpdoctrine.org
+ * @since       1.0
+ * @version     $Revision$
+ * @author      Travis Black <[email protected]>
+ */
+class Doctrine_Template_Listener_Sortable extends Doctrine_Record_Listener
+{
+  /**
+   * Array of sortable options
+   *
+   * @var array
+   */
+  protected $_options = array();
+
+
+  /**
+   * __construct
+   *
+   * @param array $options 
+   * @return void
+   */  
+  public function __construct(array $options)
+  {
+    $this->_options = $options;
+  }
+
+
+  /**
+   * Set the position value automatically when a new sortable object is created
+   *
+   * @param Doctrine_Event $event
+   * @return void
+   */
+  public function preInsert(Doctrine_Event $event)
+  {
+    $fieldName = $this->_options['name'];
+    $object = $event->getInvoker();
+    $object->$fieldName = $object->getFinalPosition()+1;
+  }
+
+
+  /**
+   * When a sortable object is deleted, promote all objects positioned lower 
than itself
+   *
+   * @param string $Doctrine_Event 
+   * @return void
+   */  
+  public function postDelete(Doctrine_Event $event)
+  {
+    $fieldName = $this->_options['name'];
+    $object = $event->getInvoker();
+    $position = $object->$fieldName;
+
+    $q = $object->getTable()->createQuery()
+                            ->update(get_class($object))
+                            ->set($fieldName, $fieldName . ' - ?', '1')
+                            ->where($fieldName . ' > ?', $position)
+                            ->orderBy($fieldName);
+
+    foreach ($this->_options['uniqueBy'] as $field)
+    {
+      $q->addWhere($field . ' = ?', $object[$field]);
+    }
+
+    $q->execute();
+  }  
+}
\ No newline at end of file

Added: 
plugins/csDoctrineActAsSortablePlugin/branches/1.4/lib/template/Sortable.php
===================================================================
--- 
plugins/csDoctrineActAsSortablePlugin/branches/1.4/lib/template/Sortable.php    
                            (rev 0)
+++ 
plugins/csDoctrineActAsSortablePlugin/branches/1.4/lib/template/Sortable.php    
    2010-05-04 14:08:43 UTC (rev 29345)
@@ -0,0 +1,375 @@
+<?php
+
+/**
+ * Easily create a slug for each record based on a specified set of fields
+ *
+ * @package     csDoctrineSortablePlugin
+ * @subpackage  template
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.phpdoctrine.org
+ * @since       1.0
+ * @version     $Revision$
+ * @author      Travis Black <[email protected]>
+ */
+class Doctrine_Template_Sortable extends Doctrine_Template
+{
+  /**
+   * Array of Sortable options
+   *
+   * @var string
+   */
+  protected $_options = array('name'        =>  'position',
+                              'alias'       =>  null,
+                              'type'        =>  'integer',
+                              'length'      =>  8,
+                              'unique'      =>  true,
+                              'options'     =>  array(),
+                              'fields'      =>  array(),
+                              'uniqueBy'    =>  array(),
+                              'uniqueIndex' =>  true,
+                              'indexName'   =>  'sortable'
+  );
+
+  /**
+   * __construct
+   *
+   * @param string $array
+   * @return void
+   */
+  public function __construct(array $options = array())
+  {
+    $this->_options = Doctrine_Lib::arrayDeepMerge($this->_options, $options);
+  }
+
+
+  /**
+   * Set table definition for sortable behavior
+   * (borrowed and modified from Sluggable in Doctrine core)
+   *
+   * @return void
+   */
+  public function setTableDefinition()
+  {
+    $name = $this->_options['name'];
+
+    if ($this->_options['alias'])
+    {
+      $name .= ' as ' . $this->_options['alias'];
+    }
+
+    $this->hasColumn($name, $this->_options['type'], 
$this->_options['length'], $this->_options['options']);
+
+    if (!empty($this->_options['uniqueBy']) && 
!is_array($this->_options['uniqueBy'])) 
+    {
+      throw new sfException("Sortable option 'uniqueBy' must be an array");
+    }
+    
+    if ($this->_options['uniqueIndex'] == true && ! 
empty($this->_options['uniqueBy']))
+    {
+      $indexFields = array($this->_options['name']);
+      $indexFields = array_merge($indexFields, $this->_options['uniqueBy']);
+
+      $this->index($this->getSortableIndexName(), array('fields' => 
$indexFields, 'type' => 'unique')); 
+
+    }
+    elseif ($this->_options['unique'])
+    {
+      $indexFields = array($this->_options['name']);
+      $this->index($this->getSortableIndexName(), array('fields' => 
$indexFields, 'type' => 'unique')); 
+
+    }
+
+    $this->addListener(new 
Doctrine_Template_Listener_Sortable($this->_options));
+  }
+  
+  /** 
+  * Returns the name of the index to create for the position field. 
+  * 
+  * @return string 
+  */ 
+  protected function getSortableIndexName() 
+  { 
+    return sprintf('%s_%s_%s', $this->getTable()->getTableName(), 
$this->_options['name'], $this->_options['indexName']); 
+  } 
+  
+  
+  /**
+   * Demotes a sortable object to a lower position
+   *
+   * @return void
+   */
+  public function demote()
+  {
+    $object = $this->getInvoker();
+    $position = $object->get($this->_options['name']);
+
+    if ($position < $object->getFinalPosition())
+    {
+      $object->moveToPosition($position + 1);
+    }
+  }
+
+
+  /**
+   * Promotes a sortable object to a higher position
+   *
+   * @return void
+   */
+  public function promote()
+  {
+    $object = $this->getInvoker();
+    $position = $object->get($this->_options['name']);
+
+    if ($position > 1)
+    {
+      $object->moveToPosition($position - 1);
+    }
+  }
+
+  /**
+   * Sets a sortable object to the first position
+   *
+   * @return void
+   */
+  public function moveToFirst()
+  {
+    $object = $this->getInvoker();
+    $object->moveToPosition(1);
+  }
+
+
+  /**
+   * Sets a sortable object to the last position
+   *
+   * @return void
+   */
+  public function moveToLast()
+  {
+    $object = $this->getInvoker();
+    $object->moveToPosition($object->getFinalPosition());
+  }
+
+
+  /**
+   * Moves a sortable object to a designate position
+   *
+   * @param int $newPosition
+   * @return void
+   */
+  public function moveToPosition($newPosition)
+  {
+    if (!is_int($newPosition))
+    {
+      throw new Doctrine_Exception('moveToPosition requires an Integer as the 
new position. Entered ' . $newPosition);
+    }
+
+    $object = $this->getInvoker();
+    $position = $object->get($this->_options['name']);
+    $connection = $object->getTable()->getConnection();
+
+    //begin Transaction
+    $connection->beginTransaction();
+
+    // Position is required to be unique. Blanks it out before it moves others 
up/down.
+    $object->set($this->_options['name'], null);
+               $object->save();
+
+
+    if ($position > $newPosition)
+    {
+      $q = $object->getTable()->createQuery()
+                              ->update(get_class($object))
+                              ->set($this->_options['name'], 
$this->_options['name'] . ' + 1')
+                              ->where($this->_options['name'] . ' < ?', 
$position)
+                              ->andWhere($this->_options['name'] . ' >= ?', 
$newPosition)
+                              ->orderBy($this->_options['name'] . ' DESC');
+
+      foreach ($this->_options['uniqueBy'] as $field)
+      {
+        $q->addWhere($field . ' = ?', $object[$field]);
+      }
+
+      $q->execute();
+    }
+    elseif ($position < $newPosition)
+    {
+
+      $q = $object->getTable()->createQuery()
+                              ->update(get_class($object))
+                              ->set($this->_options['name'], 
$this->_options['name'] . ' - 1')
+                              ->where($this->_options['name'] . ' > ?', 
$position)
+                              ->andWhere($this->_options['name'] . ' <= ?', 
$newPosition);
+
+      foreach($this->_options['uniqueBy'] as $field)
+      {
+        $q->addWhere($field . ' = ?', $object[$field]);
+      }
+
+      $q->execute();
+    }
+
+    $object->set($this->_options['name'], $newPosition);
+               $object->save();
+
+    // Commit Transaction
+    $connection->commit();
+  }
+
+
+  /**
+   * Send an array from the sortable_element tag (symfony+prototype)and it will
+   * update the sort order to match
+   *
+   * @param string $order
+   * @return void
+   * @author Travis Black
+   */
+  public function sortTableProxy($order)
+  {
+    /*
+      TODO 
+        - Add proper error messages.
+    */
+    $table = $this->getInvoker()->getTable();
+    $class  = get_class($this->getInvoker());
+    $connection = $table->getConnection();
+
+    $connection->beginTransaction();
+
+    foreach ($order as $position => $id)
+    {
+      $newObject = Doctrine::getTable($class)->findOneById($id);
+
+      if ($newObject->get($this->_options['name']) != $position + 1)
+      {
+        $newObject->moveToPosition($position + 1);
+      }
+    }
+
+    // Commit Transaction
+    $connection->commit();
+  }
+
+
+  /**
+   * Finds all sortable objects and sorts them based on position attribute
+   * Ascending or Descending based on parameter
+   *
+   * @param string $order
+   * @return $query
+   */
+  public function findAllSortedTableProxy($order = 'ASC')
+  {
+    $order = $this->formatAndCheckOrder($order);
+    $object = $this->getInvoker();
+
+    $query = $object->getTable()->createQuery()
+                                ->orderBy($this->_options['name'] . ' ' . 
$order);
+
+    return $query->execute();
+  }
+
+
+  /**
+   * Finds and returns records sorted where the parent (fk) in a specified
+   * one to many relationship has the value specified
+   *
+   * @param string $parentValue
+   * @param string $parent_column_value
+   * @param string $order
+   * @return $query
+   */
+  public function findAllSortedWithParentTableProxy($parentValue, 
$parentColumnName = null, $order = 'ASC')
+  {
+    $order = $this->formatAndCheckOrder($order);
+
+    $object = $this->getInvoker();
+    $class  = get_class($object);
+
+    if (!$parentColumnName)
+    {
+      $parents = get_class($object->getParent());
+
+      if (count($parents) > 1)
+      {
+        throw new Doctrine_Exception('No parent column name specified and 
object has mutliple parents');
+      }
+      elseif (count($parents) < 1)
+      {
+        throw new Doctrine_Exception('No parent column name specified and 
object has no parents');
+      }
+      else
+      {
+        $parentColumnName = $parents[0]->getType();
+        exit((string) $parentColumnName);
+        exit(print_r($parents[0]->toArray()));
+      }
+    }
+
+    $query = $object->getTable()->createQuery()
+                                ->from($class . ' od')
+                                ->where('od.' . $parentColumnName . ' = ?', 
$parentValue)
+                                ->orderBy($this->_options['name'] . ' ' . 
$order);
+
+    return $query->execute();
+  }
+
+
+  /**
+   * Formats the ORDER for insertion in to query, else throws exception
+   *
+   * @param string $order
+   * @return $order
+   */
+  public function formatAndCheckOrder($order)
+  {
+    $order = strtolower($order);
+
+    if ('ascending' === $order || 'asc' === $order)
+    {
+      $order = 'ASC';
+    }
+    elseif ('descending' === $order || 'desc' === $order)
+    {
+      $order = 'DESC';
+    }
+    else
+    {
+      throw new Doctrine_Exception('Order parameter value must be "asc" or 
"desc"');
+    }
+
+    return $order;
+  }
+
+
+  /**
+   * Get the final position of a model
+   *
+   * @return $position
+   */
+  public function getFinalPosition()
+  {
+    $object = $this->getInvoker();
+
+    $q = $object->getTable()->createQuery()
+                            ->select($this->_options['name'])
+                            ->orderBy($this->_options['name'] . ' desc');
+
+   foreach($this->_options['uniqueBy'] as $field)
+   {
+     if(is_object($object[$field]))
+     {
+       $q->addWhere($field . ' = ?', $object[$field]['id']);
+     }
+     else
+     {
+       $q->addWhere($field . ' = ?', $object[$field]);
+     }
+   }
+
+   $last = $q->fetchOne();
+   $finalPosition = $last ? $last->get($this->_options['name']) : 0;
+
+   return $finalPosition;
+  }
+}
\ No newline at end of file

Added: plugins/csDoctrineActAsSortablePlugin/branches/1.4/package.xml
===================================================================
--- plugins/csDoctrineActAsSortablePlugin/branches/1.4/package.xml              
                (rev 0)
+++ plugins/csDoctrineActAsSortablePlugin/branches/1.4/package.xml      
2010-05-04 14:08:43 UTC (rev 29345)
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package packagerversion="1.4.6" version="2.0" 
xmlns="http://pear.php.net/dtd/package-2.0"; 
xmlns:tasks="http://pear.php.net/dtd/tasks-1.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 
http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 
http://pear.php.net/dtd/package-2.0.xsd";>
+ <name>csDoctrineActAsSortablePlugin</name>
+ <channel>plugins.symfony-project.org</channel>
+ <summary>A plugin that adds sorting functions to model</summary>
+ <description>Gives up and down arrows along with various methods to 
manipulate the position of a model in a list</description>
+ <lead>
+  <name>Travis Black</name>
+  <user>travib</user>
+  <email>[email protected]</email>
+  <active>yes</active>
+ </lead>
+ <developer>
+  <name>Brent Shaffer</name>
+  <user>bshaffer</user>
+  <email>[email protected]</email>
+  <active>yes</active>
+ </developer>
+ <date>2009-07-10</date>
+ <time>15:54:35</time>
+ <version>
+  <release>1.0.3</release>
+  <api>1.0.3</api>
+ </version>
+ <stability>
+  <release>stable</release>
+  <api>stable</api>
+ </stability>
+ <license uri="http://www.symfony-project.org/license";>MIT license</license>
+ <notes>-</notes>
+ <contents>
+  <dir name="/">
+   <file role="data" name="README" />
+   <file role="data" name="LICENSE" />
+   <dir name="lib">
+    <dir name="listener">
+     <!-- model classes -->
+     <file role="data" name="Sortable.php" />
+    </dir>
+    <dir name="template">
+     <!-- model classes -->
+     <file role="data" name="Sortable.php" />
+    </dir>
+   </dir>
+   <dir name="web">
+    <dir name="images">
+     <!-- images -->
+     <dir name="sortable">
+      <dir name="icons">
+       <file role="data" name="promote.png" />
+       <file role="data" name="demote.png" />
+      </dir>
+     </dir>
+    </dir>
+    <dir name="css">
+     <!-- css -->
+     <file role="data" name="sortable.css" />
+    </dir>
+   </dir>
+  </dir>
+ </contents>
+ <dependencies>
+  <required>
+   <php>
+    <min>5.1.0</min>
+   </php>
+   <pearinstaller>
+    <min>1.4.1</min>
+   </pearinstaller>
+   <package>
+    <name>symfony</name>
+    <channel>pear.symfony-project.com</channel>
+    <min>1.1.0</min>
+    <max>1.3.0</max>
+    <exclude>1.3.0</exclude>
+   </package>
+  </required>
+ </dependencies>
+ <phprelease />
+ <changelog>
+  <release>
+   <version>
+    <release>1.0.0</release>
+    <api>1.0.0</api>
+   </version>
+   <stability>
+    <release>stable</release>
+    <api>stable</api>
+   </stability>
+   <date>2009-04-24</date>
+   <license uri="http://www.symfony-project.org/license";>MIT license</license>
+   <notes>
+   * minor updates
+   </notes>
+  </release>
+ </changelog>
+</package>
\ No newline at end of file

Added: plugins/csDoctrineActAsSortablePlugin/branches/1.4/web/css/sortable.css
===================================================================
--- plugins/csDoctrineActAsSortablePlugin/branches/1.4/web/css/sortable.css     
                        (rev 0)
+++ plugins/csDoctrineActAsSortablePlugin/branches/1.4/web/css/sortable.css     
2010-05-04 14:08:43 UTC (rev 29345)
@@ -0,0 +1,19 @@
+#sf_admin_container ul li.sf_admin_action_promote a 
+{
+       background-image:none;
+}
+#sf_admin_container ul li.sf_admin_action_demote a 
+{
+       background-image:none;
+}
+#sf_admin_container ul li.sf_admin_action_promote 
+{
+       background:transparent url(../images/sortable/icons/promote.png) 
no-repeat scroll 0 0;
+}
+#sf_admin_container ul li.sf_admin_action_demote 
+{
+       background:transparent url(../images/sortable/icons/demote.png) 
no-repeat scroll 0 0;
+}
+#sf_admin_container ul.sf_admin_td_actions {
+       width:120px !important;
+}
\ No newline at end of file

Added: 
plugins/csDoctrineActAsSortablePlugin/branches/1.4/web/images/sortable/icons/demote.png
===================================================================
(Binary files differ)


Property changes on: 
plugins/csDoctrineActAsSortablePlugin/branches/1.4/web/images/sortable/icons/demote.png
___________________________________________________________________
Added: svn:executable
   + 
Added: svn:mime-type
   + application/octet-stream

Added: 
plugins/csDoctrineActAsSortablePlugin/branches/1.4/web/images/sortable/icons/promote.png
===================================================================
(Binary files differ)


Property changes on: 
plugins/csDoctrineActAsSortablePlugin/branches/1.4/web/images/sortable/icons/promote.png
___________________________________________________________________
Added: svn:executable
   + 
Added: svn:mime-type
   + application/octet-stream

-- 
You received this message because you are subscribed to the Google Groups 
"symfony SVN" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/symfony-svn?hl=en.

Reply via email to