Completed
Push — master ( f7852e...e666ea )
by Richard
06:08
created

QueryImpl::run_expand()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3.0123

Importance

Changes 0
Metric Value
dl 0
loc 11
ccs 8
cts 9
cp 0.8889
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 8
nc 4
nop 2
crap 3.0123
1
<?php
2
/******************************************************************************
3
 * An implementation of dicto (scg.unibe.ch/dicto) in and for PHP.
4
 * 
5
 * Copyright (c) 2016 Richard Klees <[email protected]>
6
 *
7
 * This software is licensed under The MIT License. You should have received 
8
 * a copy of the license along with the code.
9
 */
10
11
namespace Lechimp\Dicto\Graph;
12
13
class QueryImpl implements Query {
14
    /**
15
     * @var Graph
16
     */
17
    protected $graph;
18
19
    /**
20
     * @var array[]
21
     */
22
    protected $steps;
23
24 61
    public function __construct(Graph $graph) {
25 61
        $this->graph = $graph;
26 61
        $this->steps = [];
27 61
    }
28
29
    /**
30
     * @inheritdocs
31
     */
32 25
    public function expand(\Closure $expander) {
33 25
        $clone = clone $this;
34 25
        $clone->steps[] = ["expand", $expander];
35 25
        assert('$this->steps != $clone->steps');
36 25
        return $clone;
37
    }
38
39
    /**
40
     * @inheritdocs
41
     */
42 61
    public function extract(\Closure $extractor) {
43 61
        $clone = clone $this;
44 61
        $clone->steps[] = ["extract", $extractor];
45 61
        assert('$this->steps != $clone->steps');
46 61
        return $clone;
47
    }
48
49
    /**
50
     * @inheritdocs
51
     */
52 55
    public function filter(\Closure $filter) {
53 55
        $clone = clone $this;
54 55
        $clone->steps[] = ["filter", $filter];
55 55
        assert('$this->steps != $clone->steps');
56 55
        return $clone;
57
    }
58
59
    /**
60
     * @inheritdocs
61
     */
62 61
    public function run($result) {
63 61
        $nodes = $this->add_result($this->graph->nodes(), $result);
64
65 61
        foreach ($this->steps as $step) {
66 61
            if (count($nodes) == 0) {
67 15
                return [];
68
            }
69
70 60
            list($cmd,$clsr) = $step;
71 60
            if ($cmd == "expand") {
72 22
                $nodes = $this->run_expand($nodes, $clsr);
73 22
            }
74 59
            elseif ($cmd == "extract") {
75 46
                $this->run_extract($nodes, $clsr);
76 46
            }
77 55
            elseif ($cmd == "filter") {
78 55
                $nodes = $this->run_filter($nodes, $clsr);
79 55
            }
80
            else {
81
                throw new \LogicException("Unknown command: $cmd");
82
            }
83 60
        }
84
85 46
        return array_values(array_map(function($r) {
86 46
            return $r[1];
87 46
        }, $nodes));
88
    }
89
90 22
    protected function run_expand(array &$nodes, \Closure $clsr) {
91 22
        $new_nodes = [];
92 22
        foreach ($nodes as $r) {
93 22
            list($node, $result) = $r;
94 22
            $new_nodes[] = $this->add_result($clsr($node), $result);
95 22
        }
96 22
        if (count($new_nodes) == 0) {
97
            return [];
98
        }
99 22
        return call_user_func_array("array_merge", $new_nodes);
100
    }
101
102 46
    protected function run_extract(array &$nodes, \Closure $clsr) {
103 46
        foreach ($nodes as $i => $r) {
104 46
            list($node, $result) = $r;
105 46
            if (is_object($result)) {
106
                $clsr($node, clone $result);
107
            }
108
            else {
109 46
                $clsr($node, $result);
110
            }
111 46
            $nodes[$i][1] = $result;
112 46
        }
113 46
    }
114
115 55
    protected function run_filter(array &$nodes, \Closure $clsr) {
116 55
        $res = [];
117 55
        foreach ($nodes as $r) {
118 55
            list($node, $result) = $r;
119 55
            if ($clsr($node, $result)) {
120 52
                $res[] = $r;
121 52
            }
122 55
        }
123 55
        return $res;
124
    }
125
126 61
    protected function add_result(array $nodes, &$result) {
127 61
        $res = [];
128 61
        foreach ($nodes as $node) {
129 60
            $res[] = [$node, $result];
130 61
        }
131 61
        return $res;
132
    }
133
}
134