PluginProbe
Cookie Consent – GDPR & CCPA Cookie Banner & Consent Manager / trunk
Cookie Consent – GDPR & CCPA Cookie Banner & Consent Manager vtrunk
0.0.11 0.0.10 0.0.9 0.0.8 0.0.7 0.0.6 trunk 0.0.1 0.0.2 0.0.3 0.0.4 0.0.5
cookiez / classes / services / client.php

client.php in Cookie Consent – GDPR & CCPA Cookie Banner & Consent Manager trunk, at classes/services/client.php

279 lines 6.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Cookiez\Classes\Services;
4
5 use Cookiez\Modules\Connect\Module as Connect;
6 use ElementorOne\Connect\Exceptions\Service_Exception;
7 use WP_Error;
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit; // Exit if accessed directly.
11 }
12
13 /**
14 * Class Client
15 */
16 class Client {
17 private const BASE_URL = 'https://my.elementor.com/apps/api/v1/cookiez-consent/';
18
19 private const BASE_URL_FEEDBACK = 'https://feedback-api.prod.apps.elementor.red/apps/api/v1/';
20
21 private bool $refreshed = false;
22
23 public static ?Client $instance = null;
24
25 /**
26 * set_instance
27 * used for testing
28 * @param $instance
29 */
30 public static function set_instance( $instance ) {
31 self::$instance = $instance;
32 }
33
34 /**
35 * get_instance
36 * @return Client|null
37 */
38 public static function get_instance(): ?Client {
39 if ( ! self::$instance ) {
40 self::$instance = new self();
41 }
42 return self::$instance;
43 }
44
45 /**
46 * get_site_info function
47 *
48 * @return array
49 */
50 public static function get_site_info(): array {
51 return [
52 // Which API version is used.
53 'app_version' => COOKIEZ_VERSION,
54 // Which language to return.
55 'site_lang' => get_bloginfo( 'language' ),
56 // site to connect
57 'site_url' => trailingslashit( home_url() ),
58 // Alt site url
59 'alt_site_url' => trailingslashit( site_url() ),
60 // current user
61 'local_id' => get_current_user_id(),
62 // User Agent
63 'user_agent' => ! empty( $_SERVER['HTTP_USER_AGENT'] )
64 ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) )
65 : 'Unknown',
66 'webhook_url' => self::webhook_endpoint(),
67 ];
68 }
69
70 /**
71 * Scan webhook endpoint
72 * @return string
73 */
74 private static function webhook_endpoint(): string {
75 $blog_id = get_current_blog_id();
76 $url = get_rest_url( $blog_id, 'cookiez/v1/scan/webhook' );
77
78 return add_query_arg( 'token', Webhook_Token::get(), $url );
79 }
80
81 /**
82 * make_request function
83 *
84 * @param $method - http method allowed: POST, GET, PUT, DELETE, PATCH, HEAD, OPTIONS
85 * @param $endpoint - endpoint url
86 * @param array $body - body data
87 * @param array $headers - headers data
88 * @param boolean $send_json - send json data
89 * @return mixed|WP_Error
90 */
91 public function make_request( $method, $endpoint, $body = [], array $headers = [], $send_json = false ) {
92 $headers = array_replace_recursive( [
93 'x-elementor-cookiez' => COOKIEZ_VERSION,
94 'x-elementor-apps' => 'cookiez',
95 ], $headers );
96
97 $headers = array_replace_recursive(
98 $headers,
99 $this->is_connected() ? $this->generate_authentication_headers( $endpoint ) : []
100 );
101
102 $body = array_replace_recursive( $body, $this->get_site_info() );
103
104 if ( $send_json ) {
105 $headers['Content-Type'] = 'application/json; charset=utf-8';
106 $body = wp_json_encode( $body );
107 }
108
109 return $this->request(
110 $method,
111 $endpoint,
112 [
113 'timeout' => 100,
114 'headers' => $headers,
115 'body' => $body,
116 ]
117 );
118 }
119
120 /**
121 * get_client_base_url function
122 *
123 * @return string
124 */
125 public static function get_client_base_url() {
126 return apply_filters( 'cookiez_client_base_url', self::BASE_URL );
127 }
128
129 /**
130 * get_feedback_base_url function
131 *
132 * @return void
133 */
134 public static function get_feedback_base_url() {
135 return apply_filters( 'cookiez_feedback_base_url', self::BASE_URL_FEEDBACK );
136 }
137
138 /**
139 * get_remote_url function
140 *
141 * @param [type] $endpoint
142 * @return string
143 */
144 private static function get_remote_url( $endpoint ): string {
145 if ( strpos( $endpoint, 'feedback/' ) !== false ) {
146 return self::get_feedback_base_url() . $endpoint;
147 }
148 return self::get_client_base_url() . $endpoint;
149 }
150
151 /**
152 * is_connected function
153 *
154 * @return boolean
155 */
156 protected function is_connected(): bool {
157 return Connect::is_connected();
158 }
159
160 /**
161 * add_bearer_token function
162 *
163 * @param array $headers - headers data
164 * @return array
165 */
166 public function add_bearer_token( $headers ) {
167 if ( $this->is_connected() ) {
168 $headers['Authorization'] = 'Bearer ' . Connect::get_connect()->data()->get_access_token();
169 }
170 return $headers;
171 }
172
173 /**
174 * generate_authentication_headers
175 *
176 * @param [type] $endpoint
177 * @return array
178 */
179 protected function generate_authentication_headers( $endpoint ): array {
180 $headers = [
181 'endpoint' => $endpoint,
182 ];
183
184 return $this->add_bearer_token( $headers );
185 }
186
187 /**
188 * @throws Service_Exception
189 */
190 protected function request( $method, $endpoint, $args = [] ) {
191 $args['method'] = $method;
192
193 $response = wp_remote_request(
194 self::get_remote_url( $endpoint ),
195 $args
196 );
197
198 if ( is_wp_error( $response ) ) {
199 $message = $response->get_error_message();
200
201 return new WP_Error(
202 $response->get_error_code(),
203 is_array( $message ) ? join( ', ', $message ) : $message
204 );
205 }
206
207 $body = wp_remote_retrieve_body( $response );
208 $response_code = (int) wp_remote_retrieve_response_code( $response );
209
210 if ( ! $response_code ) {
211 return new WP_Error( 500, 'No Response' );
212 }
213
214 // Server sent a success message without content.
215 if ( 'null' === $body ) {
216 $body = true;
217 }
218
219 // Return with no content on successful deletion of domain from service.
220 if ( 204 === $response_code ) {
221 return true;
222 }
223
224 if ( strpos( $endpoint, 'consent-logs/export' ) !== false ) {
225 if ( ! in_array( $response_code, [ 200, 201 ], true ) ) {
226 return new WP_Error( $response_code, wp_remote_retrieve_response_message( $response ) );
227 }
228 return $body;
229 }
230
231 $body = json_decode( $body );
232
233 if ( false === $body ) {
234 return new WP_Error( 422, 'Wrong Server Response' );
235 }
236
237 // If the token is invalid, refresh it and try again once only.
238 if ( ! $this->refreshed && ! empty( $body->message ) && ( false !== strpos( $body->message, 'Invalid Token' ) ) ) {
239 Connect::get_connect()->service()->renew_access_token();
240 $this->refreshed = true;
241 $args['headers'] = $this->add_bearer_token( $args['headers'] );
242 return $this->request( $method, $endpoint, $args );
243 }
244
245 // If there is mismatch then trigger the mismatch flow explicitly.
246 if ( ! $this->refreshed && ! empty( $body->message ) && ( false !== strpos( $body->message, 'site url mismatch' ) ) ) {
247 Connect::get_connect()->data()->set_home_url( 'https://wrongurl' );
248 return new WP_Error( 401, 'site url mismatch' );
249 }
250
251 if ( ! in_array( $response_code, [ 200, 201 ], true ) ) {
252 // In case $as_array = true.
253 $message = $body->message ?? wp_remote_retrieve_response_message( $response );
254 $message = is_array( $message ) ? join( ', ', $message ) : $message;
255 $code = isset( $body->code ) ? (int) $body->code : $response_code;
256
257 return new WP_Error( $code, $message );
258 }
259
260 return $body;
261 }
262
263 /**
264 * get_site_data
265 * @return mixed|WP_Error Site data
266 */
267 public static function get_site_data() {
268 return self::get_instance()->make_request( 'POST', 'stats' );
269 }
270
271 /**
272 * register_website
273 * @return mixed|WP_Error Site data
274 */
275 public static function register_website() {
276 return self::get_instance()->make_request( 'POST', 'site' );
277 }
278 }
279