Completed
Push — master ( 68208f...51a787 )
by Florian
12:17
created
code/SecionIO.php 2 patches
Indentation   +262 added lines, -262 removed lines patch added patch discarded remove patch
@@ -2,266 +2,266 @@
 block discarded – undo
2 2
 
3 3
 class SectionIO extends Object implements Flushable
4 4
 {
5
-    private static $flush_on_dev_build = true;
6
-
7
-    private static $sitetree_flush_strategy = 'single';
8
-
9
-    private static $api_url = 'https://aperture.section.io/api/v1';
10
-    private static $account_id = '';
11
-    private static $application_id = '';
12
-    private static $environment_name = '';
13
-    private static $proxy_name = '';
14
-    private static $username = '';
15
-    private static $password = '';
16
-
17
-    /**
18
-     * Implementation of Flushable::flush()
19
-     * Is triggered on dev/build and ?flush=1.
20
-     */
21
-    public static function flush()
22
-    {
23
-        if (Config::inst()->get('SectionIO', 'flush_on_dev_build')) {
24
-            return static::flushAll();
25
-        }
26
-
27
-        return;
28
-    }
29
-
30
-    public static function flushAll()
31
-    {
32
-        $exp = 'obj.http.x-url ~ /';
33
-
34
-        return static::performFlush($exp);
35
-    }
36
-
37
-    public static function flushImage($imageID)
38
-    {
39
-        $image = Image::get()->byID($imageID);
40
-        if ($image && $image->exists()) {
41
-            $exp = 'obj.http.x-url ~ "^/'.preg_quote($image->getFilename()).'$"'; // image itself
42
-            $exp    .= ' || obj.http.x-url ~ "^/'.preg_quote($image->Parent()->getFilename())
43
-                    .'_resampled/(.*)\-'.preg_quote($image->Name).'$"'; // resampled versions
44
-            return static::performFlush($exp);
45
-        }
46
-
47
-        return false;
48
-    }
49
-
50
-    public static function flushFile($fileID)
51
-    {
52
-        $file = File::get()->byID($fileID);
53
-        if ($file && $file->exists()) {
54
-            $exp = 'obj.http.x-url ~ "^/'.preg_quote($file->getFilename()).'$"';
55
-
56
-            return static::performFlush($exp);
57
-        }
58
-
59
-        return false;
60
-    }
61
-
62
-    public static function flushSiteTree($sitetreeID)
63
-    {
64
-        $sitetree = SiteTree::get()->byID($sitetreeID);
65
-        if ($sitetree && $sitetree->exists()) {
66
-            $strategy = Config::inst()->get('SectionIO', 'sitetree_flush_strategy');
67
-            switch ($strategy) {
68
-
69
-                case 'single':
70
-                    $exp = 'obj.http.content-type ~ "'.preg_quote('text/html').'"';
71
-                    $exp .= ' && obj.http.x-url ~ "^'.preg_quote($sitetree->Link()).'$"';
72
-                    break;
73
-
74
-                case 'parents':
75
-                    $exp = 'obj.http.content-type ~ "'.preg_quote('text/html').'"';
76
-                    $exp .= ' && (obj.http.x-url ~ "^'.preg_quote($sitetree->Link()).'$"';
77
-                    $parent = $sitetree->getParent();
78
-                    while ($parent && $parent->exists()) {
79
-                        $exp .= ' || obj.http.x-url ~ "^'.preg_quote($parent->Link()).'$"';
80
-                        $parent = $parent->getParent();
81
-                    }
82
-                    $exp .= ')';
83
-                    break;
84
-
85
-                case 'all':
86
-                    $exp = 'obj.http.content-type ~ "'.preg_quote('text/html').'"';
87
-                    break;
88
-
89
-                case 'everyting':
90
-                default:
91
-                    $exp = 'obj.http.x-url ~ /';
92
-                    break;
93
-
94
-            }
95
-
96
-            return static::performFlush($exp);
97
-        }
98
-
99
-        return false;
100
-    }
101
-
102
-    protected static function performFlush($banExpression)
103
-    {
104
-        $success = true;
105
-        $urls = static::getUrls();
106
-        // config loaded successfully
107
-        if ($urls) {
108
-            foreach ($urls as $url) {
109
-
110
-                // get restful service object
111
-                $service = static::getService($url, $banExpression);
112
-
113
-                // prepare headers
114
-                $headers = static::getHeaders();
115
-
116
-                // prepare curl options
117
-                $options = static::getOptions();
118
-
119
-                // call API
120
-                $conn = $service->request(null, 'POST', null, $headers, $options);
121
-
122
-                if ($conn->isError()) {
123
-                    SS_Log::log('SectionIO::performFlush :: '.$conn->getStatusCode().' : '.$conn->getStatusDescription().' : '.$url, SS_Log::ERR);
124
-                    $success = $success && false;
125
-                } else {
126
-                    SS_Log::log('SectionIO::performFlush :: ban successful. url: '.$url."; ban expression: '".$banExpression."'", SS_Log::ERR);
127
-                }
128
-            }
129
-        } else {
130
-            SS_Log::log('SectionIO::performFlush :: no URLs loaded for ban.', SS_Log::ERR);
131
-        }
132
-
133
-        return $success;
134
-    }
135
-
136
-    protected static function getService($url, $banExpression)
137
-    {
138
-        // prepare API call
139
-        $service = new RestfulService(
140
-            $url,
141
-            0 // expiry time 0: do not cache the API call
142
-        );
143
-        // set basic auth
144
-        $username = Config::inst()->get('SectionIO', 'username');
145
-        $password = Config::inst()->get('SectionIO', 'password');
146
-        $service->basicAuth($username, $password);
147
-        // set query string (ban expression)
148
-        $service->setQueryString(array(
149
-            'banExpression' => $banExpression,
150
-        ));
151
-
152
-        return $service;
153
-    }
154
-
155
-    protected static function getOptions()
156
-    {
157
-        // prepare curl options for ssl verification
158
-        $cert = static::getCertificates();
159
-        $options = array(
160
-            CURLOPT_SSL_VERIFYPEER => 1,
161
-            CURLOPT_SSL_VERIFYHOST => 2,
162
-            CURLOPT_CAINFO => $cert,
163
-        );
164
-
165
-        return $options;
166
-    }
167
-
168
-    protected static function getCertificates()
169
-    {
170
-        $cert = ini_get('curl.cainfo');
171
-        if (!$cert) {
172
-            $cert = BASE_PATH.'/'.SECTIONIO_BASE.'/cert/cacert.pem';
173
-        }
174
-
175
-        return $cert;
176
-    }
177
-
178
-    protected static function getHeaders()
179
-    {
180
-        $headers = array(
181
-            'Content-Type: application/json',
182
-            'Accept: application/json',
183
-        );
184
-
185
-        return $headers;
186
-    }
187
-
188
-    protected static function getUrls()
189
-    {
190
-        $urls = array();
191
-
192
-        if (static::checkConfig()) {
193
-            $api_url = Config::inst()->get('SectionIO', 'api_url');
194
-            $account_id = Config::inst()->get('SectionIO', 'account_id');
195
-            $application_id = Config::inst()->get('SectionIO', 'application_id');
196
-            $application_ids = array();
197
-            if (is_string($application_id)) {
198
-                $application_ids = preg_split("/[\s,]+/", $application_id);
199
-            } elseif (is_array($application_id)) {
200
-                $application_ids = $application_id;
201
-            }
202
-            $environment_name = Config::inst()->get('SectionIO', 'environment_name');
203
-            $proxy_name = Config::inst()->get('SectionIO', 'proxy_name');
204
-
205
-            foreach ($application_ids as $appid) {
206
-                // build API URL: /account/{accountId}/application/{applicationId}/environment/{environmentName}/proxy/{proxyName}/state
207
-                $urls[] = Controller::join_links(
208
-                    $api_url,
209
-                    'account',
210
-                    $account_id,
211
-                    'application',
212
-                    $appid,
213
-                    'environment',
214
-                    $environment_name,
215
-                    'proxy',
216
-                    $proxy_name,
217
-                    'state'
218
-                );
219
-            }
220
-        }
221
-
222
-        return $urls;
223
-    }
224
-
225
-    protected static function checkConfig()
226
-    {
227
-        $success = true;
228
-        // check config
229
-        $api_url = Config::inst()->get('SectionIO', 'api_url');
230
-        if (!isset($api_url) || strlen($api_url) < 1) {
231
-            SS_Log::log('Value for SectionIO.api_url needs to be configured.', SS_Log::WARN);
232
-            $success = false;
233
-        }
234
-        $account_id = Config::inst()->get('SectionIO', 'account_id');
235
-        if (!isset($account_id) || strlen($account_id) < 1) {
236
-            SS_Log::log('Value for SectionIO.account_id needs to be configured.', SS_Log::WARN);
237
-            $success = false;
238
-        }
239
-        $application_id = Config::inst()->get('SectionIO', 'application_id');
240
-        if (!isset($application_id) || (!is_array($application_id) && strlen((string) $application_id) < 1)) {
241
-            SS_Log::log('Value for SectionIO.application_id needs to be configured.', SS_Log::WARN);
242
-            $success = false;
243
-        }
244
-        $environment_name = Config::inst()->get('SectionIO', 'environment_name');
245
-        if (!isset($environment_name) || strlen($environment_name) < 1) {
246
-            SS_Log::log('Value for SectionIO.environment_name needs to be configured.', SS_Log::WARN);
247
-            $success = false;
248
-        }
249
-        $proxy_name = Config::inst()->get('SectionIO', 'proxy_name');
250
-        if (!isset($proxy_name) || strlen($proxy_name) < 1) {
251
-            SS_Log::log('Value for SectionIO.proxy_name needs to be configured.', SS_Log::WARN);
252
-            $success = false;
253
-        }
254
-        $username = Config::inst()->get('SectionIO', 'username');
255
-        if (!isset($username) || strlen($username) < 1) {
256
-            SS_Log::log('Value for SectionIO.username needs to be configured.', SS_Log::WARN);
257
-            $success = false;
258
-        }
259
-        $password = Config::inst()->get('SectionIO', 'password');
260
-        if (!isset($password) || strlen($password) < 1) {
261
-            SS_Log::log('Value for SectionIO.password needs to be configured.', SS_Log::WARN);
262
-            $success = false;
263
-        }
264
-
265
-        return $success;
266
-    }
5
+	private static $flush_on_dev_build = true;
6
+
7
+	private static $sitetree_flush_strategy = 'single';
8
+
9
+	private static $api_url = 'https://aperture.section.io/api/v1';
10
+	private static $account_id = '';
11
+	private static $application_id = '';
12
+	private static $environment_name = '';
13
+	private static $proxy_name = '';
14
+	private static $username = '';
15
+	private static $password = '';
16
+
17
+	/**
18
+	 * Implementation of Flushable::flush()
19
+	 * Is triggered on dev/build and ?flush=1.
20
+	 */
21
+	public static function flush()
22
+	{
23
+		if (Config::inst()->get('SectionIO', 'flush_on_dev_build')) {
24
+			return static::flushAll();
25
+		}
26
+
27
+		return;
28
+	}
29
+
30
+	public static function flushAll()
31
+	{
32
+		$exp = 'obj.http.x-url ~ /';
33
+
34
+		return static::performFlush($exp);
35
+	}
36
+
37
+	public static function flushImage($imageID)
38
+	{
39
+		$image = Image::get()->byID($imageID);
40
+		if ($image && $image->exists()) {
41
+			$exp = 'obj.http.x-url ~ "^/'.preg_quote($image->getFilename()).'$"'; // image itself
42
+			$exp    .= ' || obj.http.x-url ~ "^/'.preg_quote($image->Parent()->getFilename())
43
+					.'_resampled/(.*)\-'.preg_quote($image->Name).'$"'; // resampled versions
44
+			return static::performFlush($exp);
45
+		}
46
+
47
+		return false;
48
+	}
49
+
50
+	public static function flushFile($fileID)
51
+	{
52
+		$file = File::get()->byID($fileID);
53
+		if ($file && $file->exists()) {
54
+			$exp = 'obj.http.x-url ~ "^/'.preg_quote($file->getFilename()).'$"';
55
+
56
+			return static::performFlush($exp);
57
+		}
58
+
59
+		return false;
60
+	}
61
+
62
+	public static function flushSiteTree($sitetreeID)
63
+	{
64
+		$sitetree = SiteTree::get()->byID($sitetreeID);
65
+		if ($sitetree && $sitetree->exists()) {
66
+			$strategy = Config::inst()->get('SectionIO', 'sitetree_flush_strategy');
67
+			switch ($strategy) {
68
+
69
+				case 'single':
70
+					$exp = 'obj.http.content-type ~ "'.preg_quote('text/html').'"';
71
+					$exp .= ' && obj.http.x-url ~ "^'.preg_quote($sitetree->Link()).'$"';
72
+					break;
73
+
74
+				case 'parents':
75
+					$exp = 'obj.http.content-type ~ "'.preg_quote('text/html').'"';
76
+					$exp .= ' && (obj.http.x-url ~ "^'.preg_quote($sitetree->Link()).'$"';
77
+					$parent = $sitetree->getParent();
78
+					while ($parent && $parent->exists()) {
79
+						$exp .= ' || obj.http.x-url ~ "^'.preg_quote($parent->Link()).'$"';
80
+						$parent = $parent->getParent();
81
+					}
82
+					$exp .= ')';
83
+					break;
84
+
85
+				case 'all':
86
+					$exp = 'obj.http.content-type ~ "'.preg_quote('text/html').'"';
87
+					break;
88
+
89
+				case 'everyting':
90
+				default:
91
+					$exp = 'obj.http.x-url ~ /';
92
+					break;
93
+
94
+			}
95
+
96
+			return static::performFlush($exp);
97
+		}
98
+
99
+		return false;
100
+	}
101
+
102
+	protected static function performFlush($banExpression)
103
+	{
104
+		$success = true;
105
+		$urls = static::getUrls();
106
+		// config loaded successfully
107
+		if ($urls) {
108
+			foreach ($urls as $url) {
109
+
110
+				// get restful service object
111
+				$service = static::getService($url, $banExpression);
112
+
113
+				// prepare headers
114
+				$headers = static::getHeaders();
115
+
116
+				// prepare curl options
117
+				$options = static::getOptions();
118
+
119
+				// call API
120
+				$conn = $service->request(null, 'POST', null, $headers, $options);
121
+
122
+				if ($conn->isError()) {
123
+					SS_Log::log('SectionIO::performFlush :: '.$conn->getStatusCode().' : '.$conn->getStatusDescription().' : '.$url, SS_Log::ERR);
124
+					$success = $success && false;
125
+				} else {
126
+					SS_Log::log('SectionIO::performFlush :: ban successful. url: '.$url."; ban expression: '".$banExpression."'", SS_Log::ERR);
127
+				}
128
+			}
129
+		} else {
130
+			SS_Log::log('SectionIO::performFlush :: no URLs loaded for ban.', SS_Log::ERR);
131
+		}
132
+
133
+		return $success;
134
+	}
135
+
136
+	protected static function getService($url, $banExpression)
137
+	{
138
+		// prepare API call
139
+		$service = new RestfulService(
140
+			$url,
141
+			0 // expiry time 0: do not cache the API call
142
+		);
143
+		// set basic auth
144
+		$username = Config::inst()->get('SectionIO', 'username');
145
+		$password = Config::inst()->get('SectionIO', 'password');
146
+		$service->basicAuth($username, $password);
147
+		// set query string (ban expression)
148
+		$service->setQueryString(array(
149
+			'banExpression' => $banExpression,
150
+		));
151
+
152
+		return $service;
153
+	}
154
+
155
+	protected static function getOptions()
156
+	{
157
+		// prepare curl options for ssl verification
158
+		$cert = static::getCertificates();
159
+		$options = array(
160
+			CURLOPT_SSL_VERIFYPEER => 1,
161
+			CURLOPT_SSL_VERIFYHOST => 2,
162
+			CURLOPT_CAINFO => $cert,
163
+		);
164
+
165
+		return $options;
166
+	}
167
+
168
+	protected static function getCertificates()
169
+	{
170
+		$cert = ini_get('curl.cainfo');
171
+		if (!$cert) {
172
+			$cert = BASE_PATH.'/'.SECTIONIO_BASE.'/cert/cacert.pem';
173
+		}
174
+
175
+		return $cert;
176
+	}
177
+
178
+	protected static function getHeaders()
179
+	{
180
+		$headers = array(
181
+			'Content-Type: application/json',
182
+			'Accept: application/json',
183
+		);
184
+
185
+		return $headers;
186
+	}
187
+
188
+	protected static function getUrls()
189
+	{
190
+		$urls = array();
191
+
192
+		if (static::checkConfig()) {
193
+			$api_url = Config::inst()->get('SectionIO', 'api_url');
194
+			$account_id = Config::inst()->get('SectionIO', 'account_id');
195
+			$application_id = Config::inst()->get('SectionIO', 'application_id');
196
+			$application_ids = array();
197
+			if (is_string($application_id)) {
198
+				$application_ids = preg_split("/[\s,]+/", $application_id);
199
+			} elseif (is_array($application_id)) {
200
+				$application_ids = $application_id;
201
+			}
202
+			$environment_name = Config::inst()->get('SectionIO', 'environment_name');
203
+			$proxy_name = Config::inst()->get('SectionIO', 'proxy_name');
204
+
205
+			foreach ($application_ids as $appid) {
206
+				// build API URL: /account/{accountId}/application/{applicationId}/environment/{environmentName}/proxy/{proxyName}/state
207
+				$urls[] = Controller::join_links(
208
+					$api_url,
209
+					'account',
210
+					$account_id,
211
+					'application',
212
+					$appid,
213
+					'environment',
214
+					$environment_name,
215
+					'proxy',
216
+					$proxy_name,
217
+					'state'
218
+				);
219
+			}
220
+		}
221
+
222
+		return $urls;
223
+	}
224
+
225
+	protected static function checkConfig()
226
+	{
227
+		$success = true;
228
+		// check config
229
+		$api_url = Config::inst()->get('SectionIO', 'api_url');
230
+		if (!isset($api_url) || strlen($api_url) < 1) {
231
+			SS_Log::log('Value for SectionIO.api_url needs to be configured.', SS_Log::WARN);
232
+			$success = false;
233
+		}
234
+		$account_id = Config::inst()->get('SectionIO', 'account_id');
235
+		if (!isset($account_id) || strlen($account_id) < 1) {
236
+			SS_Log::log('Value for SectionIO.account_id needs to be configured.', SS_Log::WARN);
237
+			$success = false;
238
+		}
239
+		$application_id = Config::inst()->get('SectionIO', 'application_id');
240
+		if (!isset($application_id) || (!is_array($application_id) && strlen((string) $application_id) < 1)) {
241
+			SS_Log::log('Value for SectionIO.application_id needs to be configured.', SS_Log::WARN);
242
+			$success = false;
243
+		}
244
+		$environment_name = Config::inst()->get('SectionIO', 'environment_name');
245
+		if (!isset($environment_name) || strlen($environment_name) < 1) {
246
+			SS_Log::log('Value for SectionIO.environment_name needs to be configured.', SS_Log::WARN);
247
+			$success = false;
248
+		}
249
+		$proxy_name = Config::inst()->get('SectionIO', 'proxy_name');
250
+		if (!isset($proxy_name) || strlen($proxy_name) < 1) {
251
+			SS_Log::log('Value for SectionIO.proxy_name needs to be configured.', SS_Log::WARN);
252
+			$success = false;
253
+		}
254
+		$username = Config::inst()->get('SectionIO', 'username');
255
+		if (!isset($username) || strlen($username) < 1) {
256
+			SS_Log::log('Value for SectionIO.username needs to be configured.', SS_Log::WARN);
257
+			$success = false;
258
+		}
259
+		$password = Config::inst()->get('SectionIO', 'password');
260
+		if (!isset($password) || strlen($password) < 1) {
261
+			SS_Log::log('Value for SectionIO.password needs to be configured.', SS_Log::WARN);
262
+			$success = false;
263
+		}
264
+
265
+		return $success;
266
+	}
267 267
 }
Please login to merge, or discard this patch.
Spacing   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -38,9 +38,9 @@  discard block
 block discarded – undo
38 38
     {
39 39
         $image = Image::get()->byID($imageID);
40 40
         if ($image && $image->exists()) {
41
-            $exp = 'obj.http.x-url ~ "^/'.preg_quote($image->getFilename()).'$"'; // image itself
42
-            $exp    .= ' || obj.http.x-url ~ "^/'.preg_quote($image->Parent()->getFilename())
43
-                    .'_resampled/(.*)\-'.preg_quote($image->Name).'$"'; // resampled versions
41
+            $exp = 'obj.http.x-url ~ "^/' . preg_quote($image->getFilename()) . '$"'; // image itself
42
+            $exp .= ' || obj.http.x-url ~ "^/' . preg_quote($image->Parent()->getFilename())
43
+                    .'_resampled/(.*)\-' . preg_quote($image->Name) . '$"'; // resampled versions
44 44
             return static::performFlush($exp);
45 45
         }
46 46
 
@@ -51,7 +51,7 @@  discard block
 block discarded – undo
51 51
     {
52 52
         $file = File::get()->byID($fileID);
53 53
         if ($file && $file->exists()) {
54
-            $exp = 'obj.http.x-url ~ "^/'.preg_quote($file->getFilename()).'$"';
54
+            $exp = 'obj.http.x-url ~ "^/' . preg_quote($file->getFilename()) . '$"';
55 55
 
56 56
             return static::performFlush($exp);
57 57
         }
@@ -67,23 +67,23 @@  discard block
 block discarded – undo
67 67
             switch ($strategy) {
68 68
 
69 69
                 case 'single':
70
-                    $exp = 'obj.http.content-type ~ "'.preg_quote('text/html').'"';
71
-                    $exp .= ' && obj.http.x-url ~ "^'.preg_quote($sitetree->Link()).'$"';
70
+                    $exp = 'obj.http.content-type ~ "' . preg_quote('text/html') . '"';
71
+                    $exp .= ' && obj.http.x-url ~ "^' . preg_quote($sitetree->Link()) . '$"';
72 72
                     break;
73 73
 
74 74
                 case 'parents':
75
-                    $exp = 'obj.http.content-type ~ "'.preg_quote('text/html').'"';
76
-                    $exp .= ' && (obj.http.x-url ~ "^'.preg_quote($sitetree->Link()).'$"';
75
+                    $exp = 'obj.http.content-type ~ "' . preg_quote('text/html') . '"';
76
+                    $exp .= ' && (obj.http.x-url ~ "^' . preg_quote($sitetree->Link()) . '$"';
77 77
                     $parent = $sitetree->getParent();
78 78
                     while ($parent && $parent->exists()) {
79
-                        $exp .= ' || obj.http.x-url ~ "^'.preg_quote($parent->Link()).'$"';
79
+                        $exp .= ' || obj.http.x-url ~ "^' . preg_quote($parent->Link()) . '$"';
80 80
                         $parent = $parent->getParent();
81 81
                     }
82 82
                     $exp .= ')';
83 83
                     break;
84 84
 
85 85
                 case 'all':
86
-                    $exp = 'obj.http.content-type ~ "'.preg_quote('text/html').'"';
86
+                    $exp = 'obj.http.content-type ~ "' . preg_quote('text/html') . '"';
87 87
                     break;
88 88
 
89 89
                 case 'everyting':
@@ -120,10 +120,10 @@  discard block
 block discarded – undo
120 120
                 $conn = $service->request(null, 'POST', null, $headers, $options);
121 121
 
122 122
                 if ($conn->isError()) {
123
-                    SS_Log::log('SectionIO::performFlush :: '.$conn->getStatusCode().' : '.$conn->getStatusDescription().' : '.$url, SS_Log::ERR);
123
+                    SS_Log::log('SectionIO::performFlush :: ' . $conn->getStatusCode() . ' : ' . $conn->getStatusDescription() . ' : ' . $url, SS_Log::ERR);
124 124
                     $success = $success && false;
125 125
                 } else {
126
-                    SS_Log::log('SectionIO::performFlush :: ban successful. url: '.$url."; ban expression: '".$banExpression."'", SS_Log::ERR);
126
+                    SS_Log::log('SectionIO::performFlush :: ban successful. url: ' . $url . "; ban expression: '" . $banExpression . "'", SS_Log::ERR);
127 127
                 }
128 128
             }
129 129
         } else {
@@ -169,7 +169,7 @@  discard block
 block discarded – undo
169 169
     {
170 170
         $cert = ini_get('curl.cainfo');
171 171
         if (!$cert) {
172
-            $cert = BASE_PATH.'/'.SECTIONIO_BASE.'/cert/cacert.pem';
172
+            $cert = BASE_PATH . '/' . SECTIONIO_BASE . '/cert/cacert.pem';
173 173
         }
174 174
 
175 175
         return $cert;
Please login to merge, or discard this patch.