ShareThisSimpleProvider   F
last analyzed

Complexity

Total Complexity 63

Size/Duplication

Total Lines 528
Duplicated Lines 0 %

Importance

Changes 25
Bugs 1 Features 1
Metric Value
wmc 63
eloc 182
c 25
b 1
f 1
dl 0
loc 528
rs 3.36

30 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A setLinkMethod() 0 5 1
A setHashTags() 0 5 1
A setTitleMethod() 0 5 1
A setDescriptionMethod() 0 5 1
A setVias() 0 5 1
A setMentions() 0 5 1
A setImageMethods() 0 5 1
A getTumblrShareLink() 0 6 2
A getSignalShareLink() 0 6 2
A getRedditShareLink() 0 6 2
A shareThisTitleField() 0 3 1
A shareThisLinkField() 0 3 1
A getShareThisArray() 0 38 3
B shareThisMediaField() 0 30 10
A ShareThisLinks() 0 27 3
A getBlueSkyShareLink() 0 6 2
A getTwitterShareLink() 0 6 2
A getPrintPageLink() 0 3 1
A shareThisDescriptionField() 0 20 4
A shareThisFieldAsString() 0 10 3
A getWhatsAppShareLink() 0 6 2
A getFacebookShareLink() 0 6 2
A getValuesFromArrayToString() 0 9 4
A getSnapchatShareLink() 0 6 2
A getSmsShareLink() 0 6 2
A getWindowPopupHtml() 0 8 1
A getEmailShareLink() 0 6 2
A getLinkedInShareLink() 0 6 2
A getPinterestShareLink() 0 6 2

How to fix   Complexity   

Complex Class

Complex classes like ShareThisSimpleProvider often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ShareThisSimpleProvider, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Sunnysideup\ShareThisSimple\Api;
4
5
use SilverStripe\Core\Config\Config;
6
use SilverStripe\Core\Manifest\ModuleResourceLoader;
7
use SilverStripe\ORM\ArrayList;
8
use SilverStripe\ORM\DataObject;
9
use SilverStripe\ORM\FieldType\DBField;
10
use SilverStripe\ORM\FieldType\DBHTMLText;
11
use SilverStripe\View\ArrayData;
12
use SilverStripe\View\ViewableData;
13
14
class ShareThisSimpleProvider extends ViewableData
15
{
16
    /**
17
     * @var null|DataObject
18
     */
19
    protected $object;
20
21
    protected $linkMethod = 'AbsoluteLink';
22
23
    protected $titleMethod = 'Title';
24
25
    protected $imageMethods = [];
26
27
    protected $descriptionMethod = 'SocialMediaDescription';
28
29
    //change to 'SocialMediaDescription'
30
31
    protected $hashTagArray = [];
32
33
    protected $mentionsArray = [];
34
35
    protected $viasArray = [];
36
37
    /**
38
     * @var string
39
     */
40
    protected $pageURL = '';
41
42
    /**
43
     * @var string
44
     */
45
    protected $title = '';
46
47
    /**
48
     * @var string
49
     */
50
    protected $titleFull = '';
51
52
    /**
53
     * @var string
54
     */
55
    protected $media = '';
56
57
    /**
58
     * @var string
59
     */
60
    protected $description = '';
61
62
    /**
63
     * @var string
64
     */
65
    protected $descriptionFull = '';
66
67
    /**
68
     * @var string
69
     */
70
    protected $hashTags = '';
71
72
    /**
73
     * @var string
74
     */
75
    protected $mentions = '';
76
77
    /**
78
     * @var string
79
     */
80
    protected $vias = '';
81
82
    protected static $cacheGetShareThisArray = [];
83
84
    private static $pop_up_window_height = 320;
85
86
    private static $pop_up_window_width = 320;
87
88
    private static $description_method = '';
89
90
    private static $default_mentions = [];
91
92
    private static $default_vias = [];
93
94
    private static $default_hash_tags = [];
95
96
    private static $image_methods = [];
97
98
    private static $icon_links = [];
99
100
    private static $casting = [
101
        'FacebookShareLink' => 'Varchar',
102
        'BlueSkyShareLink' => 'Varchar',
103
        'TwitterShareLink' => 'Varchar',
104
        'TumblrShareLink' => 'Varchar',
105
        'PinterestShareLink' => 'Varchar',
106
        'RedditShareLink' => 'Varchar',
107
        'LinkedInShareLink' => 'Varchar',
108
        'EmailShareLink' => 'Varchar',
109
        'SmsShareLink' => 'Varchar',
110
        'WhatsAppShareLink' => 'Varchar',
111
        'SnapchatShareLink' => 'Varchar',
112
        'SignalShareLink' => 'Varchar',
113
        'PrintPageLink' => 'Varchar'
114
    ];
115
116
    /**
117
     * @param DataObject $object
118
     */
119
    public function __construct($object)
120
    {
121
        parent::__construct();
122
        $this->object = $object;
123
    }
124
125
    public function setLinkMethod(string $s): self
126
    {
127
        $this->linkMethod = $s;
128
129
        return $this;
130
    }
131
132
    public function setTitleMethod(string $s): self
133
    {
134
        $this->titleMethod = $s;
135
136
        return $this;
137
    }
138
139
    public function setImageMethods(string $a): self
140
    {
141
        $this->imageMethods = $a;
142
143
        return $this;
144
    }
145
146
    public function setDescriptionMethod(string $s): self
147
    {
148
        $this->descriptionMethod = $s;
149
150
        return $this;
151
    }
152
153
    public function setHashTags(array $a): self
154
    {
155
        $this->hashTagsArray = $a;
0 ignored issues
show
Bug Best Practice introduced by
The property hashTagsArray does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
156
157
        return $this;
158
    }
159
160
    public function setMentions(array $a): self
161
    {
162
        $this->mentionsArray = $a;
163
164
        return $this;
165
    }
166
167
    public function setVias(array $a): self
168
    {
169
        $this->viasArray = $a;
170
171
        return $this;
172
    }
173
174
    public function getWindowPopupHtml(): DBHTMLText
175
    {
176
        $width = $this->Config()->get('pop_up_window_width');
0 ignored issues
show
Unused Code introduced by
The assignment to $width is dead and can be removed.
Loading history...
177
        $height = $this->Config()->get('pop_up_window_height');
0 ignored issues
show
Unused Code introduced by
The assignment to $height is dead and can be removed.
Loading history...
178
        $html = 'onclick="return openPopupWindow(this.href);"';
179
        // $html = preg_replace('#\s+#', ' ', $html);
180
181
        return DBHTMLText::create_field('HTMLText', $html);
0 ignored issues
show
Bug Best Practice introduced by
The expression return SilverStripe\ORM\...ield('HTMLText', $html) returns the type SilverStripe\ORM\FieldType\DBField which includes types incompatible with the type-hinted return SilverStripe\ORM\FieldType\DBHTMLText.
Loading history...
182
    }
183
184
    /**
185
     * return of ShareThisLinks.
186
     *
187
     * @param string $customDescription e.g. foo bar cool stuff
188
     */
189
    public function ShareThisLinks(?string $customDescription = ''): ArrayList
190
    {
191
        $arrayList = ArrayList::create();
192
        $options = array_keys(Config::inst()->get(ShareThisSimpleProvider::class, 'casting', Config::UNINHERITED));
193
        $icons = $this->config()->get('icon_links');
194
        foreach ($options as $option) {
195
            $className = str_replace('ShareLink', '', (string) $option);
196
            $className = strtolower($className);
197
            $icon = '';
198
            if (! empty($icons[$className])) {
199
                $urlLink = $icons[$className];
200
                $url = ModuleResourceLoader::resourceURL($urlLink);
201
                $icon = DBField::create_field('HTMLText', '<img src="' . $url . '" alt="' . $option . '" />');
202
            }
203
            $method = 'get' . $option;
204
            $arrayList->push(
205
                ArrayData::create(
206
                    [
207
                        'Class' => $className,
208
                        'Link' => $this->{$method}($customDescription),
209
                        'Icon' => $icon,
210
                    ]
211
                )
212
            );
213
        }
214
215
        return $arrayList;
216
    }
217
218
219
    /**
220
     * Generate a URL to share this content on Facebook.
221
     *
222
     * @param string $customDescription e.g. foo bar cool stuff
223
     *                                  https://www.facebook.com/dialog/feed?
224
     *                                  &link=URL_HERE
225
     *                                  &picture=IMAGE_LINK_HERE
226
     *                                  &name=TITLE_HERE
227
     *                                  &caption=%20
228
     *                                  &description=DESCRIPTION_HERE
229
     *                                  &redirect_uri=http%3A%2F%2Fwww.facebook.com%2F
230
     */
231
    public function getFacebookShareLink(?string $customDescription = ''): string
232
    {
233
        $this->getShareThisArray($customDescription);
234
235
        return '' === $this->pageURL ? '' :
236
            'https://www.facebook.com/sharer/sharer.php?u=' . $this->pageURL;
237
    }
238
239
240
    /**
241
     * Generate a URL to share this content on Twitter
242
     * Specs: https://dev.twitter.com/web/tweet-button/web-intent.
243
     * example: https://twitter.com/intent/tweet?
244
     *  &source=http%3A%2F%2Fsunnysideup.co.nz
245
     *  &text=test:%20http%3A%2F%2Fsunnysideup.co.nz
246
     *  &via=foobar.
247
     *
248
     * @param string $customDescription e.g. foo bar cool stuff
249
     */
250
    public function getBlueSkyShareLink(?string $customDescription = ''): string
251
    {
252
        $this->getShareThisArray($customDescription);
253
254
        return '' === $this->pageURL ? '' :
255
            'https://bsky.app/intent/compose?text=' . ($this->titleFull) . '&url=' . $this->pageURL;
256
    }
257
258
    /**
259
     * Generate a URL to share this content on Twitter
260
     * Specs: https://dev.twitter.com/web/tweet-button/web-intent.
261
     * example: https://twitter.com/intent/tweet?
262
     *  &source=http%3A%2F%2Fsunnysideup.co.nz
263
     *  &text=test:%20http%3A%2F%2Fsunnysideup.co.nz
264
     *  &via=foobar.
265
     *
266
     * @param string $customDescription e.g. foo bar cool stuff
267
     */
268
    public function getTwitterShareLink(?string $customDescription = ''): string
269
    {
270
        $this->getShareThisArray($customDescription);
271
272
        return '' === $this->pageURL ? '' :
273
            'https://x.com/intent/tweet?text=' . ($this->titleFull) . '&url=' . $this->pageURL;
274
    }
275
276
277
    /**
278
     * Generate a URL to share this content on Twitter
279
     * Specs: https://dev.twitter.com/web/tweet-button/web-intent.
280
     *
281
     * @param string $customDescription e.g. foo bar cool stuff
282
     *
283
     * @return string
284
     */
285
    public function getTumblrShareLink(?string $customDescription = '')
286
    {
287
        $this->getShareThisArray($customDescription);
288
289
        return '' === $this->pageURL ? '' :
290
            'https://www.tumblr.com/share/link?url=' . ($this->pageURL) . '&name=' . ($this->title) . '&description=' . ($this->description);
291
    }
292
293
294
    /**
295
     * Generate a URL to share this content on Twitter
296
     * Specs: https://dev.twitter.com/web/tweet-button/web-intent.
297
     *
298
     * @param string $customDescription e.g. foo bar cool stuff
299
     */
300
    public function getPinterestShareLink(?string $customDescription = ''): string
301
    {
302
        $this->getShareThisArray($customDescription);
303
304
        return '' === $this->pageURL ? '' :
305
            'https://pinterest.com/pin/create/button/?url=' . $this->pageURL . '&description=' . $this->description . '&media=' . $this->media . '';
306
    }
307
308
309
310
    /**
311
     * Generate a URL to share this content on Twitter
312
     * Specs: https://dev.twitter.com/web/tweet-button/web-intent.
313
     *
314
     * @param string $customDescription e.g. foo bar cool stuff
315
     */
316
    public function getRedditShareLink(?string $customDescription = ''): string
317
    {
318
        $this->getShareThisArray($customDescription);
319
320
        return '' === $this->pageURL ? '' :
321
            'https://reddit.com/submit?url=' . $this->pageURL . '&title=' . $this->title;
322
    }
323
324
    /**
325
     * Generate a URL to share this content on Twitter
326
     * Specs: ???
327
     * example: https://www.linkedin.com/shareArticle?
328
     * mini=true&url=https://www.cnn.com&title=&summary=chek this out&source=.
329
     *
330
     * @param string $customDescription e.g. foo bar cool stuff
331
     */
332
    public function getLinkedInShareLink(?string $customDescription = ''): string
333
    {
334
        $this->getShareThisArray($customDescription);
335
336
        return '' === $this->pageURL ? '' :
337
            'https://www.linkedin.com/shareArticle?mini=true&url=' . $this->pageURL . '&summary=' . $this->titleFull . '';
338
    }
339
340
    /**
341
     * Generate a 'mailto' URL to share this content via Email.
342
     *
343
     * @param string $customDescription e.g. foo bar cool stuff
344
     */
345
    public function getEmailShareLink(?string $customDescription = ''): string
346
    {
347
        $this->getShareThisArray($customDescription);
348
349
        return '' === $this->pageURL ? '' :
350
            'mailto:?subject=' . $this->title . '&body=' . $this->pageURL;
351
    }
352
353
    /**
354
     * Generate a URL to share this content via SMS.
355
     *
356
     * @param string $customDescription e.g. foo bar cool stuff
357
     */
358
    public function getSmsShareLink(?string $customDescription = ''): string
359
    {
360
        $this->getShareThisArray($customDescription);
361
362
        return '' === $this->pageURL ? '' :
363
            'sms:?body=' . ($this->titleFull . urlencode(' ') . $this->pageURL);
364
    }
365
    /**
366
     * Generate a URL to share this content on WhatsApp.
367
     *
368
     * @param string $customDescription e.g. foo bar cool stuff
369
     */
370
    public function getWhatsAppShareLink(?string $customDescription = ''): string
371
    {
372
        $this->getShareThisArray($customDescription);
373
374
        return '' === $this->pageURL ? '' :
375
            'https://api.whatsapp.com/send?text=' . ($this->titleFull . urlencode(' ') . $this->pageURL);
376
    }
377
378
    /**
379
     * Generate a URL to share this content on Snapchat.
380
     *
381
     * @param string $customDescription e.g. foo bar cool stuff
382
     */
383
    public function getSnapchatShareLink(?string $customDescription = ''): string
384
    {
385
        $this->getShareThisArray($customDescription);
386
387
        return '' === $this->pageURL ? '' :
388
            'https://www.snapchat.com/share?url=' . $this->pageURL . '&text=' . $this->titleFull;
389
    }
390
391
392
393
    /**
394
     * Generate a URL to share this content on Signal.
395
     *
396
     * @param string $customDescription e.g. foo bar cool stuff
397
     */
398
    public function getSignalShareLink(?string $customDescription = ''): string
399
    {
400
        $this->getShareThisArray($customDescription);
401
402
        return '' === $this->pageURL ? '' :
403
            'https://signal.me/#p/' . ($this->titleFull . urlencode(' ') . $this->pageURL);
404
    }
405
406
407
    public function getPrintPageLink(): string
408
    {
409
        return 'javascript:window.print();';
410
    }
411
412
413
    /**
414
     * @param string $customDescription e.g. foo bar cool stuff
415
     */
416
    public function getShareThisArray(?string $customDescription = ''): array
417
    {
418
        $cacheKey = $this->object->ID . '_' . preg_replace('#[^A-Za-z0-9]#', '_', $customDescription);
419
        if (! isset(self::$cacheGetShareThisArray[$cacheKey])) {
420
            //1. link
421
            $this->link = $this->shareThisLinkField();
0 ignored issues
show
Bug Best Practice introduced by
The property link does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
422
423
            $this->title = $this->shareThisTitleField();
424
425
            $this->media = $this->shareThisMediaField();
426
427
            $this->description = $this->shareThisDescriptionField($customDescription);
428
429
            $this->hashTags = $this->getValuesFromArrayToString('hashTagsArray', 'hash_tags', '#');
430
            $this->mentions = $this->getValuesFromArrayToString('mentionsArray', 'mentions');
431
            $this->vias = $this->getValuesFromArrayToString('viasArray', 'vias');
432
            $this->titleFull = trim($this->mentions . ' ' . $this->title . ' ' . $this->hashTags . ' ' . $this->vias);
433
            $this->descriptionFull = trim($this->mentions . ' ' . $this->description . ' ' . $this->hashTags . ' ' . $this->vias);
434
435
            //return ...
436
            self::$cacheGetShareThisArray[$cacheKey] = [
437
                'pageURL' => rawurlencode($this->link),
438
                'title' => rawurlencode($this->title),
439
                'titleFull' => rawurlencode($this->titleFull),
440
                'media' => rawurlencode($this->media),
441
                'description' => rawurlencode($this->description),
442
                'descriptionFull' => rawurlencode($this->descriptionFull),
443
                'hashTags' => rawurlencode($this->hashTags),
444
                'mentions' => rawurlencode($this->mentions),
445
                'vias' => rawurlencode($this->vias),
446
            ];
447
        }
448
449
        foreach (self::$cacheGetShareThisArray[$cacheKey] as $field => $value) {
450
            $this->{$field} = $value;
451
        }
452
453
        return self::$cacheGetShareThisArray[$cacheKey];
454
    }
455
456
457
    protected function getValuesFromArrayToString(string $variable, string $staticVariable, ?string $prepender = '@')
458
    {
459
        $a = empty($this->{$variable}) ? $this->Config()->get($staticVariable) : $this->{$variable};
460
        $str = '';
461
        if (is_array($a) && count($a)) {
462
            $str = $prepender . implode(' ' . $prepender, $a);
463
        }
464
465
        return trim($str);
466
    }
467
468
    private function shareThisLinkField(): string
469
    {
470
        return $this->shareThisFieldAsString($this->linkMethod);
471
    }
472
473
    private function shareThisTitleField(): string
474
    {
475
        return $this->shareThisFieldAsString($this->titleMethod);
476
    }
477
478
    private function shareThisFieldAsString(string $field): string
479
    {
480
        $value = '';
481
        if ($this->object->hasMethod($field)) {
0 ignored issues
show
Bug introduced by
The method hasMethod() does not exist on null. ( Ignorable by Annotation )

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

481
        if ($this->object->/** @scrutinizer ignore-call */ hasMethod($field)) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
482
            $value = $this->object->{$field}();
483
        } elseif (isset($this->object->{$field})) {
484
            $value = $this->object->{$field};
485
        }
486
487
        return (string) $value;
488
    }
489
490
    private function shareThisMediaField(): string
491
    {
492
        $media = '';
493
        $imageMethods = $this->imageMethods;
494
        if (is_array($imageMethods) && count($imageMethods)) {
495
            //do nothing
496
        } else {
497
            $imageMethods = Config::inst()->get(
498
                'ShareThisSimpleProvider',
499
                'image_methods'
500
            );
501
        }
502
503
        if (is_array($imageMethods) && count($imageMethods)) {
504
            foreach ($imageMethods as $imageMethod) {
505
                if ($this->object->hasMethod($imageMethod)) {
506
                    $imageField = $imageMethod . 'ID';
507
                    if ($this->{$imageField}) {
508
                        $image = $this->object->{$imageMethod}();
509
                        if ($image && $image->exists()) {
510
                            $media = $image->AbsoluteLink();
511
512
                            break;
513
                        }
514
                    }
515
                }
516
            }
517
        }
518
519
        return $media;
520
    }
521
522
    private function shareThisDescriptionField(?string $customDescription = ''): string
523
    {
524
        if ($customDescription) {
525
            $description = $customDescription;
526
        } else {
527
            $description = '';
528
            $descriptionMethod = $this->descriptionMethod;
529
            if (! $descriptionMethod) {
530
                $descriptionMethod = Config::inst()->get(
531
                    'ShareThisSimpleProvider',
532
                    'description_method'
533
                );
534
            }
535
536
            if ($descriptionMethod) {
537
                $description = $this->shareThisFieldAsString($descriptionMethod);
538
            }
539
        }
540
541
        return $description;
542
    }
543
}
544