Symfony: Optgroup в DoctrineChoice

Потребовалось мне сделать optgroup в виджете choice, и не просто так, а с условием. Если у объекта есть дочерние элементы — то он становится optgroup, а иначе его можно выбрать. За основу я взял sfWidgetFormDoctrineChoiceNestedSet, который можно взять из плагина sfDoctrineNestedSetPlugin. Я скопировал код, добавил в запрос условие:

$query->addWhere('level = ?', 0);

Это потому, что все, что ниже уровнем мы будем получать через getChildren. Иначе нам пришлось бы двигать итератор Doctrine_Collection, что более сложно, заумно, и вовсе у меня не получилось (next($objects) почему-то не дает эффекта).
Сделать optgroup в choice совсем несложно, надо лишь сделать элемент массивом. Ну а что получилось собственно внутри поста.

Я еще раз повторюсь, что это код sfWidgetFormDoctrineChoiceNestedSet, за малым изменением.

class weDoctineOptgroupSelectWidget extends sfWidgetFormDoctrineChoice {   public function getChoices() { $choices = array(); if (false !== $this->getOption(‘add_empty’)) { $choices[”] = true === $this->getOption(‘add_empty’) ? ” : $this->getOption(‘add_empty’); }   if (null === $this->getOption(‘table_method’)) { $query = null === $this->getOption(‘query’) ? Doctrine_Core::getTable($this->getOption(‘model’))->createQuery() : $this->getOption(‘query’); // force manual sorting according to root_id then by lft $query->addOrderBy(‘root_id asc’) ->addOrderBy(‘lft asc’); // Viktoras: we need to fetch only top level, as we’ll get the children with getChildren() $query->addWhere(‘level = ?’, 0); $objects = $query->execute(); } else { $tableMethod = $this->getOption(‘table_method’); $results = Doctrine_Core::getTable($this->getOption(‘model’))->$tableMethod();   if ($results instanceof Doctrine_Query) { $objects = $results->execute(); } else if ($results instanceof Doctrine_Collection) { $objects = $results; } else if ($results instanceof Doctrine_Record) { $objects = new Doctrine_Collection($this->getOption(‘model’)); $objects[] = $results; } else { $objects = array(); } }   $method = $this->getOption(‘method’); $keyMethod = $this->getOption(‘key_method’);   foreach ($objects as $object) { // indent item by 4 spaces per level // Viktoras: here we check for children and make entry an array if they exists $node = $object->getNode(); if ($node->hasChildren()) { foreach ($node->getChildren() as $child) { $choices[$object->$method()][$child->$keyMethod()] = str_repeat(‘ ’, ($child[‘level’] * 4)) . $child->$method(); } } else { $choices[$object->$keyMethod()] = str_repeat(‘ ’, ($object[‘level’] * 4)) . $object->$method(); }   } return $choices; }   }

Leave a Reply

Your email address will not be published. Required fields are marked *