Completed
Push — master ( 9378c1...c4fd91 )
by Florian
04:50
created

SectionIO   B

Complexity

Total Complexity 54

Size/Duplication

Total Lines 273
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 12

Test Coverage

Coverage 72.62%

Importance

Changes 0
Metric Value
wmc 54
lcom 1
cbo 12
dl 0
loc 273
ccs 122
cts 168
cp 0.7262
rs 7.0642
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A flush() 0 8 2
A flushAll() 0 6 1
A flushImage() 0 12 3
A flushFile() 0 10 3
D flushSiteTree() 0 39 9
A flushURL() 0 7 2
B performFlush() 0 35 6
A getService() 0 18 1
A getOptions() 0 12 1
A getCertificates() 0 9 2
A getHeaders() 0 9 1
B getUrls() 0 36 5
F checkConfig() 0 41 18

How to fix   Complexity   

Complex Class

Complex classes like SectionIO 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 SectionIO, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
class SectionIO extends Object implements Flushable
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
4
{
5
    private static $flush_on_dev_build = true;
0 ignored issues
show
Unused Code introduced by
The property $flush_on_dev_build 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...
6
7
    private static $sitetree_flush_strategy = 'single';
0 ignored issues
show
Unused Code introduced by
The property $sitetree_flush_strategy 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...
8
9
    private static $api_url = 'https://aperture.section.io/api/v1';
0 ignored issues
show
Unused Code introduced by
The property $api_url 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...
10
    private static $account_id = '';
0 ignored issues
show
Unused Code introduced by
The property $account_id 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...
11
    private static $application_id = '';
0 ignored issues
show
Unused Code introduced by
The property $application_id 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...
12
    private static $environment_name = '';
0 ignored issues
show
Unused Code introduced by
The property $environment_name 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...
13
    private static $proxy_name = '';
0 ignored issues
show
Unused Code introduced by
The property $proxy_name 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...
14
    private static $username = '';
0 ignored issues
show
Unused Code introduced by
The property $username 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...
15
    private static $password = '';
0 ignored issues
show
Unused Code introduced by
The property $password 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...
16
17
    /**
18
     * Implementation of Flushable::flush()
19
     * Is triggered on dev/build and ?flush=1.
20
     */
21 1
    public static function flush()
22
    {
23 1
        if (Config::inst()->get('SectionIO', 'flush_on_dev_build')) {
24 1
            return static::flushAll();
25
        }
26
27 1
        return;
28
    }
29
30 3
    public static function flushAll()
31
    {
32 3
        $exp = 'obj.http.x-url ~ /';
33
34 3
        return static::performFlush($exp);
35
    }
36
37 1
    public static function flushImage($imageID)
38
    {
39 1
        $image = Image::get()->byID($imageID);
40 1
        if ($image && $image->exists()) {
41 1
            $exp = 'obj.http.x-url ~ "^/'.preg_quote($image->getFilename()).'$"'; // image itself
42 1
            $exp    .= ' || obj.http.x-url ~ "^/'.preg_quote($image->Parent()->getFilename())
0 ignored issues
show
Bug introduced by
The method Parent() does not exist on DataObject. Did you maybe mean parentClass()?

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...
43 1
                    .'_resampled/(.*)\-'.preg_quote($image->Name).'$"'; // resampled versions
44 1
            return static::performFlush($exp);
45
        }
46
47
        return false;
48
    }
49
50 1
    public static function flushFile($fileID)
51
    {
52 1
        $file = File::get()->byID($fileID);
53 1
        if ($file && $file->exists()) {
54 1
            $exp = 'obj.http.x-url ~ "^/'.preg_quote($file->getFilename()).'$"';
55 1
            return static::performFlush($exp);
56
        }
57
58
        return false;
59
    }
60
61 1
    public static function flushSiteTree($sitetreeID)
62
    {
63 1
        $sitetree = SiteTree::get()->byID($sitetreeID);
64 1
        if ($sitetree && $sitetree->exists()) {
65 1
            $strategy = Config::inst()->get('SectionIO', 'sitetree_flush_strategy');
66
            switch ($strategy) {
67
68 1
                case 'single':
69 1
                    $exp = 'obj.http.content-type ~ "'.preg_quote('text/html').'"';
70 1
                    $exp .= ' && obj.http.x-url ~ "^'.preg_quote($sitetree->Link()).'$"';
71 1
                    break;
72
73 1
                case 'parents':
74 1
                    $exp = 'obj.http.content-type ~ "'.preg_quote('text/html').'"';
75 1
                    $exp .= ' && (obj.http.x-url ~ "^'.preg_quote($sitetree->Link()).'$"';
76 1
                    $parent = $sitetree->getParent();
77 1
                    while ($parent && $parent->exists()) {
78 1
                        $exp .= ' || obj.http.x-url ~ "^'.preg_quote($parent->Link()).'$"';
79 1
                        $parent = $parent->getParent();
80 1
                    }
81 1
                    $exp .= ')';
82 1
                    break;
83
84 1
                case 'all':
85 1
                    $exp = 'obj.http.content-type ~ "'.preg_quote('text/html').'"';
86 1
                    break;
87
88 1
                case 'everyting':
89 1
                default:
90 1
                    $exp = 'obj.http.x-url ~ /';
91 1
                    break;
92
93 1
            }
94
95 1
            return static::performFlush($exp);
96
        }
97
98
        return false;
99
    }
100
    
101 6
    public static function flushURL($url) {
102
        if ($url) {
103 6
            $exp = 'obj.http.x-url ~ "^/'.preg_quote($url).'$"';
104
            return static::performFlush($exp);
105
        }
106
        return false;
107
    }
108
109
    protected static function performFlush($banExpression)
110
    {
111
        $success = true;
112
        $urls = static::getUrls();
113
        // config loaded successfully
114
		if (static::checkConfig()) {
115
			if (count($urls) > 0) {
116
				foreach ($urls as $url) {
117
118
					// get restful service object
119
					$service = static::getService($url, $banExpression);
120
121
					// prepare headers
122
					$headers = static::getHeaders();
123
124
					// prepare curl options
125
					$options = static::getOptions();
126
127
					// call API
128
					$conn = $service->request(null, 'POST', null, $headers, $options);
129
130
					if ($conn->isError()) {
131
						SS_Log::log('SectionIO::performFlush :: '.$conn->getStatusCode().' : '.$conn->getStatusDescription().' : '.$url, SS_Log::ERR);
132
						$success = $success && false;
133
					} else {
134
						SS_Log::log('SectionIO::performFlush :: ban successful. url: '.$url."; ban expression: '".$banExpression."'", SS_Log::NOTICE);
135
					}
136
				}
137
			} else {
138
				SS_Log::log('SectionIO::performFlush :: no URLs loaded for ban.', SS_Log::ERR);
139
			}
140
		}
141
		
142
        return $success;
143
    }
144
145 6
    protected static function getService($url, $banExpression)
146
    {
147
        // prepare API call
148 6
        $service = new RestfulService(
149 6
            $url,
150
            0 // expiry time 0: do not cache the API call
151 6
        );
152
        // set basic auth
153 6
        $username = Config::inst()->get('SectionIO', 'username');
154 6
        $password = Config::inst()->get('SectionIO', 'password');
155 6
        $service->basicAuth($username, $password);
156
        // set query string (ban expression)
157 6
        $service->setQueryString(array(
158 6
            'banExpression' => $banExpression,
159 6
        ));
160
161 6
        return $service;
162
    }
163
164 6
    protected static function getOptions()
165
    {
166
        // prepare curl options for ssl verification
167 6
        $cert = static::getCertificates();
168
        $options = array(
169 6
            CURLOPT_SSL_VERIFYPEER => 1,
170 6
            CURLOPT_SSL_VERIFYHOST => 2,
171 6
            CURLOPT_CAINFO => $cert,
172 6
        );
173
174 6
        return $options;
175
    }
176
177 6
    protected static function getCertificates()
178
    {
179 6
        $cert = ini_get('curl.cainfo');
180 6
        if (!$cert) {
181 6
            $cert = BASE_PATH.'/'.SECTIONIO_BASE.'/cert/cacert.pem';
182 6
        }
183
184 6
        return $cert;
185
    }
186
187 6
    protected static function getHeaders()
188
    {
189
        $headers = array(
190 6
            'Content-Type: application/json',
191 6
            'Accept: application/json',
192 6
        );
193
194 6
        return $headers;
195
    }
196
197 6
    protected static function getUrls()
198
    {
199 6
        $urls = array();
200
201 6
        if (static::checkConfig()) {
202 6
            $api_url = Config::inst()->get('SectionIO', 'api_url');
203 6
            $account_id = Config::inst()->get('SectionIO', 'account_id');
204 6
            $application_id = Config::inst()->get('SectionIO', 'application_id');
205 6
            $application_ids = array();
206 6
            if (is_string($application_id)) {
207 6
                $application_ids = preg_split("/[\s,]+/", $application_id);
208 6
            } elseif (is_array($application_id)) {
209
                $application_ids = $application_id;
210
            }
211 6
            $environment_name = Config::inst()->get('SectionIO', 'environment_name');
212 6
            $proxy_name = Config::inst()->get('SectionIO', 'proxy_name');
213
214 6
            foreach ($application_ids as $appid) {
215
                // build API URL: /account/{accountId}/application/{applicationId}/environment/{environmentName}/proxy/{proxyName}/state
216 6
                $urls[] = Controller::join_links(
217 6
                    $api_url,
218 6
                    'account',
219 6
                    $account_id,
220 6
                    'application',
221 6
                    $appid,
222 6
                    'environment',
223 6
                    $environment_name,
224 6
                    'proxy',
225 6
                    $proxy_name,
226
                    'state'
227 6
                );
228 6
            }
229 6
        }
230
231 6
        return $urls;
232
    }
233
234 6
    protected static function checkConfig()
235
    {
236 6
        $missing = array();
237
        // check config
238 6
        $api_url = Config::inst()->get('SectionIO', 'api_url');
239 6
        if (!isset($api_url) || strlen($api_url) < 1) {
240
            $missing[] = 'SectionIO.api_url';
241
        }
242 6
        $account_id = Config::inst()->get('SectionIO', 'account_id');
243 6
        if (!isset($account_id) || strlen($account_id) < 1) {
244
            $missing[] = 'SectionIO.account_id';
245
        }
246 6
        $application_id = Config::inst()->get('SectionIO', 'application_id');
247 6
        if (!isset($application_id) || (!is_array($application_id) && strlen((string) $application_id) < 1)) {
248
            $missing[] = 'SectionIO.application_id';
249
        }
250 6
        $environment_name = Config::inst()->get('SectionIO', 'environment_name');
251 6
        if (!isset($environment_name) || strlen($environment_name) < 1) {
252
            $missing[] = 'SectionIO.environment_name';
253
        }
254 6
        $proxy_name = Config::inst()->get('SectionIO', 'proxy_name');
255 6
        if (!isset($proxy_name) || strlen($proxy_name) < 1) {
256
            $missing[] = 'SectionIO.proxy_name';
257
        }
258 6
        $username = Config::inst()->get('SectionIO', 'username');
259 6
        if (!isset($username) || strlen($username) < 1) {
260
            $missing[] = 'SectionIO.username';
261
        }
262 6
        $password = Config::inst()->get('SectionIO', 'password');
263 6
        if (!isset($password) || strlen($password) < 1) {
264
            $missing[] = 'SectionIO.password';
265
        }
266
        
267 6
        if (count($missing) > 0) {
268
			if (!Director::isDev()) {
269
				SS_Log::log('SectionIO:: config parameters missing: ' . implode(', ', $missing), SS_Log::WARN);
270
			}
271
            return false;
272
        }
273 6
        return true;
274
    }
275
}
276