Passed
Push — master ( beb509...f9654e )
by Richard
03:40 queued 11s
created

Page   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 186
Duplicated Lines 0 %

Importance

Changes 15
Bugs 0 Features 0
Metric Value
wmc 18
eloc 39
c 15
b 0
f 0
dl 0
loc 186
rs 10

13 Methods

Rating   Name   Duplication   Size   Complexity  
A createBlock() 0 4 1
A slug() 0 2 1
A updatedAt() 0 2 1
A views() 0 6 1
A render() 0 2 1
A publishedAt() 0 2 1
A block() 0 2 1
A story() 0 2 1
A preprocess() 0 8 1
A __get() 0 11 3
A __construct() 0 11 3
A tags() 0 6 2
A hasTag() 0 2 1
1
<?php
2
3
4
namespace Riclep\Storyblok;
5
6
use Carbon\Carbon;
7
use Illuminate\Support\Str;
8
use Illuminate\View\View;
9
use Riclep\Storyblok\Traits\HasChildClasses;
10
use Riclep\Storyblok\Traits\HasMeta;
11
use Riclep\Storyblok\Traits\SchemaOrg;
12
13
class Page
14
{
15
	use HasChildClasses;
16
	use HasMeta;
17
	use SchemaOrg;
18
19
	/**
20
	 * @var string[] this is the root of the path so includes the page
21
	 */
22
	public $_componentPath = ['page'];
23
24
	/**
25
	 * @var Block root Block of the page’s content
26
	 */
27
	private $block;
28
29
	/**
30
	 * @var array the JSON decoded array from Storyblok
31
	 */
32
	private $story;
33
34
	/**
35
	 * @var array holds all the fields indexed by UUID for the JS live bridge
36
	 */
37
	public $liveContent = [];
38
39
	/**
40
	 * Page constructor.
41
	 * @param $story
42
	 */
43
	public function __construct($story) {
44
		$this->story = $story;
45
46
		$this->preprocess();
47
48
		$this->block = $this->createBlock($this->story['content']);
49
50
		// run automatic traits - methods matching initTraitClassName()
51
		foreach (class_uses_recursive($this) as $trait) {
52
			if (method_exists($this, $method = 'init' . class_basename($trait))) {
53
				$this->{$method}();
54
			}
55
		}
56
	}
57
58
	/**
59
	 * Returns a view populated with the story’s content. Additional data can
60
	 * be passed in using an associative array
61
	 *
62
	 * @param array $additionalContent
63
	 * @return View
64
	 */
65
	public function render($additionalContent = []) {
66
		return view()->first($this->views(), array_merge(['story' => $this], $additionalContent));
67
	}
68
69
	/**
70
	 * Returns a list of possible arrays for this page based on the Storyblok
71
	 * contentType component’s name
72
	 *
73
	 * @return array
74
	 */
75
	public function views() {
76
		$views = array_map(function($path) {
77
			return config('storyblok.view_path') . 'pages.' . $path;
78
		}, $this->block()->_componentPath);
79
80
		return array_reverse($views);
81
	}
82
83
	/**
84
	 * Returns the story for this Page
85
	 *
86
	 * @return array
87
	 */
88
	public function story() {
89
		return $this->story;
90
	}
91
92
	/**
93
	 * Return a lovely Carbon object of the first published date
94
	 *
95
	 * @return Carbon
96
	 */
97
	public function publishedAt() {
98
		return Carbon::parse($this->story['first_published_at']);
99
	}
100
101
	/**
102
	 * A Carbon object for the most recent publish date
103
	 *
104
	 * @return Carbon
105
	 */
106
	public function updatedAt() {
107
		return Carbon::parse($this->story['published_at']);
108
	}
109
110
	/**
111
	 * Returns the full slug for the page
112
	 *
113
	 * @return string
114
	 */
115
	public function slug() {
116
		return $this->story['full_slug'];
117
	}
118
119
	/**
120
	 * Returns all the tags, sorting them is so desired
121
	 *
122
	 * @param bool $alphabetical
123
	 * @return mixed
124
	 */
125
	public function tags($alphabetical = false) {
126
		if ($alphabetical) {
127
			sort($this->story['tag_list']);
128
		}
129
130
		return $this->story['tag_list'];
131
	}
132
133
	/**
134
	 * Checks if this page has the matching tag
135
	 *
136
	 * @param $tag
137
	 * @return bool
138
	 */
139
	public function hasTag($tag) {
140
		return in_array($tag, $this->tags());
141
	}
142
143
	/**
144
	 * Returns the page’s contentType Block - this is the component type
145
	 * used for the page in Storyblok
146
	 *
147
	 * @return Block
148
	 */
149
	public function block() {
150
		return $this->block;
151
	}
152
153
	/**
154
	 * Magic getter to return fields from the contentType block for this page
155
	 * without having to reach into the page.
156
	 *
157
	 * @param $name
158
	 * @return bool|string
159
	 */
160
	public function __get($name) {
161
		// check for accessor on the root block
162
		$accessor = 'get' . Str::studly($name) . 'Attribute';
163
164
		if (method_exists($this->block(), $accessor)) {
165
			return $this->block()->$accessor();
166
		}
167
168
		// check for attribute on the root block
169
		if ($this->block()->has($name)) {
170
			return $this->block()->{$name};
171
		}
172
	}
173
174
	/**
175
	 * Does a bit of housekeeping before processing the data
176
	 * from Storyblok any further
177
	 */
178
	private function preprocess() {
179
		// TODO extract SEO plugin
180
		//$this->story;
181
182
		$this->addMeta([
183
			'name' => $this->story['name'],
184
			'tags' => $this->story['tag_list'],
185
			'slug' => $this->story['full_slug'],
186
		]);
187
	}
188
189
	/**
190
	 * Creates the Block for the page’s contentType component
191
	 *
192
	 * @param $content
193
	 * @return mixed
194
	 */
195
	private function createBlock($content) {
196
		$class = $this->getChildClassName('Block', $content['component']);
197
198
		return new $class($content, $this);
199
	}
200
}