Completed
Push — master ( 93324c...42664a )
by Stefano
03:18
created

Map   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 143
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 6
Bugs 3 Features 1
Metric Value
c 6
b 3
f 1
dl 0
loc 143
rs 10
wmc 27
lcom 1
cbo 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A all() 0 3 1
A exists() 0 3 1
A clear() 0 3 1
A load() 0 3 2
A get() 0 11 4
A set() 0 8 2
A delete() 0 4 2
A merge() 0 5 2
A compact() 0 13 3
B find() 0 10 7
A jsonSerialize() 0 3 1
1
<?php
2
3
/**
4
 * Map class
5
 *
6
 * The map class allow to handle a repository of key-values data.
7
 * Values are accessibles via a dot notation key path.
8
 *
9
 * @package core
10
 * @author [email protected]
11
 * @copyright Caffeina srl - 2016 - http://caffeina.com
12
 */
13
14
class Map implements JsonSerializable {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
15
16
    protected $fields = [];
17
18
    /**
19
     * Returns the map as an associative array
20
     * @return array reference
21
     */
22
    public function & all(){
23
        return $this->fields;
24
    }
25
26
    /**
27
     * Get a value assigned to a key path from the map
28
     * @param  string $key The key path of the value in dot notation
29
     * @param  mixed $default (optional) The default value. If is a callable it will executed and the return value will be used.
30
     * @return mixed The value of the key or the default (resolved) value if the key not existed.
31
     */
32
    public function get($key, $default=null){
33
        if (null !== ($ptr =& $this->find($key,false))){
34
            return $ptr;
35
        } else {
36
            if ($default !== null){
37
                return $this->set($key, is_callable($default) ? call_user_func($default) : $default);
38
            } else {
39
                return null;
40
            }
41
        }
42
    }
43
44
    /**
45
     * Set a value for a key path from map
46
     * @param  string $key The key path of the value in dot notation
47
     * @param  mixed $value (optional) The value. If is a callable it will executed and the return value will be used.
48
     * @return mixed The value of the key or the default (resolved) value if the key not existed.
49
     */
50
    public function set($key, $value=null){
51
        if (is_array($key)) {
52
            return $this->merge($key);
53
        } else {
54
            $ptr =& $this->find($key, true);
55
            return $ptr = $value;
56
        }
57
    }
58
59
    /**
60
     * Delete a value and the key path from map.
61
     * @param  string $key The key path in dot notation
62
     * @param  boolean $compact (optional) Compact map removing empty paths.
63
     */
64
    public function delete($key, $compact=true){
65
        $this->set($key, null);
66
        if ($compact) $this->compact();
67
    }
68
69
    /**
70
     * Check if a key path exists in map.
71
     * @param  string $key The key path in dot notation
72
     * @return boolean
73
     */
74
    public function exists($key){
75
        return null !== $this->find($key, false);
76
    }
77
78
    /**
79
     * Clear all key path in map.
80
     */
81
    public function clear(){
82
        $this->fields = [];
83
    }
84
85
    public function __construct($fields=null){
86
        $this->load($fields);
87
    }
88
89
    /**
90
     * Load an associative array/object as the map source.
91
     * @param  string $fields The array to merge
92
     */
93
    public function load($fields){
94
        if ($fields) $this->fields = (array)$fields;
95
    }
96
97
    /**
98
     * Merge an associative array to the map.
99
     * @param  array   $array The array to merge
100
     * @param  boolean $merge_back If `true` merge the map over the $array, if `false` (default) the reverse.
101
     */
102
    public function merge($array, $merge_back=false){
103
        $this->fields = $merge_back
104
            ? array_replace_recursive((array)$array, $this->fields)
105
            : array_replace_recursive($this->fields, (array)$array);
106
    }
107
108
    /**
109
     * Compact map removing empty paths
110
     */
111
112
    public function compact(){
113
114
        $array_filter_rec = function($input, $callback = null) use (&$array_filter_rec) {
115
            foreach ($input as &$value) {
116
                if (is_array($value)) {
117
                    $value = $array_filter_rec($value, $callback);
118
                }
119
            }
120
            return array_filter($input, $callback);
121
        };
122
123
        $this->fields = $array_filter_rec($this->fields,function($a){ return $a !== null; });
124
    }
125
126
    /**
127
     * Navigate map and find the element from the path in dot notation.
128
     * @param  string  $path Key path in dot notation.
129
     * @param  boolean $create If true will create empty paths.
130
     * @param  callable  If passed this callback will be applied to the founded value.
131
     * @return mixed The founded value.
132
     */
133
    public function & find($path, $create=false, callable $operation=null) {
134
        $create ? $value =& $this->fields : $value = $this->fields;
135
        foreach (explode('.',$path) as $tok) if ($create || isset($value[$tok])) {
136
          $value =& $value[$tok];
137
        } else {
138
          $value = $create ? $value :  null;  break;
139
        }
140
        if ( is_callable($operation) ) $operation($value);
141
        return $value;
142
    }
143
144
    /**
145
     * JsonSerializable Interface handler
146
     *
147
     * @method jsonSerialize
148
     *
149
     * @return string        The json object
150
     */
151
    public function jsonSerialize(){
152
      return $this->fields;
153
    }
154
155
156
}
157