Completed
Push — master ( 27f11f...9e269b )
by Andrew
01:57
created

code/SEO_Icons_SiteConfig_DataExtension.php (6 issues)

Upgrade to new PHP Analysis Engine

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/Icons/';
0 ignored issues
show
The property $SEOIconsUpload is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
23
24
    //
25
    const APPLE_ICON_DEFAULT_BACKGROUND = '000000';
26
27
28
    /* Overload Model
29
    ------------------------------------------------------------------------------*/
30
31
    private static $db = array(
32
        // Pinned Icon Title
33
        'PiniconTitle' => 'Varchar(128)',
34
        // IOS Pinned Icon
35
//		'IOSPiniconBackgroundColor' => 'Varchar(6)',
36
        // Android Pinned Icon
37
        'AndroidPiniconThemeColor' => 'Varchar(6)',
38
        // MS Tile
39
        'WindowsPiniconBackgroundColor' => 'Varchar(6)',
40
        // Safari Pinned Tab
41
//		'SafariTabiconThemeColor' => 'Varchar(6)', // @todo maybe implement
42
    );
43
    private static $has_one = array(
44
        // Favicon
45
//		'HTML4Favicon' => 'Image', // @todo maybe implement
46
        'HTML5Favicon' => 'Image',
47
        // Apple Pinned Icon
48
        'IOSPinicon' => 'Image',
49
        // Android Pinned Icon
50
        'AndroidPinicon' => 'Image',
51
        // Windows Pinned Icon
52
        'WindowsPinicon' => 'Image',
53
        // Safari Pinned Tab
54
//		'SafariTabiconDefault' => 'Image', // @todo maybe implement
55
//		'SafariTabiconWide' => 'Image', // @todo maybe implement
56
//		'SafariTabiconLarge' => 'Image', // @todo maybe implement
57
    );
58
59
60
    /* Overload Methods
61
    ------------------------------------------------------------------------------*/
62
63
    // CMS Fields
64
    public function updateCMSFields(FieldList $fields)
65
    {
66
67
        // owner
68
        $config = SiteConfig::current_site_config();
69
        $owner = $this->owner;
0 ignored issues
show
$owner is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
70
71
        //// Favicons Tab
72
73
        $tab = 'Root.Metadata.Favicons';
74
75
        //// Favicon
76
77
        $fields->addFieldsToTab($tab, array(
78
            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>')
79
                ->addExtraClass('information')
80
        ));
81
82
        //// HTML4 Favicon
83
84
        // check favicon.ico & set status
85
        $icoStatus = ReadonlyField::create('HTML4FaviconStatus', 'Favicon ICO<pre>type: ico</pre><pre>size: (multiple)<br />16x16 & 32x32 & 64x64 px</pre>', 'favicon.ico error');
86
        if (Director::fileExists('favicon.ico')) {
87
            $icoStatus
88
                ->setValue('favicon.ico found')
89
                ->addExtraClass('success favicon');
90
        } else {
91
            $icoStatus
92
                ->setValue('favicon.ico not found')
93
                ->addExtraClass('error');
94
        }
95
96
        // header & fields
97
        $fields->addFieldsToTab($tab, array(
98
            HeaderField::create('HTML4FaviconHeader', 'HTML4 <span class="aka">( favicon.ico )</span>'),
99
            LabelField::create('HTML4FaviconDescription', 'It is recommended you simply have a `favicon.ico` file in the webroot.')
100
                ->addExtraClass('information'),
101
            $icoStatus
102
        ));
103
104
        //// HTML5 Favicon
105
106
        // header & fields
107
        $fields->addFieldsToTab($tab, array(
108
            HeaderField::create('HTML5FaviconHeader', 'HTML5 <span class="aka">( favicon.png )</span>'),
109
            LabelField::create('HTML5FaviconDescription', '@todo Description')
110
                ->addExtraClass('information'),
111
            UploadField::create('HTML5Favicon', 'Favicon PNG<pre>type: png</pre><pre>size: 192x192 px</pre>')
112
                ->setAllowedExtensions(array('png'))
113
                ->setFolderName('SiteConfig/seo-icons/')
114
        ));
115
116
        //// Pinned Icons Tab
117
118
        $tab = 'Root.Metadata.PinnedIcons';
119
120
        //// Pinned Icons Information
121
122
        $fields->addFieldsToTab($tab, array(
123
            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 :(')
124
                ->addExtraClass('information')
125
        ));
126
127
        //// Pinned Icon Title
128
129
        // CMS fields
130
        $fields->addFieldsToTab($tab, array(
131
            // header
132
            HeaderField::create('PiniconTitleHeader', 'Pinned Icon Title <span class="aka">( a.k.a. App Name )</span>'),
133
            // description
134
            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.')
135
                ->addExtraClass('information'),
136
            TextField::create('PiniconTitle', 'Application Title')
137
                ->setAttribute('placeholder', 'default: page title')
138
        ));
139
140
        //// iOS Pinned Icon
141
142
        // CMS fields
143
        $fields->addFieldsToTab($tab, array(
144
            // header
145
            HeaderField::create('IOSPiniconHeader', 'iOS Pinned Icon <span class="aka">( a.k.a. Touch Icons, Web Clips )</span>'),
146
            // information
147
            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>')
148
                ->addExtraClass('information'),
149
            // icon
150
            UploadField::create('IOSPinicon', 'iOS Icon<pre>type: png</pre><pre>size: 192x192 px</pre>')
151
                ->setAllowedExtensions(array('png'))
152
                ->setFolderName('SiteConfig/seo-icons/')
153
                ->setDescription('iOS will fill the transparent regions with black by default, so put your own background in!'),
154
            // background
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
155
//			TextField::create('IOSPiniconBackgroundColor', 'Background Color<pre>type: hex triplet</pre>')
156
//				->setAttribute('placeholder', self::APPLE_ICON_DEFAULT_BACKGROUND)
157
//				->setAttribute('size', 6)
158
//				->setMaxLength(6)
159
//				->setDescription('iOS will fill the transparent regions with black by default, so put your own background in.')
160
        ));
161
162
        //// Android Pinned Icon
163
164
        // CMS fields
165
        $fields->addFieldsToTab($tab, array(
166
            // header
167
            HeaderField::create('AndroidPiniconHeader', 'Android Pinned Icon <span class="aka">( a.k.a. Android Chrome Icons, Launcher Icons )</span>'),
168
            // information
169
            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>')
170
                ->addExtraClass('information'),
171
            // icon
172
            UploadField::create('AndroidPinicon', 'Android Icon<pre>type: png</pre><pre>size: 192x192 px</pre>')
173
                ->setAllowedExtensions(array('png'))
174
                ->setFolderName('SiteConfig/seo-icons/'),
175
            // background
176
            TextField::create('AndroidPiniconThemeColor', 'Theme Color<pre>type: hex triplet</pre>')
177
                ->setAttribute('placeholder', 'none')
178
                ->setAttribute('size', 6)
179
                ->setMaxLength(6)
180
                ->setDescription('Starting with Android Lollipop, you can customize the color of the task bar in the switcher.')
181
        ));
182
183
        //// Windows Pinned Icon
184
185
        // CMS fields
186
        $fields->addFieldsToTab($tab, array(
187
            // header
188
            HeaderField::create('WindowsShortcutHeader', 'Windows Pinned Icon <span class="aka">( a.k.a. Windows 8 / Metro Tiles )</span>'),
189
            // information
190
            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>')
191
                ->addExtraClass('information'),
192
            // icon
193
            UploadField::create('WindowsPinicon', 'Windows Icon<pre>type: png</pre><pre>size: 192x192 px</pre>')
194
                ->setAllowedExtensions(array('png'))
195
                ->setFolderName('SiteConfig/seo-icons/'),
196
            // background
197
            TextField::create('WindowsPiniconBackgroundColor', 'Background ( Tile ) Color<pre>type: hex triplet</pre>')
198
                ->setAttribute('placeholder', 'none')
199
                ->setAttribute('size', 6)
200
                ->setMaxLength(6)
201
        ));
202
203
        // @todo Safari Pinned Tab ~ maybe ??
204
205
    }
206
207
    public function onAfterWrite()
208
    {
209
210
        // parent
211
        parent::onAfterWrite();
212
213
        // regenerate manifest
214
        if ($this->generateAndroidManifest()) {
0 ignored issues
show
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
215
            // @todo SilverStripe success message
216
        } else {
0 ignored issues
show
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
217
            // @todo SilverStripe failure message
218
        }
219
220
    }
221
222
223
    /* Custom Methods
224
    ------------------------------------------------------------------------------*/
225
226
    //// fetch functions
227
228
    public function fetchPiniconTitle()
0 ignored issues
show
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
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
    public function fetchAndroidPiniconThemeColor()
242
    {
243
244
        if ($this->owner->AndroidPiniconThemeColor) {
245
            return '#' . $this->owner->AndroidPiniconThemeColor;
246
        } else {
247
            return false;
248
        }
249
250
    }
251
252
    public function fetchWindowsPiniconBackgroundColor()
253
    {
254
255
        if ($this->owner->WindowsPiniconBackgroundColor) {
256
            return '#' . $this->owner->WindowsPiniconBackgroundColor;
257
        } else {
258
            return false;
259
        }
260
261
    }
262
263
    //// generate functions
264
265
    public function generateAndroidManifest()
266
    {
267
268
        //// Android Pinicon Manifest
269
270
        $pinicon = $this->owner->AndroidPinicon();
271
272
        if ($pinicon->exists()) {
273
274
            //
275
            $manifest = new stdClass();
276
277
            //
278
            $manifest->name = $this->owner->PiniconTitle;
279
//			$manifest->start_url = null; @todo Maybe implement
280
//			$manifest->display = null; @todo Maybe implement
281
//			$manifest->orientation = null; @todo Maybe implement
282
            $manifest->icons = array();
283
284
            // 0.75x density icon
285
            array_push($manifest->icons, array(
286
                'src' => $pinicon->Fill(36, 36)->getAbsoluteURL(),
287
                'sizes' => '36x36',
288
                'type' => 'image/png',
289
                'density' => 0.75
290
            ));
291
292
            // 1x density icon
293
            array_push($manifest->icons, array(
294
                'src' => $pinicon->Fill(48, 48)->getAbsoluteURL(),
295
                'sizes' => '48x48',
296
                'type' => 'image/png',
297
                'density' => 1
298
            ));
299
300
            // 1.5x density icon
301
            array_push($manifest->icons, array(
302
                'src' => $pinicon->Fill(72, 72)->getAbsoluteURL(),
303
                'sizes' => '72x72',
304
                'type' => 'image/png',
305
                'density' => 1.5
306
            ));
307
308
            // 2x density icon
309
            array_push($manifest->icons, array(
310
                'src' => $pinicon->Fill(96, 96)->getAbsoluteURL(),
311
                'sizes' => '96x96',
312
                'type' => 'image/png',
313
                'density' => 2
314
            ));
315
316
            // 3x density icon
317
            array_push($manifest->icons, array(
318
                'src' => $pinicon->Fill(144, 144)->getAbsoluteURL(),
319
                'sizes' => '144x144',
320
                'type' => 'image/png',
321
                'density' => 3
322
            ));
323
324
            // 4x density icon
325
            array_push($manifest->icons, array(
326
                'src' => $pinicon->Fill(192, 192)->getAbsoluteURL(),
327
                'sizes' => '192x192',
328
                'type' => 'image/png',
329
                'density' => 4
330
            ));
331
332
            // create file
333
            $bytes = file_put_contents($_SERVER['DOCUMENT_ROOT'] . '/manifest.json', json_encode($manifest));
334
335
            //
336
            if ($bytes !== false) {
337
                // success
338
                return true;
339
            } else {
340
                // failure
341
                return false;
342
            }
343
344
        }
345
346
    }
347
348
}
349