Completed
Push — master ( be40dc...524dea )
by Nazar
06:35
created

Meta::render()   C

Complexity

Conditions 8
Paths 14

Size

Total Lines 25
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 8

Importance

Changes 0
Metric Value
cc 8
eloc 22
nc 14
nop 0
dl 0
loc 25
rs 5.3846
c 0
b 0
f 0
ccs 23
cts 23
cp 1
crap 8
1
<?php
2
/**
3
 * @package CleverStyle Framework
4
 * @author  Nazar Mokrynskyi <[email protected]>
5
 * @license 0BSD
6
 */
7
namespace cs\Page;
8
use
9
	cs\Config,
10
	cs\Language,
11
	cs\Page,
12
	cs\Request,
13
	cs\Singleton,
14
	h;
15
16
/**
17
 * Meta class for generation of various meta tags
18
 *
19
 * @method $this og(string $property, string|string[] $content)
20
 */
21
class Meta {
22
	use
23
		Singleton;
24
	/**
25
	 * Is used as <head prefix="$head_prefix">
26
	 * @var string
27
	 */
28
	public $head_prefix = '';
29
	/**
30
	 * If false - &lt;head&gt; will not be added automatically, and should be in template if needed
31
	 * @var bool
32
	 */
33
	public    $no_head   = false;
34
	protected $links     = '';
35
	protected $og_data   = [];
36
	protected $og_type   = '';
37
	protected $image_src = false;
38
	/**
39
	 * Common wrapper to add all necessary meta tags with images
40
	 *
41
	 * @param string|string[] $images
42
	 *
43
	 * @return Meta
44
	 */
45 3
	public function image ($images) {
46 3
		if (!$images) {
47 3
			return $this;
48
		}
49 3
		$images = (array)$images;
50 3
		if (!$this->image_src && $images[0]) {
51 3
			$this->image_src = true;
52 3
			$this->links .= h::link(
0 ignored issues
show
Bug introduced by
The method link() does not exist on h. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

52
			$this->links .= h::/** @scrutinizer ignore-call */ link(
Loading history...
53
				[
54 3
					'href' => $images[0],
55 3
					'rel'  => 'image_src'
56
				]
57
			);
58
		}
59 3
		$this->__call('og', ['image', $images]);
60 3
		return $this;
61
	}
62
	/**
63
	 * Common wrapper for generation of various Open Graph protocol meta tags
64
	 *
65
	 * @param string  $type
66
	 * @param mixed[] $params
67
	 *
68
	 * @return Meta
69
	 */
70 21
	public function __call ($type, $params) {
71 21
		if (!$params) {
72 6
			$this->og_type         = $type;
73 6
			$this->og_data['type'] = h::meta(
0 ignored issues
show
Bug introduced by
The method meta() does not exist on h. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

73
			/** @scrutinizer ignore-call */ 
74
   $this->og_data['type'] = h::meta(
Loading history...
74
				[
75 6
					'property' => 'og:type',
76 6
					'content'  => $type
77
				]
78
			);
79 6
			return $this;
80
		}
81 21
		if (!$params[0]) {
82 3
			return $this;
83
		}
84 21
		if (is_array($params[1])) {
85 9
			foreach ($params[1] as $p) {
86 9
				$this->__call($type, [$params[0], $p]);
87
			}
88 21
		} elseif ($params[1] || $params[1] === 0) {
89 21
			if (!isset($this->og_data[$params[0]])) {
90 21
				$this->og_data[$params[0]] = '';
91
			}
92 21
			$this->og_data[$params[0]] .= h::meta(
93
				[
94 21
					'property' => "$type:$params[0]",
95 21
					'content'  => $params[1]
96
				]
97
			);
98
		}
99 21
		return $this;
100
	}
101
	/**
102
	 * Generates Open Graph protocol information, and puts it into HTML
103
	 *
104
	 * Usually called by system itself, there is no need to call it manually
105
	 */
106 21
	public function render () {
107 21
		$og = &$this->og_data;
108 21
		$this->fill_required_properties($og);
109 21
		$prefix = 'og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#';
110 21
		$type   = explode('.', $this->og_type, 2)[0];
111 21
		switch ($type) {
112 21
			case 'article':
113 15
			case 'blog':
114 15
			case 'book':
115 15
			case 'profile':
116 15
			case 'video':
117 15
			case 'website':
118 6
				$prefix .= " $type: http://ogp.me/ns/$type#";
119 6
				break;
120
		}
121 21
		$Page       = Page::instance();
122 21
		$Page->Head =
123 21
			$Page->Head.
124 21
			implode('', $og).
125 21
			$this->links;
126 21
		if (!$this->no_head) {
127 21
			$Page->Head = h::head(
0 ignored issues
show
Bug introduced by
The method head() does not exist on h. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

127
			/** @scrutinizer ignore-call */ 
128
   $Page->Head = h::head(
Loading history...
128 21
				$Page->Head,
129
				[
130 21
					'prefix' => $prefix.$this->head_prefix
131
				]
132
			);
133
		}
134 21
	}
135
	/**
136
	 * If type, title and other important properties were not specified - try to guess and fill them automatically
137
	 *
138
	 * @param array $og
139
	 */
140 21
	protected function fill_required_properties (&$og) {
141 21
		$Page = Page::instance();
142 21
		if (!@$og['title']) {
143 18
			$this->og('title', $Page->Title);
144
		}
145 21
		if (!@$og['description']) {
146 18
			$this->og('description', $Page->Description);
147
		}
148 21
		$Config = Config::instance();
149 21
		if (!@$og['url']) {
150 21
			$Request = Request::instance();
151
			/** @noinspection NestedTernaryOperatorInspection */
152 21
			$this->og(
153 21
				'url',
154 21
				$Request->home_page
155 18
					? $Config->base_url()
156 21
					: ($Page->canonical_url ?: $Config->base_url().'/'.$Request->path_normalized)
0 ignored issues
show
Bug Best Practice introduced by
The property $canonical_url is declared protected in cs\Page. Since you implement __get, consider adding a @property or @property-read.
Loading history...
157
			);
158
		}
159 21
		if (!@$og['site_name']) {
160 21
			$this->og('site_name', $Config->core['site_name']);
161
		}
162 21
		if (!@$og['type']) {
163 15
			$this->og('type', 'website');
164
		}
165 21
		$this->fill_required_properties_multilingual($og);
166 21
	}
167
	/*
168
	 * @param array $og
169
	 */
170 21
	protected function fill_required_properties_multilingual (&$og) {
171 21
		$Config = Config::instance();
172 21
		if (!$Config->core['multilingual']) {
173 18
			return;
174
		}
175 3
		$L = Language::instance();
176 3
		if (!@$og['locale']) {
177 3
			$this->og('locale', $L->clocale);
0 ignored issues
show
Bug Best Practice introduced by
The property clocale does not exist on cs\Language. Since you implemented __get, consider adding a @property annotation.
Loading history...
178
		}
179
		if (
180 3
			!@$og['locale:alternate'] &&
181 3
			count($Config->core['active_languages']) > 1
182
		) {
183 3
			foreach ($Config->core['active_languages'] as $lang) {
184 3
				if ($lang != $L->clanguage) {
185 3
					$this->og('locale:alternate', $L->get('clocale', $lang));
186
				}
187
			}
188
		}
189 3
	}
190
}
191