Completed
Pull Request — master (#5)
by Moesjarraf
09:47
created

DataEnricher::hasProcessorProperty()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 10
rs 9.4285
cc 1
eloc 6
nc 1
nop 1
1
<?php
2
3
namespace LegalThings;
4
5
use LegalThings\DataEnricher\Node;
6
use LegalThings\DataEnricher\Processor;
7
8
/**
9
 * Enrich objects by processing special properties.
10
 */
11
class DataEnricher
12
{
13
    /**
14
     * Default processors
15
     * @var array
16
     */
17
    public static $defaultProcessors = [
18
        '_ref' => Processor\Reference::class,
19
        '_switch' => Processor\SwitchChoose::class,
20
        '_src' => Processor\Http::class,
21
        '_merge' => Processor\Merge::class,
22
        '_jmespath' => Processor\JmesPath::class,
23
        '_tpl' => Processor\Mustache::class
24
    ];
25
    
26
    
27
    /**
28
     * @var object
29
     */
30
    protected $source;
31
    
32
    /**
33
     * Processors, applied in specified order.
34
     * 
35
     * @var DataEnricher\Processor[]
36
     */
37
    public $processors;
38
    
39
    
40
    /**
41
     * Class constructor
42
     * 
43
     * @param object $source  Data source
44
     */
45
    public function __construct($source)
46
    {
47
        if (!is_object($source)) {
48
            throw new \Exception("Data enricher on works on an object, not on a " . gettype($source));
49
        }
50
        
51
        $this->source = $source;
52
        
53
        foreach (static::$defaultProcessors as $property => $processor) {
54
            if (is_string($processor)) {
55
                $class = $processor;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
56
                $processor = new $class($this, $property);
57
            }
58
            
59
            $this->processors[] = $processor;
60
        }
61
    }
62
    
63
    /**
64
     * Get the source object
65
     * 
66
     * @return object
67
     */
68
    public function getSource()
69
    {
70
        return $this->source;
71
    }
72
    
73
    
74
    /**
75
     * Invoke enricher 
76
     * 
77
     * @param array|object|string $target  Target or dot key path
78
     */
79
    public function applyTo($target)
80
    {
81
        if (is_string($target)) {
82
            $target = \DotKey::on($this->source)->get($target);
83
        }
84
        
85
        $nodes = $this->findNodes($target);
86
        
87
        foreach ($this->processors as $processor) {
88
            $processor->applyTo($nodes);
89
        }
90
        
91
        $this->applyNodeResults($target);
92
    }
93
94
    /**
95
     * Find nodes that have processing instructions
96
     * 
97
     * @param array|object $target
98
     * @return array
99
     */
100
    public function findNodes(&$target)
101
    {
102
        $nodes = [];
103
        
104
        foreach ($target as $key => &$value) {
105
            if (is_array($value) || (is_object($value) && !$value instanceof Node)) {
106
                $nodes = array_merge($nodes, $this->findNodes($value));
107
            }
108
            
109
            if ($value instanceof \stdClass && $this->hasProcessorProperty($value)) {
110
                $value = new Node($value);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
111
                $nodes[] = $value;
112
            }
113
        }
114
        
115
        return $nodes;
116
    }
117
    
118
    /**
119
     * Check if object has at leas one process property
120
     * 
121
     * @param \stdClass $value
122
     * @return boolean
123
     */
124
    protected function hasProcessorProperty($value)
125
    {
126
        $processorProps = array_map(function ($processor) {
127
            return $processor->getProperty();
128
        }, $this->processors);
129
        
130
        $valueProps = array_keys(get_object_vars($value));
131
        
132
        return count(array_intersect($valueProps, $processorProps)) > 0;
133
    }
134
    
135
    /**
136
     * Replace nodes with their results
137
     * 
138
     * @param array|object $target
139
     */
140
    public function applyNodeResults(&$target)
141
    {
142
        foreach ($target as &$value) {
143
            if ($value instanceof Node) {
144
                $value = $value->getResult();
145
            } elseif (is_array($value) || is_object($value)) {
146
                $this->applyNodeResults($value);
147
            }
148
        }
149
    }
150
    
151
    /**
152
     * Enrich object
153
     * 
154
     * @param object $subject
155
     */
156
    public static function process($subject)
157
    {
158
        $enrich = new static($subject);
159
        $enrich->applyTo($subject);
160
    }
161
}
162