Selaa lähdekoodia

Sortable documentation

Lukas Botsch 14 vuotta sitten
vanhempi
commit
b9d8622916
2 muutettua tiedostoa jossa 370 lisäystä ja 0 poistoa
  1. 5 0
      README.markdown
  2. 365 0
      doc/sortable.md

+ 5 - 0
README.markdown

@@ -8,6 +8,7 @@ records being flushed in the behavioral way. List of extensions:
 - Tree - this extension automates the tree handling process and adds some tree specific functions on repository. (closure or nestedset)
 - Translatable - gives you a very handy solution for translating records into diferent languages. Easy to setup, easier to use.
 - Sluggable - urlizes your specified fields into single unique slug
+- Sortable - maintains a position field for ordering entities
 - Timestampable - updates date fields on create, update and even property change.
 - Loggable - helps tracking changes and history of objects, also supports version managment.
 
@@ -35,6 +36,9 @@ use these extensions from separate branch **doctrine2.0.x** or simply checkout t
 
 ### Latest updates
 
+**2011-07-04**
+- [lbotsch](http://github.com/lbotsch) implemented the Sortable extension.
+
 **2011-06-08**
 
 - [mvrhov](http://github.com/mvrhov) implemented the XML driver for extensions and now
@@ -100,3 +104,4 @@ To setup and run tests follow these steps:
 - Christophe Coevoet [stof](http://github.com/stof)
 - Kudryashov Konstantin [everzet](http://github.com/everzet)
 - Klein Florian [docteurklein](http://github.com/docteurklein)
+- Lukas Botsch [lbotsch](http://github.com/lbotsch)

+ 365 - 0
doc/sortable.md

@@ -0,0 +1,365 @@
+# Sortable behavior extension for Doctrine 2
+
+**Sortable** behavior will maintain a position field for ordering
+entities.
+
+Features:
+
+- Automatic handling of position index
+- Group entity ordering by one or more fields
+- Can be nested with other behaviors
+- Annotation, Yaml and Xml mapping support for extensions
+
+**Notice:**
+
+- Public [Sortable repository](http://github.com/lbotsch/DoctrineExtensions "Sortable extension on Github") is available on github
+- Last update date: **2011-06-08**
+
+**Portability:**
+
+- **Sortable** is now available as [Bundle](http://github.com/stof/DoctrineExtensionsBundle)
+ported to **Symfony2** by **Christophe Coevoet**, together with all other extensions
+
+This article will cover the basic installation and functionality of **Sortable**
+behavior
+
+Content:
+
+- [Including](#including-extension) the extension
+- [Attaching](#event-listener) the **Sortable Listener**
+- Entity [example](#entity)
+- [Yaml](#yaml) mapping example
+- [Xml](#xml) mapping example
+- Basic usage [examples](#basic-examples)
+- Advanced usage [examples](#advanced-examples)
+
+
+## Setup and autoloading {#including-extension}
+
+If you are using the source from github repository, initial directory structure for
+the extension library should look like this:
+
+    ...
+    /DoctrineExtensions
+        /lib
+            /Gedmo
+                /Exception
+                /Loggable
+                /Mapping
+                /Sluggable
+                /Sortable
+                /Timestampable
+                /Translatable
+                /Tree
+        /tests
+            ...
+    ...
+
+First of all we need to setup the autoloading of extensions:
+
+    $classLoader = new \Doctrine\Common\ClassLoader('Gedmo', "/path/to/library/DoctrineExtensions/lib");
+    $classLoader->register();
+
+### Attaching the Sortable Listener to the event manager {#event-listener}
+
+To attach the **Sortable Listener** to your event system:
+
+    $evm = new \Doctrine\Common\EventManager();
+    // ORM
+    $sortableListener = new \Gedmo\Sortable\SortableListener();
+    
+    $evm->addEventSubscriber($sortableListener);
+    // now this event manager should be passed to entity manager constructor
+
+## Sortable Entity example: {#entity}
+
+### Sortable annotations:
+
+- **@gedmo:SortableGroup** it will use this field for **grouping**
+- **@gedmo:SortablePosition** it will use this column to store **position** index
+
+**Notice:** that Sortable interface is not necessary, except in cases there
+you need to identify entity as being Sortable. The metadata is loaded only once then
+cache is activated
+
+    namespace Entity;
+    
+    /**
+     * @Table(name="items")
+     * @Entity
+     */
+    class Item
+    {
+        /** @Id @GeneratedValue @Column(type="integer") */
+        private $id;
+    
+        /**
+         * @Column(name="name", type="string", length=64)
+         */
+        private $name;
+    
+        /**
+         * @gedmo:SortablePosition
+         * @Column(name="position", type="integer")
+         */
+        private $position;
+    
+        /**
+         * @gedmo:SortableGroup
+         * @Column(name="category", type="string", length=128)
+         */
+        private $category;
+    
+        public function getId()
+        {
+            return $this->id;
+        }
+    
+        public function setName($name)
+        {
+            $this->name = $name;
+        }
+    
+        public function getName()
+        {
+            return $this->name;
+        }
+    
+        public function setPosition($position)
+        {
+            $this->position = $position;
+        }
+    
+        public function getPosition()
+        {
+            return $this->position;
+        }
+        
+        public function setCategory($category)
+        {
+            $this->category = $category;
+        }
+        
+        public function getCategory()
+        {
+            return $this->category;
+        }
+    }
+
+
+## Yaml mapping example {#yaml}
+
+Yaml mapped Item: **/mapping/yaml/Entity.Item.dcm.yml**
+
+    ---
+    Entity\Item:
+      type: entity
+      table: items
+      id:
+        id:
+          type: integer
+          generator:
+            strategy: AUTO
+      fields:
+        name:
+          type: string
+          length: 64
+        position:
+          type: integer
+          gedmo:
+            - sortablePosition
+        category:
+          type: string
+          length: 128
+          gedmo:
+            - sortableGroup
+
+## Xml mapping example {#xml}
+
+    <?xml version="1.0" encoding="UTF-8"?>
+    <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
+                      xmlns:gedmo="http://gediminasm.org/schemas/orm/doctrine-extensions-mapping">
+        <entity name="Entity\Item" table="items">
+            <id name="id" type="integer" column="id">
+                <generator strategy="AUTO"/>
+            </id>
+    
+            <field name="name" type="string" length="128">
+            </field>
+            
+            <field name="position" type="integer">
+                <gedmo:sortable-position/>
+            </field>
+            <field name="category" type="string" length="128">
+                <gedmo:sortable-group />
+            </field>
+        </entity>
+    </doctrine-mapping>
+
+## Basic usage examples: {#basic-examples}
+
+### To save **Items** at the end of the sorting list simply do:
+
+    // By default, items are appended to the sorting list
+    $item1 = new Item();
+    $item1->setName('item 1');
+    $item1->setCategory('category 1');
+    $this->em->persist($item1);
+    
+    $item2 = new Item();
+    $item2->setName('item 2');
+    $item2->setCategory('category 1');
+    $this->em->persist($item2);
+    
+    $this->em->flush();
+    
+    echo $item1->getPosition();
+    // prints: 0
+    echo $item2->getPosition();
+    // prints: 1
+
+### Save **Item** at a given position:
+
+    $item1 = new Item();
+    $item1->setName('item 1');
+    $item1->setCategory('category 1');
+    $this->em->persist($item1);
+    
+    $item2 = new Item();
+    $item2->setName('item 2');
+    $item2->setCategory('category 1');
+    $this->em->persist($item2);
+    
+    $item0 = new Item();
+    $item0->setName('item 0');
+    $item0->setCategory('category 1');
+    $item0->setPosition(0);
+    $this->em->persist($item0);
+    
+    $this->em->flush();
+    $this->em->clear();
+    
+    $repo = $this->em->getRepository('Entity\\Item');
+    $items = $repo->getBySortableGroupsQuery(array('category' => 'category 1'));
+    foreach ($items as $item) {
+        echo "{$item->getPosition()}: {$item->getName()}\n";
+    }
+    // prints:
+    // 0: item 0
+    // 1: item 1
+    // 2: item 2
+    
+    
+### Reordering the sorted list:
+
+    $item1 = new Item();
+    $item1->setName('item 1');
+    $item1->setCategory('category 1');
+    $this->em->persist($item1);
+    
+    $item2 = new Item();
+    $item2->setName('item 2');
+    $item2->setCategory('category 1');
+    $this->em->persist($item2);
+    
+    $this->em->flush();
+    
+    // Update the position of item2
+    $item2->setPosition(0);
+    $this->em->persist($item2);
+    
+    $this->em->clear();
+    
+    $repo = $this->em->getRepository('Entity\\Item');
+    $items = $repo->getBySortableGroupsQuery(array('category' => 'category 1'));
+    foreach ($items as $item) {
+        echo "{$item->getPosition()}: {$item->getName()}\n";
+    }
+    // prints:
+    // 0: item 2
+    // 1: item 1
+
+## Advanced examples: {#advanced-examples}
+
+### Using TranslationListener to translate our slug
+
+If you want to attach **TranslationListener** also add it to EventManager after
+the **SluggableListener**. It is important because slug must be generated first
+before the creation of it`s translation.
+
+    $evm = new \Doctrine\Common\EventManager();
+    $sluggableListener = new \Gedmo\Sluggable\SluggableListener();
+    $evm->addEventSubscriber($sluggableListener);
+    $translatableListener = new \Gedmo\Translatable\TranslationListener();
+    $translatableListener->setTranslatableLocale('en_us');
+    $evm->addEventSubscriber($translatableListener);
+    // now this event manager should be passed to entity manager constructor
+
+And the Entity should look like:
+
+    namespace Entity;
+    
+    /**
+     * @Table(name="articles")
+     * @Entity
+     */
+    class Article
+    {
+        /** @Id @GeneratedValue @Column(type="integer") */
+        private $id;
+    
+        /**
+         * @gedmo:Translatable
+         * @gedmo:Sluggable
+         * @Column(name="title", type="string", length=64)
+         */
+        private $title;
+    
+        /**
+         * @gedmo:Translatable
+         * @gedmo:Sluggable
+         * @Column(name="code", type="string", length=16)
+         */
+        private $code;
+    
+        /**
+         * @gedmo:Translatable
+         * @gedmo:Slug
+         * @Column(name="slug", type="string", length=128, unique=true)
+         */
+        private $slug;
+    
+        public function getId()
+        {
+            return $this->id;
+        }
+    
+        public function setTitle($title)
+        {
+            $this->title = $title;
+        }
+    
+        public function getTitle()
+        {
+            return $this->title;
+        }
+    
+        public function setCode($code)
+        {
+            $this->code = $code;
+        }
+    
+        public function getCode()
+        {
+            return $this->code;
+        }
+    
+        public function getSlug()
+        {
+            return $this->slug;
+        }
+    }
+
+Now the generated slug will be translated by Translatable behavior
+
+Easy like that, any suggestions on improvements are very welcome