Passed
Push — develop ( 6e8f17...2975bd )
by Jens
03:53
created

Repository::__get()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 16
Code Lines 11

Duplication

Lines 12
Ratio 75 %

Importance

Changes 0
Metric Value
cc 4
eloc 11
nc 4
nop 1
dl 12
loc 16
rs 9.2
c 0
b 0
f 0
1
<?php
2
/**
3
 * User: Jens
4
 * Date: 30-1-2017
5
 * Time: 20:15
6
 */
7
8
namespace CloudControl\Cms\storage;
9
10
use CloudControl\Cms\storage\repository\ContentRepository;
11
12
/**
13
 * Class Repository
14
 * @package CloudControl\Cms\storage
15
 * @property array sitemap
16
 * @property array applicationComponents
17
 * @property array documentTypes
18
 * @property array bricks
19
 * @property array imageSet
20
 * @property array images
21
 * @property array files
22
 * @property array users
23
 * @property array valuelists
24
 * @property array redirects
25
 * @property array activityLog
26
 */
27
class Repository
28
{
29
    protected $storagePath;
30
31
    protected $fileBasedSubsets = array('sitemap', 'applicationComponents', 'documentTypes', 'bricks', 'imageSet', 'images', 'files', 'users', 'valuelists', 'redirects', 'activityLog');
32
33
    protected $sitemap;
34
    protected $sitemapChanges = false;
35
36
    protected $applicationComponents;
37
    protected $applicationComponentsChanges = false;
38
39
    protected $documentTypes;
40
    protected $documentTypesChanges = false;
41
42
    protected $bricks;
43
    protected $bricksChanges = false;
44
45
    protected $imageSet;
46
    protected $imageSetChanges = false;
47
48
    protected $images;
49
    protected $imagesChanges = false;
50
51
    protected $files;
52
    protected $filesChanges = false;
53
54
    protected $users;
55
    protected $usersChanges = false;
56
57
    protected $valuelists;
58
    protected $valuelistsChanges = false;
59
60
    protected $redirects;
61
    protected $redirectsChanges = false;
62
63
    protected $activityLog;
64
    protected $activityLogChanges = false;
65
66
    /**
67
     * @var ContentRepository
68
     */
69
    protected $contentDbHandle;
70
71
    protected $contentRepository;
72
73
74
    /**
75
     * Repository constructor.
76
     * @param $storagePath
77
     * @throws \Exception
78
     */
79
    public function __construct($storagePath)
80
    {
81
        $storagePath = realpath($storagePath);
82
        if (is_dir($storagePath) && $storagePath !== false) {
83
            $this->storagePath = $storagePath;
84
            $this->contentRepository = new ContentRepository($storagePath);
85
        } else {
86
            throw new \Exception('Repository not yet initialized.');
87
        }
88
    }
89
90
    /**
91
     * Initiates default storage
92
     * @param $baseStorageDefaultPath
93
     * @param $baseStorageSqlPath
94
     */
95
    public function init($baseStorageDefaultPath, $baseStorageSqlPath)
96
    {
97
        $storageDefaultPath = realpath($baseStorageDefaultPath);
98
        $contentSqlPath = realpath($baseStorageSqlPath);
99
100
        $this->initConfigStorage($storageDefaultPath);
101
        $this->initContentDb($contentSqlPath);
102
103
        $this->save();
104
    }
105
106
    /**
107
     * Load filebased subset and return it's contents
108
     *
109
     * @param $name
110
     * @return mixed|string
111
     * @throws \Exception
112
     */
113
    public function __get($name)
114
    {
115
        if (isset($this->$name)) {
116 View Code Duplication
            if (in_array($name, $this->fileBasedSubsets)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
117
                return $this->$name;
118
            } else {
119
                throw new \Exception('Trying to get undefined property from Repository: ' . $name);
120
            }
121 View Code Duplication
        } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
122
            if (in_array($name, $this->fileBasedSubsets)) {
123
                return $this->loadSubset($name);
124
            } else {
125
                throw new \Exception('Trying to get undefined property from Repository: ' . $name);
126
            }
127
        }
128
    }
129
130
    /**
131
     * Set filebased subset contents
132
     * @param $name
133
     * @param $value
134
     * @throws \Exception
135
     */
136
    public function __set($name, $value)
137
    {
138
        if (in_array($name, $this->fileBasedSubsets)) {
139
            $this->$name = $value;
140
            $changes = $name . 'Changes';
141
            $this->$changes = true;
142
        } else {
143
            throw new \Exception('Trying to persist unknown subset in repository: ' . $name . ' <br /><pre>' . print_r($value, true) . '</pre>');
144
        }
145
    }
146
147
    /**
148
     * Persist all subsets
149
     */
150
    public function save()
151
    {
152
        $host = $this;
153
        array_map(function ($value) use ($host) {
154
            $host->saveSubset($value);
155
        }, $this->fileBasedSubsets);
156
    }
157
158
    /**
159
     * Persist subset to disk
160
     * @param $subset
161
     */
162
    public function saveSubset($subset)
163
    {
164
        $changes = $subset . 'Changes';
165
        if ($this->$changes === true) {
166
            if (!defined('JSON_PRETTY_PRINT')) {
167
                $json = json_encode($this->$subset);
168
            } else {
169
                $json = json_encode($this->$subset, JSON_PRETTY_PRINT);
170
            }
171
            $subsetStoragePath = $this->storagePath . DIRECTORY_SEPARATOR . $subset . '.json';
172
            file_put_contents($subsetStoragePath, $json);
173
174
            $this->$changes = false;
175
        }
176
    }
177
178
    /**
179
     * Load subset from disk
180
     * @param $subset
181
     * @return mixed|string
182
     */
183
    protected function loadSubset($subset)
184
    {
185
        $subsetStoragePath = $this->storagePath . DIRECTORY_SEPARATOR . $subset . '.json';
186
        $json = file_get_contents($subsetStoragePath);
187
        $json = json_decode($json);
188
        $this->$subset = $json;
189
        return $json;
190
    }
191
192
    /**
193
     * @param $contentSqlPath
194
     */
195
    protected function initContentDb($contentSqlPath)
196
    {
197
        $db = $this->getContentDbHandle();
198
        $sql = file_get_contents($contentSqlPath);
199
        $db->exec($sql);
200
    }
201
202
    /**
203
     * @param $storageDefaultPath
204
     */
205
    protected function initConfigStorage($storageDefaultPath)
206
    {
207
        $json = file_get_contents($storageDefaultPath);
208
        $json = json_decode($json);
209
        $this->initConfigIfNotExists($json, 'sitemap');
210
        $this->initConfigIfNotExists($json, 'applicationComponents');
211
        $this->initConfigIfNotExists($json, 'documentTypes');
212
        $this->initConfigIfNotExists($json, 'bricks');
213
        $this->initConfigIfNotExists($json, 'imageSet');
214
        $this->initConfigIfNotExists($json, 'images');
215
        $this->initConfigIfNotExists($json, 'files');
216
        $this->initConfigIfNotExists($json, 'users');
217
        $this->initConfigIfNotExists($json, 'valuelists');
218
        $this->initConfigIfNotExists($json, 'redirects');
219
        $this->initConfigIfNotExists($json, 'activityLog');
220
    }
221
222
    /**
223
     * @return \PDO
224
     */
225 View Code Duplication
    protected function getContentDbHandle()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
226
    {
227
        if ($this->contentDbHandle === null) {
228
            $this->contentDbHandle = new \PDO('sqlite:' . $this->storagePath . DIRECTORY_SEPARATOR . 'content.db');
0 ignored issues
show
Documentation Bug introduced by
It seems like new \PDO('sqlite:' . $th...PARATOR . 'content.db') of type object<PDO> is incompatible with the declared type object<CloudControl\Cms\...tory\ContentRepository> of property $contentDbHandle.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
229
        }
230
        return $this->contentDbHandle;
231
    }
232
233
    private function initConfigIfNotExists($json, $subsetName)
234
    {
235
        $subsetFileName = $this->storagePath . DIRECTORY_SEPARATOR . $subsetName . '.json';
236
        if (file_exists($subsetFileName)) {
237
            $this->loadSubset($subsetName);
238
        } else {
239
            $changes = $subsetName . 'Changes';
240
            $this->$subsetName = $json->$subsetName;
241
            $this->$changes = true;
242
        }
243
    }
244
245
    /**
246
     * @return ContentRepository
247
     */
248
    public function getContentRepository()
249
    {
250
        return $this->contentRepository;
251
    }
252
}