Completed
Pull Request — master (#9)
by
unknown
08:34
created

ShareThisSTE   A

Complexity

Total Complexity 42

Size/Duplication

Total Lines 267
Duplicated Lines 10.11 %

Coupling/Cohesion

Components 1
Dependencies 16

Importance

Changes 0
Metric Value
dl 27
loc 267
rs 9.0399
c 0
b 0
f 0
wmc 42
lcom 1
cbo 16

9 Methods

Rating   Name   Duplication   Size   Complexity  
A updateCMSFields() 0 31 5
A getShowShareIcons() 0 10 3
A getShareIcons() 0 5 1
A ShareAllExpandedList() 0 7 1
A IncludeShareAll() 0 5 1
A getShareAll() 0 6 2
B makeShareIcons() 10 54 10
B makeBookmarks() 0 25 6
C applyToOwnerClass() 17 34 13

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like ShareThisSTE 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 ShareThisSTE, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace SunnysideUp\ShareThis;
4
5
use SilverStripe\Dev\Debug;
6
use SilverStripe\Forms\FieldList;
7
use SilverStripe\Forms\HeaderField;
8
use SilverStripe\Forms\CheckboxField;
9
use SilverStripe\Forms\LiteralField;
10
use SunnysideUp\ShareThis\ShareThisOptions;
11
use SilverStripe\View\Requirements;
12
use SilverStripe\Core\Config\Config;
13
use SilverStripe\Core\Convert;
14
use SilverStripe\View\ArrayData;
15
use SilverStripe\ORM\ArrayList;
16
use SunnysideUp\ShareThis\ShareThisDataObject;
17
use SilverStripe\CMS\Model\SiteTreeExtension;
18
19
/**
20
 * Add a field to each SiteTree object and it's subclasses to enable Share icons.
21
 * @author nicolaas [at] sunnysideup.co.nz
22
 * @inspiration: Silverstripe Original Module - full credits to them.  We made our own to improve their module
23
 * @todo fix populateDefaults to make sure SiteConfig table is built first
24
 */
25
class ShareThisSTE extends SiteTreeExtension
26
{
27
28
    /**
29
     * Use the font-awesome icon collection?
30
     * @var Boolean
31
     */
32
    private static $use_font_awesome = true;
33
34
    /**
35
     * list of sitetree extending classnames where
36
     * the ShareThis functionality should be included
37
     * @var Array
38
     */
39
    private static $always_include_in = [];
40
41
    /**
42
     * list of sitetree extending classnames where
43
     * the ShareThis functionality should NEVER be included
44
     * @var Array
45
     */
46
    private static $never_include_in = [];
47
48
    /**
49
    * use BW icons
50
    * @var boolean
51
    */
52
    private static $use_bw_effect = false;
53
54
    /**
55
    * specify icons to be included, if left empty, this variable will be ignored
56
    * We have this variable so that you can setup a bunch of default icons
57
    * @var array
58
    */
59
    private static $included_icons = [];
60
61
    /**
62
    * specify icons to be excluded, if left empty, this variable will be ignored
63
    * We have this variable so that you can setup a bunch of default icons
64
    * @var array
65
    */
66
    private static $excluded_icons = [];
67
68
    /**
69
     * standard SS method
70
     * @var Array
71
     **/
72
    private static $db = array(
73
        'ShareIcons' => 'Boolean'
74
    );
75
76
    /**
77
     * @param  FieldList $fields
78
     *
79
     * @return FieldList $fields
80
     */
81
    public function updateCMSFields(FieldList $fields)
82
    {
83
        if ($this->applyToOwnerClass()) {
84
            $config = $this->owner->getSiteConfig();
0 ignored issues
show
Bug introduced by
The method getSiteConfig() does not exist on SilverStripe\ORM\DataObject. Did you maybe mean config()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
85
86
            if (! $config->AlwaysIncludeShareThisLinks) {
87
                $fields->addFieldToTab('Root.SocialMedia', HeaderField::create('ShareThisHeader', 'Allow users to share this page'));
88
89
                $fields->addFieldToTab('Root.SocialMedia', CheckboxField::create('ShareIcons', 'Show Share Icons on this page', $config->IncludeByDefault));
90
91
                $fields->addFieldToTab('Root.SocialMedia', LiteralField::create('LinkToSiteConfigSocialMedia', "<p>Note: make sure to review the social media settings in the <a href=\"{$config->CMSEditLink()}\">Site Config</a>.</p>"));
92
            }
93
94
            $list = ShareThisOptions::get_all_options($this->owner->Title, $this->owner->Link(), $this->owner->MetaDescription);
95
96
            $fields->addFieldToTab('Root.SocialMedia', HeaderField::create('ShareThisNow', 'Share this page on your favourite social media sites...'));
97
98
            $html = "<div><p>Click on any of the icons below to share the '<i>{$this->owner->Title}</i>' page. Any click will open a new tab/window where you will need to enter your login details.</p>";
99
100
            foreach ($list as $key => $innerArray) {
101
                if (! isset($innerArray['click'])) {
102
                    $html .= "<span><a href=\"{$innerArray['url']}\" target=\"_blank\" style=\"whitespace: nowrap; display: inline-block;\"><img src=\"" . SS_SHARETHIS_DIR . "/images/icons/$key.png\" alt=\"$key\"/>{$innerArray['title']}</a></span>&nbsp;&nbsp;";
103
                }
104
            }
105
106
            $html .= '</div>';
107
            $fields->addFieldToTab('Root.SocialMedia', LiteralField::create('ShareNow', $html));
108
        }
109
110
        return $fields;
111
    }
112
113
    /**
114
     * Show the sharing icons
115
     */
116
    public function getShowShareIcons()
0 ignored issues
show
Documentation introduced by
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...
117
    {
118
        if ($this->applyToOwnerClass()) {
119
            $config = $this->owner->getSiteConfig();
0 ignored issues
show
Bug introduced by
The method getSiteConfig() does not exist on SilverStripe\ORM\DataObject. Did you maybe mean config()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
120
            if ($config->AlwaysIncludeShareThisLinks) {
121
                return true;
122
            }
123
            return $this->owner->ShareIcons;
124
        }
125
    }
126
127
    /**
128
     * Get the sharing icons
129
     */
130
    public function getShareIcons()
131
    {
132
        $bookmarks = $this->makeBookmarks('IncludeThisIcon');
133
        return $this->makeShareIcons($bookmarks);
134
    }
135
136
    /**
137
     * Grabbing front end dependencies for the expanded sharing list with some extra
138
     * functionality
139
     */
140
    public function ShareAllExpandedList()
141
    {
142
        Requirements::javascript('silverstripe/admin: thirdparty/jquery/jquery.min.js');
143
        Requirements::javascript('sunnysideup/sharethis: javascript/ShareAllExpandedList.js');
144
        $bookmarks = $this->makeBookmarks('IncludeThisIconInExtendedList');
145
        return $this->makeShareIcons($bookmarks);
146
    }
147
148
    /**
149
     * Include share all
150
     */
151
    public function IncludeShareAll()
0 ignored issues
show
Documentation introduced by
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...
152
    {
153
        $config = $this->owner->getSiteConfig();
0 ignored issues
show
Bug introduced by
The method getSiteConfig() does not exist on SilverStripe\ORM\DataObject. Did you maybe mean config()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
154
        return $config->ShareThisAllInOne;
155
    }
156
157
    /**
158
     * @return boolean
0 ignored issues
show
Documentation introduced by
Should the return type not be string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
159
     */
160
    public function getShareAll()
161
    {
162
        if ($this->IncludeShareAll()) {
163
            return ShareThisOptions::get_share_all();
164
        }
165
    }
166
167
    /**
168
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be ArrayList?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
169
     */
170
    protected function makeShareIcons($bookmarks)
171
    {
172
        $icons = [];
173
        if ($bookmarks) {
174
            $useFontAwesome = Config::inst()->get(ShareThisSTE::class, "use_font_awesome");
175
            Requirements::themedCSS('SocialNetworking', "sharethis"); // ALSO  added in template
176
177
            if ($useFontAwesome) {
178
                Requirements::css("//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css");
179
            }
180
181
            Requirements::javascript('silverstripe/admin: thirdparty/jquery/jquery.min.js');
182
            Requirements::javascript('sunnysideup/sharethis: javascript/shareThis.js');
183
184
            if (Config::inst()->get(ShareThisSTE::class, "use_bw_effect")) {
185
                Requirements::customScript('sharethis.set_use_BW(true);', 'ShareThisBWEffect');
186
            }
187
188
            foreach ($bookmarks as $key => $bookmark) {
189
                if (isset($bookmark['title']) && isset($bookmark['url'])) {
190
                    $icon = array(
191
                        'Title' => Convert::raw2att($bookmark['title']),
192
                        'URL' => $bookmark['url'],
193
                        'Key' => $key,
194
                        'ImageSource' => "sharethis/images/icons/$key.png",
195
                        'FAIcon' => $bookmark["faicon"],
196
                        'UseStandardImage' => true
197
                    );
198
199
                    if (isset($bookmark['click'])) {
200
                        $icon['OnClick'] = $bookmark['click'];
201
                    }
202
203 View Code Duplication
                    if ($useFontAwesome) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
204
                        $icon['ImageSource'] = null;
205
                        $icon['UseStandardImage'] = false;
206
                        $icon['FAIcon'] = $bookmark["faicon"];
207
                    }
208
209 View Code Duplication
                    if (isset($bookmark['icon'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
210
                        $icon['ImageSource'] = $bookmark['icon'];
211
                        $icon['UseStandardImage'] = false;
212
                        $icon['FAIcon'] = null;
213
                    }
214
215
                    $icons[] = new ArrayData($icon);
216
                } else {
217
                    Debug::show("Title of url not defined for $key");
218
                }
219
            }
220
        }
221
222
        return new ArrayList($icons);
223
    }
224
225
    /**
226
     * Creating the bookmarks
227
     */
228
    protected function makeBookmarks($field)
229
    {
230
        $finalBookmarks = [];
231
232
        $bookmarks = ShareThisOptions::get_page_specific_data($this->owner->Title, $this->owner->Link(), $this->owner->MetaDescription);
233
234
        $objects = ShareThisDataObject::get()
235
            ->filter($field, 1)
236
            ->sort(array('Sort' => 'ASC', 'Title' => 'ASC'));
237
        if ($objects->count()) {
238
            foreach ($objects as $obj) {
239
                if (isset($bookmarks[$obj->Title])) {
240
                    $finalBookmarks[$obj->Title] = $bookmarks[$obj->Title];
241
242
                    if ($obj->AlternativeIconID && $obj->AlternativeIcon()->exists()) {
243
                        $finalBookmarks[$obj->Title]['icon'] = $obj->AlternativeIcon()->Link();
244
                    }
245
                }
246
            }
247
        } else {
248
            $finalBookmarks = $bookmarks;
249
        }
250
251
        return $finalBookmarks;
252
    }
253
254
    /**
255
     * @return boolean
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
256
     */
257
    private function applyToOwnerClass()
258
    {
259
        $always = Config::inst()->get(ShareThisSTE::class, "always_include_in");
260
        $never = Config::inst()->get(ShareThisSTE::class, "never_include_in");
261
        if (count($always) == 0 && count($never) == 0) {
262
            return true;
263 View Code Duplication
        } elseif (count($never) && count($always) == 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
264
            if (in_array($this->owner->ClassName, $never)) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return !in_array($this->...er->ClassName, $never);.
Loading history...
265
                return false;
266
            }
267
268
            return true;
269
        } elseif (count($always) && count($never) == 0) {
270
            if (in_array($this->owner->ClassName, $always)) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return in_array($this->o...r->ClassName, $always);.
Loading history...
271
                return true;
272
            }
273
274
            return false;
275 View Code Duplication
        } elseif (count($never) && count($always)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
276
            if (in_array($this->owner->ClassName, $never)) {
277
                return false;
278
            }
279
280
            if (in_array($this->owner->ClassName, $always)) {
0 ignored issues
show
Unused Code introduced by
This if statement and the following return statement are superfluous as you return always true.
Loading history...
281
                return true;
282
            }
283
284
            //exception... if dev sets both always and never
285
            //then the ones not set will be included by default.
286
            return true;
287
        } else {
288
            user_error("Strange condition!", E_USER_NOTICE);
289
        }
290
    }
291
}
292