Completed
Pull Request — master (#227)
by Alex
09:20
created

BaseNodeHandler::handleStartNode()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 3
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
6
namespace POData\Readers\Atom\Processors;
7
8
use Closure;
9
use ParseError;
10
use POData\Common\ODataConstants;
11
use SplStack;
12
13
abstract class BaseNodeHandler
14
{
15
    private static $processExceptionMessage =
16
        'FeedProcessor encountered %s %s Tag with name %s that we don\'t know how to process';
17
18
    private $charData = '';
19
20
    /**
21
     * @var SplStack|callable
22
     */
23
    private $tagEndQueue;
24
25
    private function resolveNamespaceToMethodTag($tagNamespace)
26
    {
27
        $tags = [
28
            strtolower(ODataConstants::ODATA_METADATA_NAMESPACE) => 'Metadata',
29
            strtolower(ODataConstants::ATOM_NAMESPACE) => 'Atom',
30
            strtoLower(ODataConstants::ODATA_NAMESPACE) => 'Dataservice'
31
        ];
32
        return $tags[strtolower($tagNamespace)];
33
    }
34
35
    public function handleStartNode($tagNamespace, $tagName, $attributes)
36
    {
37
        $methodType = $this->resolveNamespaceToMethodTag($tagNamespace);
38
        $method     = 'handleStart' . $methodType . ucfirst(strtolower($tagName));
39
        if (!method_exists($this, $method)) {
40
            $this->onParseError($methodType, 'Start', $tagName);
41
        }
42
        $this->{$method}($attributes);
43
    }
44
45
    public function handleCharacterData($characters)
46
    {
47
        if (ord($characters) === 10 && empty($this->charData)) {
48
            return;
49
        }
50
        $this->charData .= $characters;
51
    }
52
53
    final public function popCharData()
54
    {
55
        $data           = $this->charData;
56
        $this->charData = '';
57
        return $data;
58
    }
59
60
    abstract public function handleChildComplete($objectModel);
61
62
    abstract public function getObjetModelObject();
63
64
    final protected function arrayKeyOrDefault($array, $key, $default)
65
    {
66
        if (array_key_exists($key, $array)) {
67
            return $array[$key];
68
        }
69
        foreach ($array as $objKey => $value) {
70
            if (strtolower($key) === strtolower($objKey)) {
71
                return $value;
72
            }
73
        }
74
        return $default;
75
    }
76
77
    final protected function onParseError($namespace, $startEnd, $tagName)
78
    {
79
        throw new ParseError(sprintf(self::$processExceptionMessage, $namespace, $startEnd, $tagName));
80
    }
81
82
83
    protected function doNothing()
84
    {
85
        return function () {
86
        };
87
    }
88
89
    protected function bindHere(Closure $closure)
90
    {
91
        return $closure->bindTo($this, get_class($this));
92
    }
93
    protected function enqueueEnd(Closure $closure)
94
    {
95
        if (null === $this->tagEndQueue) {
96
            $this->tagEndQueue = new SplStack();
97
        }
98
        $this->tagEndQueue->push($this->bindHere($closure));
99
    }
100
101
    public function handleEndNode($tagNamespace, $tagName)
102
    {
103
        assert(!$this->tagEndQueue->isEmpty(), 'every node that opens should register a end tag');
104
        $endMethod = $this->tagEndQueue->pop();
105
        $endMethod();
106
    }
107
}
108