主义2可排序

时间:2010-11-18 17:33:19

标签: php doctrine-orm jquery-ui-sortable

客户需要根据需要更改项目的顺序,这意味着我需要一些“订单”或“序列”列来保存每个项目的实际位置。

如何使用Doctrine 2实现此目的?

5 个答案:

答案 0 :(得分:3)

我会使用Doctrine的event system来实现它。要添加行为,我通常会编写一个事件订阅者,并使用我的实体类实现的接口强制执行规则。我在某个服务对象中保存的实际逻辑(你自己就是这样)。

use Doctrine\Common\EventSubscriber,
    Doctrine\ORM\Events,
    Doctrine\ORM\Event\LifecycleEventArgs,
    Doctrine\ORM\Event\PreUpdateEventArgs;


class SortableBehavior implements EventSubscriber
{
   public function getSubscribedEvents()
   {
      return array(Events::prePersist, Events::preUpdate);
   }

   public function prePersist(LifeCycleEventsArgs $args)
   {
     // the entity being persisted
     $entity = $args->getEntity();
     if ($entity instanceof SortableInterface) {
        //perform sorting magic
     }
   }

   public function preUpdate(preUpdateEventsArgs $args)
   {
     // the entity being updated
     $entity = $args->getEntity();
     if ($entity instanceof SortableInterface) {
        //perform sorting magic
     }
   }
}

在引导您的应用时,不要忘记注册订阅者:

$eventManager = $entityManager->getEventManager();
$eventManager->addEventSubscriber(new SortableBehavior());

答案 1 :(得分:2)

GitHub上有一个很好的存储库,其中包含Doctrine的各种扩展,其中一个只是一个可排序的功能。

检查出来: https://github.com/l3pp4rd/DoctrineExtensions

Sortable documentation

答案 2 :(得分:0)

添加另一栏:

    sort_order:
      type: integer(4)
      default: 10

现在将该条目从10更改为其他任何内容会将其移动到结果集中,该结果集将通过以下内容检索:

$this->result = Doctrine_Core::getTable('CustomerTable')
  ->createQuery('a')->orderBy("a.sort_order asc, a.id desc")->execute();

答案 3 :(得分:0)

您可以自动检索由给定字段排序的集合:

http://www.doctrine-project.org/projects/orm/2.0/docs/reference/association-mapping/en#ordering-to-many-collections

这样您就可以使用“sort_order”列定义订单。然后,您需要一些方法来处理此问题,以便出于性能原因使用DQL Update语句正确更新排序列,即“moveTo($ pos,$ entity)”并发出相关的更新次数。

但如果你必须在同一个请求中迭代集合,那么这就解决了你的一半问题。然而,这是一种罕见的用例,因此可能经常被忽略。

答案 4 :(得分:0)

我使用EventSubscriber进行了一些测试,但无法使其正常工作,所以我决定直接将代码添加到我的班级(q& d)。我使用Zend Framework,如果您有不同的解决方案,请更改实体管理器的提取。

它的工作原理如下:

  1. 创建实体时使用getLast()并最后添加新实体($ last_entity-> getSort()+ 1)
  2. 将sortUp和sortDown函数及其子例程添加到实体代码
  3. 在您希望对其进行排序的所有DQL查询中添加“sort ASC”
  4. 实体代码如下:

    /**
     * Searches for the element above and switches them
     * with eachother. Performs a EntityManager::flush()
     * to save the results after the switch.
     */
    public function sortUp() {
    
        try {
            $em = \Zend_Registry::get("entitymanager");
    
            $class_name = get_class($this);
            $dql = "SELECT ut FROM $class_name ut WHERE ut.inactive IS NULL AND ut.inactive IS NULL AND ut.sort < '" . $this->getSort() . "' ORDER BY ut.sort DESC";
            $query = $em->createQuery($dql);
            $query->setMaxResults(1);
            $ut = $query->getResult();
        } catch (Exception $exc) {
            throw new Exception("Error when looking for sortable partner: " . $exc->getMessage());
        }
    
        if (count($ut)) {
            $this->_switchSortAndSave($ut[0]);
        }
    }
    
    /**
     * Searches for the element below and switches them
     * with eachother. Performs a EntityManager::flush()
     * to save the results after the switch.
     */
    public function sortDown() {
        try {
            $em = \Zend_Registry::get("entitymanager");
    
            $class_name = get_class($this);
            $dql = "SELECT ut FROM $class_name ut WHERE ut.inactive IS NULL AND ut.sort > '" . $this->getSort() . "' ORDER BY ut.sort ASC";
            $query = $em->createQuery($dql);
            $query->setMaxResults(1);
            $ut = $query->getResult();
        } catch (Exception $exc) {
            throw new Exception("Error when looking for sortable partner: " . $exc->getMessage());
        }
    
    
        if (count($ut)) {
            $this->_switchSortAndSave($ut[0]);
        }
    }
    
    private function _switchSortAndSave(\Entities\Usertype $switch_entity) {
        $new_sort = $switch_entity->getSort();
        $switch_entity->setSort($this->getSort());
        $this->setSort($new_sort);
    
        $em = \Zend_Registry::get("entitymanager");
        $em->persist($switch_entity);
        $em->persist($this);
        $em->flush();
    }
    
    /**
     * Looks for the last entry according to sort order
     * and returns that if found.
     * 
     * @return Entity|null
     */
    public static function findLast() {
        try {
            $em = \Zend_Registry::get("entitymanager");
    
            $class_name = get_called_class();
            $dql = "SELECT ut FROM $class_name ut ORDER BY ut.sort DESC";
            $query = $em->createQuery($dql);
            $query->setMaxResults(1);
            $ut = $query->getResult();
        } catch (Exception $exc) {
            throw new Exception("Error when searching for last $class_name: " . $exc->getMessage());
        }
    
        if (count($ut))
            return $ut[0];
        else
            return null;
    }
    

    我对这个解决方案不是很满意,所以如果有人想出一个很好的Sortable for Doctrine 2,请分享:)