Passed
Push — master ( 0076ce...72e11f )
by Richard
10:31 queued 15s
created

Page::__construct()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 6
c 1
b 0
f 0
dl 0
loc 11
rs 10
cc 3
nc 3
nop 1
1
<?php
2
3
4
namespace Riclep\Storyblok;
5
6
use Exception;
7
use Carbon\Carbon;
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
	 * Page constructor.
36
	 * @param $story
37
	 */
38
	public function __construct($story) {
39
		$this->story = $story;
40
41
		$this->preprocess();
42
43
		$this->block = $this->createBlock($this->story['content']);
44
45
		// run automatic traits - methods matching initTraitClassName()
46
		foreach (class_uses_recursive($this) as $trait) {
47
			if (method_exists($this, $method = 'init' . class_basename($trait))) {
48
				$this->{$method}();
49
			}
50
		}
51
	}
52
53
	/**
54
	 * Returns a view populated with the story’s content. Additional data can
55
	 * be passed in using an associative array
56
	 *
57
	 * @param array $additionalContent
58
	 * @return View
59
	 */
60
	public function render($additionalContent = []) {
61
		return view()->first($this->views(), array_merge(['story' => $this], $additionalContent));
62
	}
63
64
	/**
65
	 * Returns a list of possible arrays for this page based on the Storyblok
66
	 * contentType component’s name
67
	 *
68
	 * @return array
69
	 */
70
	public function views() {
71
		$views = array_map(function($path) {
72
			return config('storyblok.view_path') . 'pages.' . $path;
73
		}, $this->block()->_componentPath);
74
75
		return array_reverse($views);
76
	}
77
78
	/**
79
	 * Return a lovely Carbon object of the first published date
80
	 *
81
	 * @return Carbon
82
	 */
83
	public function publishedAt() {
84
		return Carbon::parse($this->story['first_published_at']);
85
	}
86
87
	/**
88
	 * A Carbon object for the most recent publish date
89
	 *
90
	 * @return Carbon
91
	 */
92
	public function updatedAt() {
93
		return Carbon::parse($this->story['published_at']);
94
	}
95
96
	/**
97
	 * Returns the full slug for the page
98
	 *
99
	 * @return string
100
	 */
101
	public function slug() {
102
		return $this->story['full_slug'];
103
	}
104
105
	/**
106
	 * Returns all the tags, sorting them is so desired
107
	 *
108
	 * @param bool $alphabetical
109
	 * @return mixed
110
	 */
111
	public function tags($alphabetical = false) {
112
		if ($alphabetical) {
113
			sort($this->story['tag_list']);
114
		}
115
116
		return $this->story['tag_list'];
117
	}
118
119
	/**
120
	 * Checks if this page has the matching tag
121
	 *
122
	 * @param $tag
123
	 * @return bool
124
	 */
125
	public function hasTag($tag) {
126
		return in_array($tag, $this->tags());
127
	}
128
129
	/**
130
	 * Returns the page’s contentType Block - this is the component type
131
	 * used for the page in Storyblok
132
	 *
133
	 * @return Block
134
	 */
135
	public function block() {
136
		return $this->block;
137
	}
138
139
	/**
140
	 * Magic getter to return fields from te contentType block for this page
141
	 * without having to reach into the page.
142
	 *
143
	 * @param $name
144
	 * @return bool|string
145
	 */
146
	public function __get($name) {
147
		try {
148
			if ($this->block && $this->block->has($name)) {
149
				return $this->block->{$name};
150
			}
151
152
			return false;
153
		} catch (Exception $e) {
154
			return 'Caught exception: ' .  $e->getMessage();
155
		}
156
	}
157
158
159
	/**
160
	 * Does a bit of housekeeping before processing the data
161
	 * from Storyblok any further
162
	 */
163
	private function preprocess() {
164
		// TODO extract SEO plugin
165
		//$this->story;
166
167
		$this->addMeta([
168
			'name' => $this->story['name'],
169
			'tags' => $this->story['tag_list'],
170
			'slug' => $this->story['full_slug'],
171
		]);
172
	}
173
174
	/**
175
	 * Creates the Block for the page’s contentType component
176
	 *
177
	 * @param $content
178
	 * @return mixed
179
	 */
180
	private function createBlock($content) {
181
		$class = $this->getChildClassName('Block', $content['component']);
182
183
		return new $class($content, $this);
184
	}
185
}