1<?php
2
3/**
4 * Class CompositeBuilder
5 *
6 * Date: 27.03.13
7 * Time: 12:18
8 * @author Thomas Joußen <tjoussen@databay.de>
9 */
10class ilAssLacCompositeBuilder
11{
12
13    /**
14     * This array defines the weights and direction of operators.<br />
15     * It is required to build the composite tree with the correct depth structure
16     *
17     * @var array
18     */
19    protected $operators = array('<=','<','=','>=','>','<>','&','|');
20
21    /**
22     * Construct requirements
23     */
24    public function __construct()
25    {
26        include_once 'Modules/TestQuestionPool/classes/questions/LogicalAnswerCompare/Factory/ilAssLacOperationManufacturer.php';
27        include_once 'Modules/TestQuestionPool/classes/questions/LogicalAnswerCompare/Factory/ilAssLacExpressionManufacturer.php';
28    }
29
30    /**
31     * @param array $nodes
32     *
33     * @return array
34     */
35    public function create($nodes)
36    {
37        if ($nodes['type'] == 'group') {
38            foreach ($nodes['nodes'] as $key => $child) {
39                $nodes['nodes'][$key] = $this->create($child);
40            }
41
42            foreach ($this->operators as $next_operator) {
43                do {
44                    $index = -1;
45                    for ($i = 0; $i < count($nodes['nodes']); $i++) {
46                        if (!is_object($nodes['nodes'][$i]) && $nodes['nodes'][$i]['type'] == 'operator' && $nodes['nodes'][$i]['value'] == $next_operator) {
47                            $index = $i;
48                            break;
49                        }
50                    }
51                    if ($index >= 0) {
52                        $operation_manufacture = ilAssLacOperationManufacturer::_getInstance();
53                        $operator = $operation_manufacture->manufacture($nodes['nodes'][$index]['value']);
54
55                        $operator->setNegated($nodes["negated"]);
56                        $operator->addNode($this->getExpression($nodes, $index - 1));
57                        $operator->addNode($this->getExpression($nodes, $index + 1));
58
59                        $new_nodes = array_slice($nodes['nodes'], 0, $index - 1);
60                        $new_nodes[] = $operator;
61                        $nodes['nodes'] = array_merge($new_nodes, array_slice($nodes['nodes'], $index + 2));
62                    }
63                } while ($index >= 0);
64            }
65            return $nodes['nodes'][0];
66        }
67        return $nodes;
68    }
69
70    /**
71     * Manufacure an expression from the delivered node and the index. If an expression already exist in the node for<br />
72     * for the delivered index, this function will return the existing expression
73     *
74     * @param array $node
75     * @param int $index
76     *
77     * @return ilAssLacCompositeInterface
78     */
79    private function getExpression(array $node, $index)
80    {
81        $manufacturer = ilAssLacExpressionManufacturer::_getInstance();
82
83        $expression = $node['nodes'][$index];
84        if (!($expression instanceof ilAssLacAbstractComposite)) {
85            $expression = $manufacturer->manufacture($node['nodes'][$index]['value']);
86        }
87        return $expression;
88    }
89}
90