Completed
Push — master ( 1857e6...d96bec )
by Joao Gilberto
03:02
created

SerializerObject::buildObject()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 22
rs 8.9197
cc 4
eloc 12
nc 4
nop 1
1
<?php
2
3
namespace ByJG\AnyDataset\Model;
4
5
use stdClass;
6
7
class SerializerObject
8
{
9
10
    const CLASS_REFL = "ClassRefl";
11
    const CLASS_NAME = "ClassName";
12
    const CLASS_GETTER = "ClassGetter";
13
    const CLASS_PROPERTY_PATTERN = "ClassPropertyPattern";
14
    const CLASS_WRITE_EMPTY = "ClassWriteEmpty";
15
    const CLASS_DOC_TYPE = "ClassDocType";
16
    const CLASS_RDF_TYPE = "ClassRdfType";
17
    const CLASS_RDF_ABOUT = "ClassRdfAbout";
18
    const CLASS_DEFAULT_PREFIX = "ClassDefaultPrefix";
19
    const CLASS_IS_RDF = "ClassIsRDF";
20
    const CLASS_IGNORE_ALL_CLASS = "ClassIgnoreAllClass";
21
    const CLASS_NAMESPACE = "ClassNamespace";
22
    const CLASS_DONT_CREATE_NODE_CLASS = "ClassDontCreateClassNode";
23
    const PROP_IGNORE = "PropIgnore";
24
    const PROP_NAME = "PropName";
25
    const PROP_ATTRIBUTE_OF = "PropAttributeOf";
26
    const PROP_IS_BLANK_NODE = "PropIsBlankNode";
27
    const PROP_IS_RESOURCE_URI = "PropIsResourceUri";
28
    const PROP_IS_CLASS_ATTR = "PropIsClassAttr";
29
    const PROP_DONT_CREATE_NODE = "PropDontCreateNode";
30
    const PROP_FORCE_NAME = "PropForceName";
31
    const PROP_VALUE = 'PropValue';
32
    const OBJECT_ARRAY_IGNORE_NODE = '__object__ignore';
33
    const OBJECT_ARRAY = '__object';
34
35
    protected $_config = "xmlnuke";
36
    protected $_forcePropName;
37
    protected $_current;
38
    protected $_node = null;
39
    protected $_parentArray = false;
40
    protected $_currentArray = false;
41
42
    protected $objectInfo = null;
43
44
    protected $nodeRefs = [];
45
46
47
    protected $_model = null;
48
    protected $_methodPattern = ['/([^A-Za-z0-9])/', ''];
49
    protected $_methodGetPrefix = 'get';
50
    protected $_stopFirstLevel = false;
51
    protected $_currentLevel = 0;
52
53
    public function __construct($model)
54
    {
55
        $this->_model = $model;
56
    }
57
58
    /**
59
     * @param $key
60
     * @return array
61
     */
62
    public function getMethodPattern($key)
63
    {
64
        return $this->_methodPattern[$key];
65
    }
66
67
    /**
68
     * @param $search
69
     * @param $replace
70
     * @internal param array $methodPattern
71
     */
72
    public function setMethodPattern($search, $replace)
73
    {
74
        $this->_methodPattern = [$search, $replace];
75
    }
76
77
    /**
78
     * @return string
79
     */
80
    public function getMethodGetPrefix()
81
    {
82
        return $this->_methodGetPrefix;
83
    }
84
85
    /**
86
     * @param string $methodGetPrefix
87
     */
88
    public function setMethodGetPrefix($methodGetPrefix)
89
    {
90
        $this->_methodGetPrefix = $methodGetPrefix;
91
    }
92
93
    /**
94
     * @return bool
95
     */
96
    public function getStopFirstLevel()
97
    {
98
        return $this->_stopFirstLevel;
99
    }
100
101
    /**
102
     * @param bool $stopAtFirstLevel
103
     */
104
    public function setStopFirstLevel($stopAtFirstLevel)
105
    {
106
        $this->_stopFirstLevel = $stopAtFirstLevel;
107
    }
108
109
    public function build()
110
    {
111
        $this->_currentLevel = 1;
112
        return $this->buildProperty($this->_model);
113
    }
114
115
    public function buildProperty($property)
116
    {
117
        if ($this->getStopFirstLevel() && $this->_currentLevel > 1) {
118
            return $property;
119
        }
120
121
        if (is_array($property)) {
122
            return $this->buildArray($property);
123
        }
124
125
        if ($property instanceof \stdClass) {
126
            return $this->buildStdClass($property);
127
        }
128
129
        if (is_object($property)) {
130
            return $this->buildObject($property);
131
        }
132
133
        return $property;
134
    }
135
136
    /**
137
     * @param array $array
138
     * @return array
139
     */
140
    public function buildArray(array $array)
141
    {
142
        $result = [];
143
        $this->_currentLevel++;
144
145
        foreach ($array as $key=>$value)
146
        {
147
            $result[$key] = $this->buildProperty($value);
148
        }
149
150
        return $result;
151
    }
152
153
    /**
154
     * @param stdClass $stdClass
155
     * @return array
156
     */
157
    public function buildStdClass(\stdClass $stdClass)
158
    {
159
        return $this->buildArray((array)$stdClass);
160
    }
161
    
162
    public function buildObject($object)
163
    {
164
        $result = [];
165
        $this->_currentLevel++;
166
167
        foreach ((array)$object as $key=>$value) {
168
169
            if ($key[0] == "\0") {
170
                // validate protected;
171
                $keyName = substr($key, strrpos($key, "\0"));
172
                $propertyName = preg_replace($this->getMethodPattern(0), $this->getMethodPattern(1), $keyName);
173
174
                if (method_exists($object, $this->getMethodGetPrefix() . $propertyName)) {
175
                    $result[$propertyName] = $this->buildProperty($value);
176
                }
177
            } else {
178
                $result[$key] = $this->buildProperty($value);
179
            }
180
        }
181
182
        return $result;
183
    }
184
185
186
//    /**
0 ignored issues
show
Unused Code Comprehensibility introduced by Joao Gilberto Magalhães
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
187
//     *
188
//     * @param DOMNode $current Current Dom Node
189
//     * @param mixed $model Array or instance of object model
190
//     * @param string $config The name of comment inspector
191
//     * @param string $forcePropName force a name
192
//     * @throws InvalidArgumentException
193
//     */
194
//    public function __construct($current, $model, $config = "xmlnuke", $forcePropName = "", $parentArray = false)
195
//    {
196
//        // Setup
197
//        $this->_current = $current;
198
//        $this->_config = $config;
199
//        $this->_forcePropName = $forcePropName;
200
//
201
//        // Define the parentArray
202
//        $this->_parentArray = $parentArray;
203
//
204
//        // Check the proper treatment
205
//        if (is_array($model)) {
206
//            $this->_model = (object) $model;
207
//            $this->_currentArray = true;
208
//
209
//            // Fix First Level non-associative arrays
210
//            if (count(get_object_vars($this->_model)) == 0) {
211
//                foreach ($model as $value) {
212
//                    if (!is_object($value) && !is_array($value)) {
213
//                        $this->_model->scalar[] = $value;
214
//                    } else {
215
//                        $this->_model->{ObjectHandler::OBJECT_ARRAY_IGNORE_NODE}[] = $value; // __object__ignore is a special name and it is not rendered
216
//                    }
217
//                }
218
//            }
219
//        } else if (is_object($model)) {
220
//            $this->_model = $model;
221
//        } else {
222
//            throw new InvalidArgumentException('The model is not an object or an array');
223
//        }
224
//
225
//        $this->objectInfo = new ClassAnnotations($this->_model, $config, $forcePropName);
226
//    }
227
228
//    /**
0 ignored issues
show
Unused Code Comprehensibility introduced by Joao Gilberto Magalhães
51% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
229
//     * Create a object model inside the "current node"
230
//     * @return DOMNode
231
//     */
232
//    public function createObjectFromModel()
233
//    {
234
//        if ($this->_model instanceof IteratorInterface) {
235
//            foreach ($this->_model as $singleRow) {
236
//                XmlUtil::AddNodeFromNode($this->_current, $singleRow->getDomObject());
237
//            }
238
//            return $this->_current;
239
//        }
240
//
241
//        if ($this->objectInfo->getClassIgnoreAllClass()) {
242
//            return $this->_current;
243
//        }
244
//
245
//        # Get the node names of this Class
246
//        $node = $this->createClassNode();
247
//
248
//        # Get property node names of this class.
249
//        $this->createPropertyNodes($node);
250
//
251
//        return $node;
252
//    }
253
//
254
//
255
//    protected function createClassNode()
256
//    {
257
//        #-----------
258
//        # Setup NameSpaces
259
//        foreach ($this->objectInfo->getClassNamespace() as $value) {
260
//            XmlUtil::AddNamespaceToDocument($this->_current, $value['prefix'], $value['uri']);
261
//        }
262
//
263
//        #------------
264
//        # Create Class Node
265
//        if ($this->_model instanceof stdClass && $this->_parentArray) {
266
//            $node = XmlUtil::CreateChild($this->_current, ObjectHandler::OBJECT_ARRAY);
267
//        } else if ($this->objectInfo->getClassDontCreateClassNode() || $this->_model instanceof stdClass) {
268
//            $node = $this->_current;
269
//        } else {
270
//            if (!$this->objectInfo->getClassIsRDF()) {
271
//                $node = XmlUtil::CreateChild($this->_current, $this->objectInfo->getClassName());
272
//            } else {
273
//                XmlUtil::AddNamespaceToDocument($this->_current, "rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
274
//                $node = XmlUtil::CreateChild($this->_current, "rdf:Description");
275
//                XmlUtil::AddAttribute($node, "rdf:about", $this->objectInfo->getClassRdfAbout());
276
//                $nodeType = XmlUtil::CreateChild($node, "rdf:type");
277
//                XmlUtil::AddAttribute($nodeType, "rdf:resource", $this->objectInfo->getClassRdfType());
278
//            }
279
//        }
280
//
281
//        return $node;
282
//    }
283
//
284
//    protected function createPropertyNodes($node)
285
//    {
286
//        $properties = $this->objectInfo->getPropertyList();
287
//
288
//        if (empty($properties)) {
289
//            return;
290
//        }
291
//
292
//        foreach ($properties as $keyProp => $prop) {
293
//            # Define Properties
294
//            $propMeta = $this->objectInfo->getPropertyAnnotation($prop, $keyProp);
295
//
296
//            if ($propMeta->getPropIgnore()) {
297
//                continue;
298
//            }
299
//
300
//            # Process the Property Value
301
//            $used = null;
302
//
303
//            # ------------------------------------------------
304
//            # Value is a OBJECT?
305
//            if (is_object($propMeta->getPropValue())) {
306
//                if ($propMeta->getPropDontCreateNode()) {
307
//                    $nodeUsed = $node;
308
//                } else {
309
//                    $nodeUsed = XmlUtil::CreateChild($node, $propMeta->getPropName());
310
//                }
311
//
312
//                $objHandler = new ObjectHandler($nodeUsed, $propMeta->getPropValue(), $this->_config,
313
//                    $propMeta->getPropForceName());
314
//                $used = $objHandler->createObjectFromModel();
315
//            }
316
//
317
//            # ------------------------------------------------
318
//            # Value is an ARRAY?
319
//            elseif (is_array($propMeta->getPropValue())) {
320
//                // Check if the array is associative or dont.
321
//                $isAssoc = (bool) count(array_filter(array_keys($propMeta->getPropValue()), 'is_string'));
322
//                $hasScalar = (bool) count(array_filter(array_values($propMeta->getPropValue()),
323
//                            function($val) {
324
//                            return !(is_object($val) || is_array($val));
325
//                        }));
326
//
327
//                $lazyCreate = false;
328
//
329
//                if ($propMeta->getPropDontCreateNode() || (!$isAssoc && $hasScalar)) {
330
//                    $nodeUsed = $node;
331
//                } else if ((!$isAssoc && !$hasScalar)) {
332
//                    $lazyCreate = true;    // Have to create the node every iteration
333
//                } else {
334
//                    $nodeUsed = $used = XmlUtil::CreateChild($node, $propMeta->getPropName());
335
//                }
336
//
337
//
338
//                foreach ($propMeta->getPropValue() as $keyAr => $valAr) {
339
//                    if (
340
//                        (!$isAssoc && $hasScalar)   # Is not an associative array and have scalar numbers in it.
341
//                        || !(is_object($valAr) || is_array($valAr))    # The value is not an object and not is array
342
//                        || (is_string($keyAr) && (is_object($valAr) || is_array($valAr))) # The key is string (associative array) and
343
//                    # the valluris a object or array
344
//                    ) {
345
//                        $obj = new \stdClass;
346
//                        $obj->{(is_string($keyAr) ? $keyAr : $propMeta->getPropName())} = $valAr;
347
//                        $this->_currentArray = false;
348
//                    } else if ($lazyCreate) {
349
//                        if (Is_null($used) && is_object($valAr)) { // If the child is an object there is no need to create every time the node.
350
//                            $lazyCreate = false;
351
//                        }
352
//                        $nodeUsed = $used = XmlUtil::CreateChild($node, $propMeta->getPropName());
353
//                        $obj = $valAr;
354
//                    } else {
355
//                        $obj = $valAr;
356
//                    }
357
//
358
//                    $objHandler = new ObjectHandler($nodeUsed, $obj, $this->_config,
359
//                        $propMeta->getPropForceName(), $this->_currentArray);
360
//                    $objHandler->createObjectFromModel();
361
//                }
362
//            }
363
//
364
//            # ------------------------------------------------
365
//            # Value is a Single Value?
366
//            else if (!empty($propMeta->getPropValue())    // Some values are empty for PHP but need to be considered
367
//                || ($propMeta->getPropValue() === 0) || ($propMeta->getPropValue() === false) || ($propMeta->getPropValue()
368
//                === '0') || ($this->objectInfo->getClassWriteEmpty())
369
//            ) {
370
//                if ($propMeta->getPropIsClassAttr()) {
371
//                    XmlUtil::AddAttribute($node, $propMeta->getPropName(),
372
//                        $propMeta->getPropValue());
373
//                } elseif ($propMeta->getPropIsBlankNode() != "") {
374
//                    if (!array_key_exists($propMeta->getPropIsBlankNode(),
375
//                            $this->nodeRefs)) {
376
//                        $this->nodeRefs[$propMeta->getPropIsBlankNode()] = XmlUtil::CreateChild($node,
377
//                                $propMeta->getPropIsBlankNode());
378
//                        XmlUtil::AddAttribute($this->nodeRefs[$propMeta->getPropIsBlankNode()],
379
//                            "rdf:parseType", "Resource");
380
//                    }
381
//
382
//                    if ($propMeta->getPropIsResourceUri()) {
383
//                        $blankNodeType = XmlUtil::CreateChild($this->nodeRefs[$propMeta->getPropIsBlankNode()],
384
//                                "rdf:type");
385
//                        XmlUtil::AddAttribute($blankNodeType, "rdf:resource", $propMeta->getPropValue());
386
//                    } else {
387
//                        XmlUtil::CreateChild($this->nodeRefs[$propMeta->getPropIsBlankNode()],
388
//                            $propMeta->getPropName(), $propMeta->getPropValue());
389
//                    }
390
//                } elseif (($propMeta->getPropAttributeOf() != "") && (array_key_exists($propMeta->getPropAttributeOf(),
391
//                        $this->nodeRefs))) {
392
//                    XmlUtil::AddAttribute($this->nodeRefs[$propMeta->getPropAttributeOf()],
393
//                        $propMeta->getPropName(), $propMeta->getPropValue());
394
//                } elseif ((preg_match('|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i',
395
//                        $propMeta->getPropValue())) && $this->objectInfo->getClassIsRDF()) {
396
//                    $used = XmlUtil::CreateChild($node, $propMeta->getPropName());
397
//                    XmlUtil::AddAttribute($used, "rdf:resource", $propMeta->getPropValue());
398
//                } elseif (is_bool($propMeta->getPropValue())) {
399
//                    $used = XmlUtil::CreateChild($node, $propMeta->getPropName(),
400
//                            $propMeta->getPropValue() ? 'true' : 'false');
401
//                } else {
402
//                    $used = XmlUtil::CreateChild($node, $propMeta->getPropName(),
403
//                            $propMeta->getPropValue());
404
//                }
405
//            }
406
//
407
//            # Save Reference for "isAttributeOf" attribute.
408
//            if (!is_null($used)) {
409
//                $this->nodeRefs[$propMeta->getPropName()] = $used;
410
//            }
411
//        }
412
//    }
413
//
414
//    protected static function mapArray(&$value, $key = null)
415
//    {
416
//        if ($value instanceof SimpleXMLElement) {
417
//            $x = array();
418
//            foreach ($value->children() as $k => $v) {
419
//                $text = "" . $v;
420
//                if ($text != "") {
421
//                    $arText = array($text);
422
//                } else {
423
//                    $arText = array();
424
//                }
425
//                $x[$k][] = (array) $v + $arText;
426
//            }
427
//            $value = (array) $value->attributes() + $x;
428
//        }
429
//
430
//        // Fix empty arrays or with one element only.
431
//        if (is_array($value)) {
432
//            if (count($value) == 0) {
433
//                $value = "";
434
//            } elseif (count($value) == 1 && array_key_exists(0, $value)) {
435
//                $value = $value[0];
436
//            }
437
//        }
438
//
439
//        // If still as array, process it
440
//        if (is_array($value)) {
441
//            // Transform attributes
442
//            if (array_key_exists("@attributes", $value)) {
443
//                $attributes = array();
444
//                foreach ($value["@attributes"] as $k => $v) {
445
//                    $attributes["$k"] = $v;
446
//                }
447
//                $value = $attributes + $value;
448
//                unset($value["@attributes"]);
449
//            }
450
//
451
//            // Fix empty arrays or with one element only.
452
//            if (count($value) == 0) {
453
//                $value = "";
454
//            } else if (array_key_exists(0, $value) && count($value) == 1) {
455
//                $value = $value[0];
456
//            } else if (array_key_exists(0, $value) && !array_key_exists(1, $value)) {
457
//                $value["_text"] = $value[0];
458
//                unset($value[0]);
459
//            }
460
//
461
//            // If still an array, walk.
462
//            if (is_array($value)) {
463
//                array_walk($value, "ByJG\AnyDataset\Model\ObjectHandler::mapArray");
464
//            }
465
//        }
466
//    }
467
//
468
//    /**
469
//     *
470
//     * @param DOMNode $domnode
471
//     * @param type $jsonFunction
472
//     * @return type
473
//     */
474
//    public static function xml2json($domnode, $jsonFunction = "")
475
//    {
476
//        if (!($domnode instanceof DOMNode)) {
477
//            throw new InvalidArgumentException("xml2json requires a \DOMNode descendant");
478
//        }
479
//
480
//        $xml = simplexml_import_dom($domnode);
481
//
482
//        $pre = $pos = "";
483
//        if (!empty($jsonFunction)) {
484
//            $pre = "(";
485
//            $pos = ")";
486
//        }
487
//
488
//        if ($xml->getName() == "xmlnuke") {
489
//            $array = (array) $xml->children();
490
//        } else {
491
//            $array = (array) $xml;
492
//        }
493
//
494
//        array_walk($array, "ByJG\AnyDataset\Model\ObjectHandler::mapArray");
495
//
496
//        // Check an special case from Xml
497
//        if (isset($array[ObjectHandler::OBJECT_ARRAY])) {
498
//            $json = json_encode($array[ObjectHandler::OBJECT_ARRAY]);
499
//        } else {
500
//            $json = json_encode($array);
501
//        }
502
//
503
//        return $jsonFunction . $pre . $json . $pos;
504
//    }
505
}
506