:-)
  • Потребовалось мне сделать 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;
      }
     
    }

    И выглядит это вот так:

    Tags: , , ,

  • Оставить комментарий

    Внимание: Комментарии проходят премодерацию. Не надо посылать их несколько раз.