These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * @todo Description |
||
5 | * |
||
6 | * I called them Pinicons & Tabicons in keeping with the absolutely pointless name: Favicons. |
||
7 | * |
||
8 | * @package silverstripe-seo |
||
9 | * @subpackage icons |
||
10 | * @author Andrew Gerber <[email protected]> |
||
11 | * @version 1.0.0 |
||
12 | * |
||
13 | */ |
||
14 | class SEO_Icons_SiteConfig_DataExtension extends DataExtension |
||
15 | { |
||
16 | |||
17 | |||
18 | /* Static Variables |
||
19 | ------------------------------------------------------------------------------*/ |
||
20 | |||
21 | // |
||
22 | private static $SEOIconsUpload = 'SEO/SiteConfig/Icons/'; |
||
23 | |||
24 | // |
||
25 | const APPLE_ICON_DEFAULT_BACKGROUND = '000000'; |
||
26 | |||
27 | |||
28 | /* Overload Model |
||
29 | ------------------------------------------------------------------------------*/ |
||
30 | |||
31 | private static $db = array( |
||
0 ignored issues
–
show
|
|||
32 | // Pinned Icon Title |
||
33 | 'PiniconTitle' => 'Varchar(128)', |
||
34 | // Android Pinned Icon |
||
35 | 'AndroidPiniconThemeColor' => 'Varchar(6)', |
||
36 | // MS Tile |
||
37 | 'WindowsPiniconBackgroundColor' => 'Varchar(6)', |
||
38 | // Safari Pinned Tab |
||
39 | // 'SafariTabiconThemeColor' => 'Varchar(6)', // @todo maybe implement |
||
40 | ); |
||
41 | private static $has_one = array( |
||
0 ignored issues
–
show
|
|||
42 | // Favicon |
||
43 | // 'HTML4Favicon' => 'Image', // @todo maybe implement |
||
44 | 'HTML5Favicon' => 'Image', |
||
45 | // Apple Pinned Icon |
||
46 | 'IOSPinicon' => 'Image', |
||
47 | // Android Pinned Icon |
||
48 | 'AndroidPinicon' => 'Image', |
||
49 | // Windows Pinned Icon |
||
50 | 'WindowsPinicon' => 'Image', |
||
51 | // Safari Pinned Tab |
||
52 | // 'SafariTabiconDefault' => 'Image', // @todo maybe implement |
||
53 | // 'SafariTabiconWide' => 'Image', // @todo maybe implement |
||
54 | // 'SafariTabiconLarge' => 'Image', // @todo maybe implement |
||
55 | ); |
||
56 | |||
57 | |||
58 | /* Overload Methods |
||
59 | ------------------------------------------------------------------------------*/ |
||
60 | |||
61 | /** |
||
62 | * Adds tabs & fields to the CMS. |
||
63 | * |
||
64 | * @param FieldList $fields |
||
65 | */ |
||
66 | public function updateCMSFields(FieldList $fields) |
||
67 | { |
||
68 | |||
69 | //// Favicons Tab |
||
70 | |||
71 | $tab = 'Root.Metadata.Favicons'; |
||
72 | |||
73 | //// Favicon |
||
74 | |||
75 | $fields->addFieldsToTab($tab, array( |
||
76 | LabelField::create('FaviconDescription', 'Favicons are `favourite icons` used by browsers in a number of ways whenever an icon is necessary e.g. tabs, history, bookmarks, dashboards.<br />@ <a href="https://en.wikipedia.org/wiki/Favicon" target="_blank">Favicon - Wikipedia, the free encyclopedia</a>') |
||
77 | ->addExtraClass('information') |
||
78 | )); |
||
79 | |||
80 | //// HTML4 Favicon |
||
81 | |||
82 | // check favicon.ico & set status |
||
83 | $icoStatus = ReadonlyField::create('HTML4FaviconStatus', 'Favicon ICO<pre>type: ico</pre><pre>size: (multiple)<br />16x16 & 32x32 & 64x64 px</pre>', 'favicon.ico error'); |
||
84 | if (Director::fileExists('favicon.ico')) { |
||
85 | $icoStatus |
||
86 | ->setValue('favicon.ico found') |
||
87 | ->addExtraClass('success favicon'); |
||
88 | } else { |
||
89 | $icoStatus |
||
90 | ->setValue('favicon.ico not found') |
||
91 | ->addExtraClass('error'); |
||
92 | } |
||
93 | |||
94 | // header & fields |
||
95 | $fields->addFieldsToTab($tab, array( |
||
96 | HeaderField::create('HTML4FaviconHeader', 'HTML4 <span class="aka">( favicon.ico )</span>'), |
||
97 | LabelField::create('HTML4FaviconDescription', 'It is recommended you simply have a `favicon.ico` file in the webroot.') |
||
98 | ->addExtraClass('information'), |
||
99 | $icoStatus |
||
100 | )); |
||
101 | |||
102 | //// HTML5 Favicon |
||
103 | |||
104 | // header & fields |
||
105 | $fields->addFieldsToTab($tab, array( |
||
106 | HeaderField::create('HTML5FaviconHeader', 'HTML5 <span class="aka">( favicon.png )</span>'), |
||
107 | LabelField::create('HTML5FaviconDescription', '@todo Description') |
||
108 | ->addExtraClass('information'), |
||
109 | UploadField::create('HTML5Favicon', 'Favicon PNG<pre>type: png</pre><pre>size: 192x192 px</pre>') |
||
110 | ->setAllowedExtensions(array('png')) |
||
111 | ->setFolderName(self::$SEOIconsUpload) |
||
112 | )); |
||
113 | |||
114 | //// Pinned Icons Tab |
||
115 | |||
116 | $tab = 'Root.Metadata.PinnedIcons'; |
||
117 | |||
118 | //// Pinned Icons Information |
||
119 | |||
120 | $fields->addFieldsToTab($tab, array( |
||
121 | LabelField::create('PiniconDescription', 'Pinned icons are OS-specific desktop shortcuts to pages on your website, they allow you to configure additional theming options to make pages appear more `native` / `web-app-y` within the OS.<br />Given they are OS-specific, they (obviously!) have a different format for each one :(') |
||
122 | ->addExtraClass('information') |
||
123 | )); |
||
124 | |||
125 | //// Pinned Icon Title |
||
126 | |||
127 | // CMS fields |
||
128 | $fields->addFieldsToTab($tab, array( |
||
129 | // header |
||
130 | HeaderField::create('PiniconTitleHeader', 'Pinned Icon Title <span class="aka">( a.k.a. App Name )</span>'), |
||
131 | // description |
||
132 | LabelField::create('PiniconTitleDescription', 'When adding a link to the home screen, the user can choose a caption. By default, this is the bookmarked page title, which is usually fine. However, iOS and Windows 8 let you override this default value.') |
||
133 | ->addExtraClass('information'), |
||
134 | TextField::create('PiniconTitle', 'Application Title') |
||
135 | ->setAttribute('placeholder', 'default: page title') |
||
136 | )); |
||
137 | |||
138 | //// iOS Pinned Icon |
||
139 | |||
140 | // CMS fields |
||
141 | $fields->addFieldsToTab($tab, array( |
||
142 | // header |
||
143 | HeaderField::create('IOSPiniconHeader', 'iOS Pinned Icon <span class="aka">( a.k.a. Touch Icons, Web Clips )</span>'), |
||
144 | // information |
||
145 | LabelField::create('IOSPiniconDescription', 'iPhone and iPad users can pin your web site on their home screen. The link looks like a native app.<br />@ <a href="https://developer.apple.com/library/ios/documentation/AppleApplications/Reference/SafariWebContent/ConfiguringWebApplications/ConfiguringWebApplications.html" target="_blank">Configuring Web Applications - iOS Developer Library</a>') |
||
146 | ->addExtraClass('information'), |
||
147 | // icon |
||
148 | UploadField::create('IOSPinicon', 'iOS Icon<pre>type: png</pre><pre>size: 192x192 px</pre>') |
||
149 | ->setAllowedExtensions(array('png')) |
||
150 | ->setFolderName(self::$SEOIconsUpload) |
||
151 | ->setDescription('iOS will fill the transparent regions with black by default, so put your own background in!') |
||
152 | )); |
||
153 | |||
154 | //// Android Pinned Icon |
||
155 | |||
156 | // CMS fields |
||
157 | $fields->addFieldsToTab($tab, array( |
||
158 | // header |
||
159 | HeaderField::create('AndroidPiniconHeader', 'Android Pinned Icon <span class="aka">( a.k.a. Android Chrome Icons, Launcher Icons )</span>'), |
||
160 | // information |
||
161 | LabelField::create('AndroidPiniconDescription', 'Add to Homescreen is a also a feature of Android Chrome. Your visitors can mix their natives apps and web bookmarks.<br />@ <a href="https://developer.chrome.com/multidevice/android/installtohomescreen" target="_blank">Add to Homescreen - Google Chrome</a>') |
||
162 | ->addExtraClass('information'), |
||
163 | // icon |
||
164 | UploadField::create('AndroidPinicon', 'Android Icon<pre>type: png</pre><pre>size: 192x192 px</pre>') |
||
165 | ->setAllowedExtensions(array('png')) |
||
166 | ->setFolderName(self::$SEOIconsUpload), |
||
167 | // background |
||
168 | TextField::create('AndroidPiniconThemeColor', 'Theme Color<pre>type: hex triplet</pre>') |
||
169 | ->setAttribute('placeholder', 'none') |
||
170 | ->setAttribute('size', 6) |
||
171 | ->setMaxLength(6) |
||
172 | ->setDescription('Starting with Android Lollipop, you can customize the color of the task bar in the switcher.') |
||
173 | )); |
||
174 | |||
175 | //// Windows Pinned Icon |
||
176 | |||
177 | // CMS fields |
||
178 | $fields->addFieldsToTab($tab, array( |
||
179 | // header |
||
180 | HeaderField::create('WindowsShortcutHeader', 'Windows Pinned Icon <span class="aka">( a.k.a. Windows 8 / Metro Tiles )</span>'), |
||
181 | // information |
||
182 | LabelField::create('WindowsShortcutDescription', 'Windows 8 users can pin your web site on their desktop. Your site appears as a tile, just like a native Windows 8 app.<br />@ <a href="https://msdn.microsoft.com/en-us/library/dn455106" target="_blank">Creating custom tiles for IE11 websites (Windows)</a>') |
||
183 | ->addExtraClass('information'), |
||
184 | // icon |
||
185 | UploadField::create('WindowsPinicon', 'Windows Icon<pre>type: png</pre><pre>size: 192x192 px</pre>') |
||
186 | ->setAllowedExtensions(array('png')) |
||
187 | ->setFolderName(self::$SEOIconsUpload), |
||
188 | // background |
||
189 | TextField::create('WindowsPiniconBackgroundColor', 'Background ( Tile ) Color<pre>type: hex triplet</pre>') |
||
190 | ->setAttribute('placeholder', 'none') |
||
191 | ->setAttribute('size', 6) |
||
192 | ->setMaxLength(6) |
||
193 | )); |
||
194 | |||
195 | // @todo Safari Pinned Tab ~ maybe ?? |
||
196 | |||
197 | } |
||
198 | |||
199 | /** |
||
200 | * Generates the Android manifest.json file. |
||
201 | * |
||
202 | * @todo Information about permissions |
||
203 | * |
||
204 | * @return void |
||
205 | */ |
||
206 | public function onAfterWrite() |
||
207 | { |
||
208 | |||
209 | // parent |
||
210 | parent::onAfterWrite(); |
||
211 | |||
212 | // @todo Add success & error states + messages |
||
213 | $this->generateAndroidManifest(); |
||
214 | |||
215 | } |
||
216 | |||
217 | |||
218 | /* Custom Methods |
||
219 | ------------------------------------------------------------------------------*/ |
||
220 | |||
221 | //// Fetch functions |
||
222 | |||
223 | /** |
||
224 | * Fetches the pinicon title. |
||
225 | * |
||
226 | * @return bool|string |
||
227 | */ |
||
228 | public function fetchPiniconTitle() |
||
229 | { |
||
230 | |||
231 | if ($this->owner->PiniconTitle) { |
||
232 | // return pinicon title |
||
233 | return $this->owner->PiniconTitle; |
||
234 | } else { |
||
235 | // default |
||
236 | return false; |
||
237 | } |
||
238 | |||
239 | } |
||
240 | |||
241 | /** |
||
242 | * Fetches the Android pinicon theme color. |
||
243 | * |
||
244 | * @return string|false |
||
245 | */ |
||
246 | public function fetchAndroidPiniconThemeColor() |
||
247 | { |
||
248 | |||
249 | if ($this->owner->AndroidPiniconThemeColor) { |
||
250 | return '#' . $this->owner->AndroidPiniconThemeColor; |
||
251 | } else { |
||
252 | return false; |
||
253 | } |
||
254 | |||
255 | } |
||
256 | |||
257 | /** |
||
258 | * Fetches the Windows pinicon background color. |
||
259 | * |
||
260 | * @return string|false |
||
261 | */ |
||
262 | public function fetchWindowsPiniconBackgroundColor() |
||
263 | { |
||
264 | |||
265 | if ($this->owner->WindowsPiniconBackgroundColor) { |
||
266 | return '#' . $this->owner->WindowsPiniconBackgroundColor; |
||
267 | } else { |
||
268 | return false; |
||
269 | } |
||
270 | |||
271 | } |
||
272 | |||
273 | //// Generate functions |
||
274 | |||
275 | /** |
||
276 | * Generates the android manifest |
||
277 | * |
||
278 | * @todo check this is working 100% |
||
279 | * |
||
280 | * @return bool |
||
281 | */ |
||
282 | public function generateAndroidManifest() |
||
283 | { |
||
284 | |||
285 | //// Android Pinicon Manifest |
||
286 | |||
287 | $pinicon = $this->owner->AndroidPinicon(); |
||
288 | |||
289 | if ($pinicon->exists()) { |
||
290 | |||
291 | // |
||
292 | $manifest = new stdClass(); |
||
293 | |||
294 | // |
||
295 | $manifest->name = $this->owner->PiniconTitle; |
||
296 | // $manifest->start_url = null; @todo Maybe implement |
||
297 | // $manifest->display = null; @todo Maybe implement |
||
298 | // $manifest->orientation = null; @todo Maybe implement |
||
299 | $manifest->icons = array(); |
||
300 | |||
301 | // 0.75x density icon |
||
302 | array_push($manifest->icons, array( |
||
303 | 'src' => $pinicon->Fill(36, 36)->getAbsoluteURL(), |
||
304 | 'sizes' => '36x36', |
||
305 | 'type' => 'image/png', |
||
306 | 'density' => 0.75 |
||
307 | )); |
||
308 | |||
309 | // 1x density icon |
||
310 | array_push($manifest->icons, array( |
||
311 | 'src' => $pinicon->Fill(48, 48)->getAbsoluteURL(), |
||
312 | 'sizes' => '48x48', |
||
313 | 'type' => 'image/png', |
||
314 | 'density' => 1 |
||
315 | )); |
||
316 | |||
317 | // 1.5x density icon |
||
318 | array_push($manifest->icons, array( |
||
319 | 'src' => $pinicon->Fill(72, 72)->getAbsoluteURL(), |
||
320 | 'sizes' => '72x72', |
||
321 | 'type' => 'image/png', |
||
322 | 'density' => 1.5 |
||
323 | )); |
||
324 | |||
325 | // 2x density icon |
||
326 | array_push($manifest->icons, array( |
||
327 | 'src' => $pinicon->Fill(96, 96)->getAbsoluteURL(), |
||
328 | 'sizes' => '96x96', |
||
329 | 'type' => 'image/png', |
||
330 | 'density' => 2 |
||
331 | )); |
||
332 | |||
333 | // 3x density icon |
||
334 | array_push($manifest->icons, array( |
||
335 | 'src' => $pinicon->Fill(144, 144)->getAbsoluteURL(), |
||
336 | 'sizes' => '144x144', |
||
337 | 'type' => 'image/png', |
||
338 | 'density' => 3 |
||
339 | )); |
||
340 | |||
341 | // 4x density icon |
||
342 | array_push($manifest->icons, array( |
||
343 | 'src' => $pinicon->Fill(192, 192)->getAbsoluteURL(), |
||
344 | 'sizes' => '192x192', |
||
345 | 'type' => 'image/png', |
||
346 | 'density' => 4 |
||
347 | )); |
||
348 | |||
349 | // create file |
||
350 | $bytes = file_put_contents(Director::baseFolder() . '/manifest.json', json_encode($manifest)); |
||
351 | |||
352 | // |
||
353 | if ($bytes !== false) { |
||
354 | // success |
||
355 | return true; |
||
356 | } |
||
357 | |||
358 | } |
||
359 | |||
360 | // default return |
||
361 | return false; |
||
362 | |||
363 | } |
||
364 | |||
365 | } |
||
366 |
This check marks private properties in classes that are never used. Those properties can be removed.