2010-11-12 8 views
8

Ho una struttura che rappresenta un modulo e desidero iterarlo utilizzando RecursiveIterator. Il problema è che restituisce solo le domande di livello superiore. Che cosa sto facendo di sbagliato?PHP RecursiveIterator che attraversa

forma totale:

class Form implements RecursiveIterator{ 
    private $id; 
    private $caption; 
    private $other_text; 
    private $questions = array(); 
    private $current; 

    private function __construct(DibiRow $row){ 
     $this->id = $row->id; 
     $this->caption = $row->caption; 
     $this->other_text = $row->other_text; 
     $this->loadQuestions(); 
    } 

    private function loadQuestions(){ 
     $questions = dibi::query('SELECT * FROM cyp_questions WHERE form_id = %i AND parent_id IS NULL', $this->id); 
     while($question = $questions->fetch()) $this->questions[] = new Question($question->question_id, $question->type, $question->caption, $question->other_text, $question->triggers_unique == 1); 
    } 

    /** 
    * @throws InvalidArgumentException 
    * @param $id 
    * @return Form 
    */ 
    public static function loadById($id){ 
     $form = dibi::query('SELECT * FROM cyp_forms WHERE id = %i', $id)->fetch(); 
     if($form === false) throw new InvalidArgumentException('Form with id '.$id.' was not found.'); 

     return new Form($form); 
    } 

    /** 
    * @throws FormFieldException 
    * @return bool 
    */ 
    public function validate($postfields){ 

    } 

    public function getQuestions(){ 
     return $this->questions; 
    } 

    public function getChildren(){ 
     return $this->questions[$this->current]; 
    } 

    public function hasChildren(){ 
     return count($this->questions) > 0; 
    } 

    public function current(){ 
     return $this->questions[$this->current]; 
    } 

    public function key(){ 
     return $this->current; 
    } 

    public function next(){ 
     $this->current++; 
    } 

    public function rewind(){ 
     $this->current = 0; 
    } 

    public function valid(){ 
     return isset($this->questions[$this->current]); 
    } 
} 

Domanda:

class Question implements RecursiveIterator{ 
    private $id; 
    private $type; 
    private $answers = array(); 
    private $subquestions = array(); 
    private $other_text; 
    private $triggers_unique; 
    private $caption; 
    private $current = 0; 


    public function __construct($id, $type, $caption, $other_text = null, $triggers_unique = false){ 
     $this->id = $id; 
     $this->type = $type; 
     $this->caption = $caption; 
     $this->other_text = $other_text; 
     $this->triggers_unique = $triggers_unique; 
     $this->setSubQuestions(); 

    } 

    private function setSubQuestions(){ 
     $questions = dibi::query('SELECT * FROM cyp_questions WHERE parent_id = %i', $this->id); 
     while($question = $questions->fetch()) $this->subquestions[] = new Question($question->question_id, $question->type, $question->caption, $question->other_text, $question->triggers_unique == 1); 
    } 

    public function getOtherText(){ 
     return $this->other_text; 
    } 

    public function getCaption(){ 
     return $this->caption; 
    } 

    public function addAnswer($answer){ 
     $this->answers[] = $answer; 
    } 

    public function getChildren(){ 
     return $this->subquestions[$this->current]; 
    } 

    public function hasChildren(){ 
     return count($this->subquestions) > 0; 
    } 

    public function current(){ 
     return $this->subquestions[$this->current]; 
    } 

    public function key(){ 
     return $this->id; 
    } 

    public function next(){ 
     ++$this->current; 
    } 

    public function rewind(){ 
     $this->current = 0; 
    } 

    public function valid(){ 
     return isset($this->subquestions[$this->current]); 
    } 

    public function getAnswers(){ 
     return $this->answers; 
    } 


} 

Iterazione:

$form = Form::loadById(1); 

foreach($form as $question){ 
    echo $question->getCaption().'<br />'; 
} 

risposta

9

Per iterare su RecursiveIterator, è necessario inserirlo in un RecursiveIteratorIterator.

vedere alcuni esempi in

L'impostazione predefinita in modalità di iterazione è solo quello di elencare le foglie. Se vuoi anche che i nodi contenenti vengano visualizzati nell'iterazione, passa il RecursiveIteratorIterator::SELF_FIRST come secondo argomento al costruttore del RecursiveIteratorIterator

2

Beh, come si può vedere here

public RecursiveIterator RecursiveIterator::getChildren (void) 

Returns an iterator for the current iterator entry. 

il metodo deve restituire un oggetto che implementa l'iteratore. Il tuo metodo restituisce un array semplice.

La mia ipotesi sarebbe quella di restituire qualcosa del genere:

public function getChildren(){ 
    return new Question($this->subquestions); 
} 

Questo perché si sta utilizzando un iteratore RECURSIVE quindi è aspettato di avere ogni nodo dell'albero dello stesso tipo (un iteratore)

+0

Sì, ora ho questo, ma il problema sono solo i nodi di livello superiore e io davvero don ' so cosa fare Posterò l'intero codice – cypher

+0

Ok, ho pubblicato il tutto, per favore dai un'occhiata. – cypher

Problemi correlati