Completed
Pull Request — 1.0 (#58)
by Titouan
04:36 queued 01:59
created

ChangeStream::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 11
ccs 8
cts 8
cp 1
rs 9.4286
cc 1
eloc 7
nc 1
nop 0
crap 1
1
<?php
2
3
/*
4
 * This file is part of the puli/repository package.
5
 *
6
 * (c) Bernhard Schussek <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Puli\Repository\ChangeStream;
13
14
use Puli\Repository\Api\Resource\PuliResource;
15
use Puli\Repository\Api\ResourceRepository;
16
use Puli\Repository\ChangeStream\Normalizer\DirectoryResourceNormalizer;
17
use Puli\Repository\ChangeStream\Normalizer\FileResourceNormalizer;
18
use Puli\Repository\ChangeStream\Normalizer\GenericResourceNormalizer;
19
use Puli\Repository\ChangeStream\Normalizer\LinkResourceNormalizer;
20
use Puli\Repository\ChangeStream\Normalizer\ResourceNormalizer;
21
22
/**
23
 * Stream to track repositories changes and fetch previous versions of resources.
24
 *
25
 * @since  1.0
26
 *
27
 * @author Titouan Galopin <[email protected]>
28
 */
29
class ChangeStream
30
{
31
    /**
32
     * @var array
33
     */
34
    private $stack;
35
36
    /**
37
     * @var ResourceNormalizer[]
38
     */
39
    private $normalizers;
40
41
    /**
42
     * Create a change stream.
43
     */
44 10
    public function __construct()
45
    {
46 10
        $this->stack = array();
47
48 10
        $this->normalizers = array(
49 10
            new LinkResourceNormalizer(),
50 10
            new DirectoryResourceNormalizer(),
51 10
            new FileResourceNormalizer(),
52 10
            new GenericResourceNormalizer(),
53
        );
54 10
    }
55
56
    /**
57
     * Store a version of a resource in the ChangeStream to retrieve it if needed.
58
     *
59
     * @param string       $path
60
     * @param PuliResource $resource
61
     */
62 10
    public function log($path, PuliResource $resource)
63
    {
64 10
        if (!array_key_exists($path, $this->stack)) {
65 10
            $this->stack[$path] = array();
66 10
        }
67
68 10
        $this->stack[$path][] = $this->normalize($resource);
69 9
    }
70
71
    /**
72
     * Create a stack of resources for the given path.
73
     *
74
     * @param ResourceRepository $repository
75
     * @param string             $path
76
     *
77
     * @return ResourceStack
78
     */
79 8
    public function buildResourceStack(ResourceRepository $repository, $path)
80
    {
81 8
        $stack = array();
82
83 8
        if (isset($this->stack[$path]) && is_array($this->stack[$path])) {
84 8
            foreach ($this->stack[$path] as $data) {
85 8
                $resource = $this->denormalize($data);
86 8
                $resource->attachTo($repository, $path);
87
88 8
                $stack[] = $resource;
89 8
            }
90 8
        }
91
92 8
        return new ResourceStack($stack);
93
    }
94
95
    /**
96
     * @return array
97
     */
98 1
    public function getLogStack()
99
    {
100 1
        return $this->stack;
101
    }
102
103
    /**
104
     * Register a given normalizer for usage by this change stream.
105
     *
106
     * @param ResourceNormalizer $normalizer
107
     */
108
    public function registerNormalizer(ResourceNormalizer $normalizer)
109
    {
110
        array_unshift($this->normalizers, $normalizer);
111
    }
112
113
    /**
114
     * @param PuliResource $resource
115
     *
116
     * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,string>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
117
     */
118 10
    private function normalize(PuliResource $resource)
119
    {
120 10
        foreach ($this->normalizers as $normalizer) {
121 10
            if ($normalizer->supports($resource)) {
122 9
                $data = $normalizer->normalize($resource);
123 9
                $data['normalizer'] = get_class($normalizer);
124
125 9
                return $data;
126
            }
127 10
        }
128
129 1
        throw new \RuntimeException(sprintf(
130
            'Instances of "%s" are not supported by this ChangeStream as no normalizer in the '.
131 1
            'ChangeStream supports them (see the documentation to create your own normalizer).',
132 1
            get_class($resource)
133 1
        ));
134
    }
135
136
    /**
137
     * @param array $data
138
     *
139
     * @return PuliResource
140
     */
141 8
    private function denormalize($data)
142
    {
143 8
        foreach ($this->normalizers as $normalizer) {
144 8
            if (get_class($normalizer) === $data['normalizer']) {
145 8
                return $normalizer->denormalize($data);
146
            }
147 8
        }
148
149
        throw new \RuntimeException(sprintf(
150
            'Normalizer %s is not registered in this ChangeStream. You need to register it to be able '.
151
            'to get versions of resource "%s".',
152
            $data['normalizer'],
153
            $data['path']
154
        ));
155
    }
156
}
157