1: <?php
2:
3: namespace Alchemy\core\query;
4: use Alchemy\core\Element;
5:
6:
7: 8: 9:
10: class Expression extends Element {
11:
12: protected $elements = array();
13:
14:
15: public static function __callStatic($name, $args) {
16: $def = self::get_definition(trim(strtolower($name), '_'));
17: $elements = (isset($args[0]) && is_array($args[0])) ? $args[0] : $args;
18:
19: return new $def['tags']['element.class']($def['tags']['element.type'], $elements);
20: }
21:
22:
23: public function __construct($type, array $elements) {
24: parent::__construct($type);
25: $cls = get_called_class();
26:
27: $def = self::get_definition($type);
28: $tag = $def['tags']['expr.element'];
29:
30: if ($def['arity'] != -1 && $def['arity'] != count($elements)) {
31: throw new \Exception("{$cls} '{$type}': Expected {$def['arity']} elements, got " . count($elements));
32: }
33:
34: foreach ($elements as $element) {
35: if (!$element->getTag($tag)) {
36: throw new \Exception("{$cls} '{$type}': Expected '{$tag}' at position {$key}");
37: }
38: }
39:
40: $this->elements = $elements;
41: }
42:
43:
44: public function getDescription($maxdepth = 3, $curdepth = 0) {
45: $str = parent::getDescription($maxdepth, $curdepth);
46:
47: if ($curdepth <= $maxdepth) {
48: $i = str_repeat(' ', $curdepth);
49: $elements = array();
50: foreach($this->elements as $element) {
51: $elements[] = $element->getDescription($maxdepth, $curdepth + 1);
52: }
53:
54: $str .= " [\n$i ".implode(",\n$i ", $elements)."\n$i]";
55: }
56:
57: return $str;
58: }
59:
60:
61: public function elements() {
62: return $this->elements;
63: }
64:
65:
66: 67: 68: 69: 70:
71: public function parameters() {
72: $params = array();
73:
74: foreach ($this->elements as $element) {
75: if (method_exists($element, 'parameters')) {
76: $params = array_merge($params, $element->parameters());
77: }
78: }
79:
80: return $params;
81: }
82:
83:
84: public function tables() {
85: $tables = array();
86:
87: foreach($this->elements as $element) {
88: if ($element instanceof Expression) {
89: $tables += $element->tables();
90: } elseif ($element instanceof ColumnRef) {
91: $tables[$element->table()->getID()] = $element->table();
92: }
93: }
94:
95: return $tables;
96: }
97: }
98: