PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.2.1
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.2.1
6.2.2 6.2.1 6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 All 155 releases
← All changes | class/class-mainwp-db-client.php +1409 -1130 5.0.3 → 6.2.1 View file →
@@ -8,1314 +8,1593 @@
8 8 */
9 9
10 10 namespace MainWP\Dashboard;
11 11
12 +// Exit if accessed directly.
13 +if ( ! defined( 'ABSPATH' ) ) {
14 + exit;
15 +}
16 +
12 17 /**
13 18 * Class MainWP_DB_Client
14 19 *
15 20 * @package MainWP\Dashboard
16 21 */
17 -class MainWP_DB_Client extends MainWP_DB {
22 +class MainWP_DB_Client extends MainWP_DB { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
18 23
19 - // phpcs:disable WordPress.DB.RestrictedFunctions, WordPress.DB.PreparedSQL.NotPrepared, Generic.Metrics.CyclomaticComplexity -- unprepared SQL ok, accessing the database directly to custom database functions.
24 + // phpcs:disable WordPress.DB.RestrictedFunctions, WordPress.DB.PreparedSQL.NotPrepared, Generic.Metrics.CyclomaticComplexity -- unprepared SQL ok, accessing the database directly to custom database functions.
20 25
21 - /**
22 - * Private static variable to hold the single instance of the class.
23 - *
24 - * @static
25 - *
26 - * @var mixed Default null
27 - */
28 - private static $instance = null;
26 + /**
27 + * Private static variable to hold the single instance of the class.
28 + *
29 + * @static
30 + *
31 + * @var mixed Default null
32 + */
33 + private static $instance = null;
29 34
30 - /**
31 - * Method instance()
32 - *
33 - * Create public static instance.
34 - *
35 - * @static
36 - * @return MainWP_DB_Client
37 - */
38 - public static function instance() {
39 - if ( null === self::$instance ) {
40 - self::$instance = new self();
41 - }
42 - return self::$instance;
43 - }
35 + /**
36 + * Method instance()
37 + *
38 + * Create public static instance.
39 + *
40 + * @static
41 + * @return MainWP_DB_Client
42 + */
43 + public static function instance() {
44 + if ( null === static::$instance ) {
45 + static::$instance = new self();
46 + }
47 + return static::$instance;
48 + }
44 49
45 - /**
46 - * Constructor.
47 - *
48 - * Run each time the class is called.
49 - */
50 - public function __construct() {
51 - parent::__construct();
52 - add_filter( 'mainwp_db_install_tables', array( $this, 'hook_db_install_tables' ), 10, 3 );
53 - }
50 + /**
51 + * Constructor.
52 + *
53 + * Run each time the class is called.
54 + */
55 + public function __construct() {
56 + parent::__construct();
57 + add_filter( 'mainwp_db_install_tables', array( $this, 'hook_db_install_tables' ), 10, 3 );
58 + }
54 59
55 - /**
56 - * Method hook_db_install_tables()
57 - *
58 - * Get the query to install db tables.
59 - *
60 - * @param array $sql input filter.
61 - * @param string $currentVersion Current db Version.
62 - * @param string $charset_collate charset collate.
63 - *
64 - * @return array $sql queries.
65 - */
66 - public function hook_db_install_tables( $sql, $currentVersion, $charset_collate ) {
60 + /**
61 + * Method hook_db_install_tables()
62 + *
63 + * Get the query to install db tables.
64 + *
65 + * @param array $sql input filter.
66 + * @param string $currentVersion Current db Version.
67 + * @param string $charset_collate charset collate.
68 + *
69 + * @return array $sql queries.
70 + */
71 + public function hook_db_install_tables( $sql, $currentVersion, $charset_collate ) {
67 72
68 - $tbl = 'CREATE TABLE ' . $this->table_name( 'wp_clients' ) . " (
69 - client_id int(11) NOT NULL auto_increment,
70 - image varchar(255) NOT NULL default '',
71 - name varchar(255) NOT NULL,
72 - address_1 varchar(255) NOT NULL default '',
73 - address_2 varchar(255) NOT NULL default '',
74 - city varchar(100) NOT NULL default '',
75 - zip varchar(32) NOT NULL default '',
76 - state varchar(200) NOT NULL default '',
77 - country varchar(200) NOT NULL default '',
78 - note longtext NOT NULL default '',
79 - selected_icon_info varchar(64) NOT NULL default '',
80 - client_email varchar(191) NOT NULL,
81 - client_phone varchar(100) NOT NULL default '',
82 - client_facebook varchar(255) NOT NULL default '',
83 - client_twitter varchar(255) NOT NULL default '',
84 - client_instagram varchar(255) NOT NULL default '',
85 - client_linkedin varchar(255) NOT NULL default '',
86 - created int(11) NOT NULL DEFAULT 0,
87 - `suspended` tinyint(1) NOT NULL DEFAULT 0,
88 - primary_contact_id int(11) NOT NULL default 0";
73 + $tbl = 'CREATE TABLE ' . $this->table_name( 'wp_clients' ) . " (
74 + client_id int(11) NOT NULL auto_increment,
75 + image varchar(255) NOT NULL default '',
76 + name varchar(255) NOT NULL,
77 + address_1 varchar(255) NOT NULL default '',
78 + address_2 varchar(255) NOT NULL default '',
79 + city varchar(100) NOT NULL default '',
80 + zip varchar(32) NOT NULL default '',
81 + state varchar(200) NOT NULL default '',
82 + country varchar(200) NOT NULL default '',
83 + note longtext NOT NULL default '',
84 + selected_icon_info varchar(64) NOT NULL default '',
85 + client_email varchar(191) NOT NULL,
86 + client_phone varchar(100) NOT NULL default '',
87 + client_facebook varchar(255) NOT NULL default '',
88 + client_twitter varchar(255) NOT NULL default '',
89 + client_instagram varchar(255) NOT NULL default '',
90 + client_linkedin varchar(255) NOT NULL default '',
91 + created int(11) NOT NULL DEFAULT 0,
92 + `suspended` tinyint(1) NOT NULL DEFAULT 0,
93 + primary_contact_id int(11) NOT NULL default 0";
89 94
90 - if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.61', '<=' ) ) {
91 - $tbl .= ',
92 - PRIMARY KEY (client_id)';
93 - }
94 - $tbl .= ') ' . $charset_collate;
95 - $sql[] = $tbl;
95 + if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.61', '<=' ) ) {
96 + $tbl .= ',
97 + PRIMARY KEY (client_id)';
98 + }
99 + $tbl .= ') ' . $charset_collate;
100 + $sql[] = $tbl;
96 101
97 - $tbl = 'CREATE TABLE ' . $this->table_name( 'wp_clients_fields' ) . ' (
98 - field_id int(11) NOT NULL auto_increment,
99 - field_name varchar(191) NOT NULL DEFAULT "",
100 - field_desc varchar(255) NOT NULL DEFAULT "",
101 - client_id int(11) NOT NULL,
102 - UNIQUE KEY client_id_field_name (client_id,field_name)';
102 + $tbl = 'CREATE TABLE ' . $this->table_name( 'wp_clients_fields' ) . ' (
103 + field_id int(11) NOT NULL auto_increment,
104 + field_name varchar(191) NOT NULL DEFAULT "",
105 + field_desc varchar(255) NOT NULL DEFAULT "",
106 + client_id int(11) NOT NULL,
107 + UNIQUE KEY client_id_field_name (client_id,field_name)';
103 108
104 - if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.61', '<=' ) ) {
105 - $tbl .= ',
106 - PRIMARY KEY (`field_id`) ';
107 - }
109 + if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.61', '<=' ) ) {
110 + $tbl .= ',
111 + PRIMARY KEY (`field_id`) ';
112 + }
108 113
109 - $tbl .= ') ' . $charset_collate;
110 - $sql[] = $tbl;
114 + $tbl .= ') ' . $charset_collate;
115 + $sql[] = $tbl;
111 116
112 - $tbl = 'CREATE TABLE ' . $this->table_name( 'wp_clients_field_values' ) . ' (
113 - value_id int(11) NOT NULL auto_increment,
114 - field_id int(11) NOT NULL,
115 - field_value longtext NOT NULL DEFAULT "",
116 - value_client_id int(11) NOT NULL,
117 - UNIQUE KEY value_client_id_field_id (value_client_id, field_id)';
117 + $tbl = 'CREATE TABLE ' . $this->table_name( 'wp_clients_field_values' ) . ' (
118 + value_id int(11) NOT NULL auto_increment,
119 + field_id int(11) NOT NULL,
120 + field_value longtext NOT NULL DEFAULT "",
121 + value_client_id int(11) NOT NULL,
122 + UNIQUE KEY value_client_id_field_id (value_client_id, field_id)';
118 123
119 - if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.61', '<=' ) ) {
120 - $tbl .= ',
121 - PRIMARY KEY (`value_id`) ';
122 - }
124 + if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.61', '<=' ) ) {
125 + $tbl .= ',
126 + PRIMARY KEY (`value_id`) ';
127 + }
123 128
124 - $tbl .= ') ' . $charset_collate;
125 - $sql[] = $tbl;
129 + $tbl .= ') ' . $charset_collate;
130 + $sql[] = $tbl;
126 131
127 - $tbl = 'CREATE TABLE ' . $this->table_name( 'wp_clients_contacts' ) . ' (
128 - contact_id int(11) NOT NULL auto_increment,
129 - contact_client_id int(11) NOT NULL,
130 - contact_email varchar(191) NOT NULL,
131 - contact_image varchar(255) NOT NULL default "",
132 - contact_icon_info varchar(64) NOT NULL default "",
133 - contact_name varchar(255) NOT NULL,
134 - contact_phone varchar(100) NOT NULL default "",
135 - contact_role varchar(255) NOT NULL default "",
136 - facebook varchar(255) NOT NULL default "",
137 - twitter varchar(255) NOT NULL default "",
138 - instagram varchar(255) NOT NULL default "",
139 - linkedin varchar(255) NOT NULL default "",
140 - UNIQUE KEY contact_email(contact_email)';
132 + $tbl = 'CREATE TABLE ' . $this->table_name( 'wp_clients_contacts' ) . ' (
133 + contact_id int(11) NOT NULL auto_increment,
134 + contact_client_id int(11) NOT NULL,
135 + contact_email varchar(191) NOT NULL,
136 + contact_image varchar(255) NOT NULL default "",
137 + contact_icon_info varchar(64) NOT NULL default "",
138 + contact_name varchar(255) NOT NULL,
139 + contact_phone varchar(100) NOT NULL default "",
140 + contact_role varchar(255) NOT NULL default "",
141 + facebook varchar(255) NOT NULL default "",
142 + twitter varchar(255) NOT NULL default "",
143 + instagram varchar(255) NOT NULL default "",
144 + linkedin varchar(255) NOT NULL default "",
145 + UNIQUE KEY contact_email (contact_email)';
141 146
142 - if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.69', '<=' ) ) {
143 - $tbl .= ',
144 - PRIMARY KEY (contact_id)';
145 - }
146 - $tbl .= ') ' . $charset_collate;
147 - $sql[] = $tbl;
147 + if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.69', '<=' ) ) {
148 + $tbl .= ',
149 + PRIMARY KEY (contact_id)';
150 + }
151 + $tbl .= ') ' . $charset_collate;
152 + $sql[] = $tbl;
148 153
149 - return $sql;
150 - }
154 + return $sql;
155 + }
151 156
152 - /**
153 - * Method check_to_updates_reports_data_861()
154 - *
155 - * Check version less than 8.61 to import reports data.
156 - *
157 - * @param string $currentVersion Current db Version.
158 - *
159 - * @return void.
160 - */
161 - public function check_to_updates_reports_data_861( $currentVersion ) {
157 + /**
158 + * Method check_to_updates_reports_data_861()
159 + *
160 + * Check version less than 8.61 to import reports data.
161 + *
162 + * @param string $currentVersion Current db Version.
163 + *
164 + * @return void.
165 + */
166 + public function check_to_updates_reports_data_861( $currentVersion ) {
162 167
163 - $convert_pro_reports_dt = false;
164 - $convert_client_reports_dt = false;
165 - if ( is_plugin_active( 'mainwp-pro-reports-extension/mainwp-pro-reports-extension.php' ) ) {
166 - $convert_pro_reports_dt = true;
167 - } elseif ( is_plugin_active( 'mainwp-client-reports-extension/mainwp-client-reports-extension.php' ) ) {
168 - $convert_client_reports_dt = true;
169 - }
168 + $convert_pro_reports_dt = false;
169 + $convert_client_reports_dt = false;
170 + if ( is_plugin_active( 'mainwp-pro-reports-extension/mainwp-pro-reports-extension.php' ) ) {
171 + $convert_pro_reports_dt = true;
172 + } elseif ( is_plugin_active( 'mainwp-client-reports-extension/mainwp-client-reports-extension.php' ) ) {
173 + $convert_client_reports_dt = true;
174 + }
170 175
171 - if ( ! $convert_pro_reports_dt && ! $convert_client_reports_dt ) {
172 - $rslt = $this->query( "SHOW TABLES LIKE '" . $this->table_name( 'pro_reports_token' ) . "'" );
173 - if ( self::num_rows( $rslt ) ) {
174 - $convert_pro_reports_dt = true;
175 - }
176 + if ( ! $convert_pro_reports_dt && ! $convert_client_reports_dt ) {
177 + $table_token = esc_sql( $this->table_name( 'pro_reports_token' ) );
178 + $rslt = $this->query( 'SHOW TABLES LIKE ' . $this->wpdb->prepare( '%s', $table_token ) );
179 + if ( static::num_rows( $rslt ) ) {
180 + $convert_pro_reports_dt = true;
181 + }
176 182
177 - $rslt = $this->query( "SHOW TABLES LIKE '" . $this->table_name( 'client_report_token' ) . "'" );
178 - if ( self::num_rows( $rslt ) ) {
179 - $convert_client_reports_dt = true;
180 - }
181 - }
183 + $table_report_token = esc_sql( $this->table_name( 'client_report_token' ) );
184 + $rslt = $this->query( 'SHOW TABLES LIKE ' . $this->wpdb->prepare( '%s', $table_report_token ) );
185 + if ( static::num_rows( $rslt ) ) {
186 + $convert_client_reports_dt = true;
187 + }
188 + }
182 189
183 - $this->insert_client_fields_861( $currentVersion );
190 + $this->insert_client_fields_861( $currentVersion );
184 191
185 - if ( $convert_pro_reports_dt ) {
186 - $this->pro_reports_check_updates_861( $currentVersion );
187 - } elseif ( $convert_client_reports_dt ) {
188 - $this->client_reports_check_updates_861( $currentVersion );
189 - }
190 - }
192 + if ( $convert_pro_reports_dt ) {
193 + $this->pro_reports_check_updates_861( $currentVersion );
194 + } elseif ( $convert_client_reports_dt ) {
195 + $this->client_reports_check_updates_861( $currentVersion );
196 + }
197 + }
191 198
192 - /**
193 - * Method insert_client_fields_861()
194 - *
195 - * Check version less than 8.61 to import client reports data.
196 - *
197 - * @param string $currentVersion Current db Version.
198 - *
199 - * @return null.
200 - */
201 - public function insert_client_fields_861( $currentVersion ) {
199 + /**
200 + * Method insert_client_fields_861()
201 + *
202 + * Check version less than 8.61 to import client reports data.
203 + *
204 + * @param string $currentVersion Current db Version.
205 + *
206 + * @return null.
207 + */
208 + public function insert_client_fields_861( $currentVersion ) {
202 209
203 - if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.61', '>' ) ) {
204 - return;
205 - }
210 + if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.61', '>' ) ) {
211 + return;
212 + }
206 213
207 - $default_tokens = array(
208 - 'client.name' => 'Displays the Client Name',
209 - 'client.contact.name' => 'Displays the Client Contact Name',
210 - 'client.contact.address.1' => 'Displays the Client Contact Address 1',
211 - 'client.contact.address.2' => 'Displays the Client Contact Address 2',
212 - 'client.city' => 'Displays the Client City',
213 - 'client.state' => 'Displays the Client State',
214 - 'client.zip' => 'Displays the Client Zip',
215 - 'client.phone' => 'Displays the Client Phone',
216 - 'client.email' => 'Displays the Client Email',
217 - 'client.note' => 'Displays the Client Note',
218 - );
214 + $default_tokens = array(
215 + 'client.name' => 'Displays the Client Name',
216 + 'client.contact.name' => 'Displays the Client Contact Name',
217 + 'client.contact.address.1' => 'Displays the Client Contact Address 1',
218 + 'client.contact.address.2' => 'Displays the Client Contact Address 2',
219 + 'client.city' => 'Displays the Client City',
220 + 'client.state' => 'Displays the Client State',
221 + 'client.zip' => 'Displays the Client Zip',
222 + 'client.phone' => 'Displays the Client Phone',
223 + 'client.email' => 'Displays the Client Email',
224 + 'client.note' => 'Displays the Client Note',
225 + );
219 226
220 - // create or update default token.
221 - foreach ( $default_tokens as $field_name => $field_desc ) {
222 - $current = $this->get_client_fields_by( 'field_name', $field_name );
223 - if ( $current ) {
224 - $this->update_client_field(
225 - $current->field_id,
226 - array(
227 - 'field_name' => $field_name,
228 - 'field_desc' => $field_desc,
229 - )
230 - );
231 - } else {
232 - $this->add_client_field(
233 - array(
234 - 'field_name' => $field_name,
235 - 'field_desc' => $field_desc,
236 - 'client_id' => 0,
237 - )
238 - );
227 + // create or update default token.
228 + foreach ( $default_tokens as $field_name => $field_desc ) {
229 + $current = $this->get_client_fields_by( 'field_name', $field_name );
230 + if ( $current ) {
231 + $this->update_client_field(
232 + $current->field_id,
233 + array(
234 + 'field_name' => $field_name,
235 + 'field_desc' => $field_desc,
236 + )
237 + );
238 + } else {
239 + $this->add_client_field(
240 + array(
241 + 'field_name' => $field_name,
242 + 'field_desc' => $field_desc,
243 + 'client_id' => 0,
244 + )
245 + );
239 246
240 - }
241 - }
242 - }
247 + }
248 + }
249 + }
243 250
244 - /**
245 - * Method client_reports_check_updates_861()
246 - *
247 - * Check version less than 8.61 to import client reports data.
248 - *
249 - * @param string $currentVersion Current db Version.
250 - *
251 - * @return null.
252 - */
253 - public function client_reports_check_updates_861( $currentVersion ) {
251 + /**
252 + * Method client_reports_check_updates_861()
253 + *
254 + * Check version less than 8.61 to import client reports data.
255 + *
256 + * @param string $currentVersion Current db Version.
257 + *
258 + * @return null.
259 + */
260 + public function client_reports_check_updates_861( $currentVersion ) {
254 261
255 - if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.61', '>' ) ) {
256 - return;
257 - }
262 + if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.61', '>' ) ) {
263 + return;
264 + }
258 265
259 - $tokens = $this->client_reports_get_tokens();
260 - $sites_tokens_values = $this->client_reports_get_site_token_values();
266 + $tokens = $this->client_reports_get_tokens();
267 + $sites_tokens_values = $this->client_reports_get_site_token_values();
261 268
262 - $this->reports_check_updates_861( $tokens, $sites_tokens_values );
263 - }
269 + $this->reports_check_updates_861( $tokens, $sites_tokens_values );
270 + }
264 271
265 - /**
266 - * Method pro_reports_check_updates_861()
267 - *
268 - * Check version less than 8.61 to import pro reports data.
269 - *
270 - * @param string $currentVersion Current db Version.
271 - *
272 - * @return null.
273 - */
274 - public function pro_reports_check_updates_861( $currentVersion ) {
272 + /**
273 + * Method pro_reports_check_updates_861()
274 + *
275 + * Check version less than 8.61 to import pro reports data.
276 + *
277 + * @param string $currentVersion Current db Version.
278 + *
279 + * @return null.
280 + */
281 + public function pro_reports_check_updates_861( $currentVersion ) {
275 282
276 - if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.61', '>' ) ) {
277 - return;
278 - }
283 + if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.61', '>' ) ) {
284 + return;
285 + }
279 286
280 - $tokens = $this->pro_reports_get_tokens();
281 - $sites_tokens_values = $this->pro_reports_get_site_token_values();
287 + $tokens = $this->pro_reports_get_tokens();
288 + $sites_tokens_values = $this->pro_reports_get_site_token_values();
282 289
283 - $this->reports_check_updates_861( $tokens, $sites_tokens_values );
284 - }
290 + $this->reports_check_updates_861( $tokens, $sites_tokens_values );
291 + }
285 292
286 293
287 - /**
288 - * Method reports_check_updates_861()
289 - *
290 - * Check version less than 8.61 to import reports data.
291 - *
292 - * @param array $tokens Tokens.
293 - * @param array $sites_tokens_values Tokens values.
294 - *
295 - * @return void.
296 - */
297 - public function reports_check_updates_861( $tokens, $sites_tokens_values ) { // phpcs:ignore -- complexex function. Current complexity is the only way to achieve desired results, pull request solutions appreciated.
294 + /**
295 + * Method reports_check_updates_861()
296 + *
297 + * Check version less than 8.61 to import reports data.
298 + *
299 + * @param array $tokens Tokens.
300 + * @param array $sites_tokens_values Tokens values.
301 + *
302 + * @return void.
303 + */
304 + public function reports_check_updates_861( $tokens, $sites_tokens_values ) { // phpcs:ignore -- NOSONAR complexex function. Current complexity is the only way to achieve desired results, pull request solutions appreciated.
298 305
299 - $default_client_fields = MainWP_Client_Handler::get_default_client_fields();
300 - $default_contact_fields = MainWP_Client_Handler::get_default_contact_fields();
306 + $default_client_fields = MainWP_Client_Handler::get_default_client_fields();
307 + $default_contact_fields = MainWP_Client_Handler::get_default_contact_fields();
301 308
302 - $compatible_tokens = MainWP_Client_Handler::get_compatible_tokens();
309 + $compatible_tokens = MainWP_Client_Handler::get_compatible_tokens();
303 310
304 - $ids_to_tokens = array();
311 + $ids_to_tokens = array();
305 312
306 - if ( $tokens ) {
307 - foreach ( $tokens as $token ) {
308 - $tok_name = $token->token_name;
309 - $ids_to_tokens[ $token->id ] = array(
310 - 'token_name' => $tok_name,
311 - 'token_desc' => $token->token_description,
312 - );
313 - }
314 - }
313 + if ( $tokens ) {
314 + foreach ( $tokens as $token ) {
315 + $tok_name = $token->token_name;
316 + $ids_to_tokens[ $token->id ] = array(
317 + 'token_name' => $tok_name,
318 + 'token_desc' => $token->token_description,
319 + );
320 + }
321 + }
315 322
316 - $ids_to_tokens_values = array();
323 + $ids_to_tokens_values = array();
317 324
318 - if ( $sites_tokens_values ) {
319 - foreach ( $sites_tokens_values as $token ) {
320 - if ( ! isset( $ids_to_tokens[ $token->token_id ] ) ) {
321 - continue;
322 - }
323 - if ( empty( $token->token_value ) ) {
324 - continue;
325 - }
326 - $tok_name = $ids_to_tokens[ $token->token_id ]['token_name'];
325 + if ( $sites_tokens_values ) {
326 + foreach ( $sites_tokens_values as $token ) {
327 + if ( ! isset( $ids_to_tokens[ $token->token_id ] ) ) {
328 + continue;
329 + }
330 + if ( empty( $token->token_value ) ) {
331 + continue;
332 + }
333 + $tok_name = $ids_to_tokens[ $token->token_id ]['token_name'];
327 334
328 - $ids_to_tokens_values[ $token->site_id ][ $tok_name ] = array(
329 - 'token_value' => $token->token_value,
330 - 'token_desc' => $ids_to_tokens[ $token->token_id ]['token_desc'],
331 - );
332 - }
333 - }
335 + $ids_to_tokens_values[ $token->site_id ][ $tok_name ] = array(
336 + 'token_value' => $token->token_value,
337 + 'token_desc' => $ids_to_tokens[ $token->token_id ]['token_desc'],
338 + );
339 + }
340 + }
334 341
335 - $clients_to_add = array();
336 - $primary_contacts_to_add = array();
337 - $custom_tokens_to_add = array();
342 + $clients_to_add = array();
343 + $primary_contacts_to_add = array();
344 + $custom_tokens_to_add = array();
338 345
339 - foreach ( $ids_to_tokens_values as $site_id => $tokens ) {
346 + foreach ( $ids_to_tokens_values as $site_id => $tokens ) {
340 347
341 - if ( empty( $tokens['client.email'] ) ) {
342 - continue;
343 - }
348 + if ( empty( $tokens['client.email'] ) ) {
349 + continue;
350 + }
344 351
345 - $email = $tokens['client.email']['token_value'];
352 + $email = $tokens['client.email']['token_value'];
346 353
347 - if ( ! isset( $clients_to_add[ $email ] ) ) {
348 - $clients_to_add[ $email ] = array();
349 - }
354 + if ( ! isset( $clients_to_add[ $email ] ) ) {
355 + $clients_to_add[ $email ] = array();
356 + }
350 357
351 - if ( ! isset( $clients_to_add[ $email ]['site_ids'] ) ) {
352 - $clients_to_add[ $email ]['site_ids'] = array();
353 - }
358 + if ( ! isset( $clients_to_add[ $email ]['site_ids'] ) ) {
359 + $clients_to_add[ $email ]['site_ids'] = array();
360 + }
354 361
355 - $clients_to_add[ $email ]['site_ids'][] = $site_id;
362 + $clients_to_add[ $email ]['site_ids'][] = $site_id;
356 363
357 - // prepare clients to add.
358 - foreach ( $default_client_fields as $field_name => $field ) {
359 - if ( ! isset( $tokens[ $field_name ] ) ) {
360 - continue;
361 - }
362 - $clients_to_add[ $email ][ $field['db_field'] ] = $tokens[ $field_name ]['token_value'];
363 - }
364 + // prepare clients to add.
365 + foreach ( $default_client_fields as $field_name => $field ) {
366 + if ( ! isset( $tokens[ $field_name ] ) ) {
367 + continue;
368 + }
369 + $clients_to_add[ $email ][ $field['db_field'] ] = $tokens[ $field_name ]['token_value'];
370 + }
364 371
365 - $flip_compatible_tokens = array_flip( $compatible_tokens ); // flip: new_token_name => old_token_name.
366 - // prepare primary contacts to add.
367 - foreach ( $default_contact_fields as $field_name => $field ) {
372 + $flip_compatible_tokens = array_flip( $compatible_tokens ); // flip: new_token_name => old_token_name.
373 + // prepare primary contacts to add.
374 + foreach ( $default_contact_fields as $field_name => $field ) {
368 375
369 - // $field_name - new_token_name.
370 - // $tok_name - old_token_name.
371 - $tok_name = isset( $flip_compatible_tokens[ $field_name ] ) ? $flip_compatible_tokens[ $field_name ] : $field_name;
372 - if ( ! isset( $tokens[ $tok_name ] ) ) {
373 - continue;
374 - }
376 + // $field_name - new_token_name.
377 + // $tok_name - old_token_name.
378 + $tok_name = isset( $flip_compatible_tokens[ $field_name ] ) ? $flip_compatible_tokens[ $field_name ] : $field_name;
379 + if ( ! isset( $tokens[ $tok_name ] ) ) {
380 + continue;
381 + }
375 382
376 - $primary_contacts_to_add[ $email ][ $field['db_field'] ] = $tokens[ $tok_name ]['token_value'];
377 - }
383 + $primary_contacts_to_add[ $email ][ $field['db_field'] ] = $tokens[ $tok_name ]['token_value'];
384 + }
378 385
379 - foreach ( $tokens as $tok_name => $tok_value_desc ) {
380 - if ( isset( $default_client_fields[ $tok_name ] ) || isset( $default_contact_fields[ $tok_name ] ) ) {
381 - continue;
382 - }
383 - if ( 'client.site.url' === $tok_name || 'client.site.name' === $tok_name ) { // avoid those tokens.
384 - continue;
385 - }
386 - if ( isset( $compatible_tokens[ $tok_name ] ) ) {
387 - continue;
388 - }
389 - $custom_tokens_to_add[ $email ][ $tok_name ] = $tok_value_desc;
390 - }
391 - }
386 + foreach ( $tokens as $tok_name => $tok_value_desc ) {
387 + if ( isset( $default_client_fields[ $tok_name ] ) || isset( $default_contact_fields[ $tok_name ] ) ) {
388 + continue;
389 + }
390 + if ( 'client.site.url' === $tok_name || 'client.site.name' === $tok_name ) { // avoid those tokens.
391 + continue;
392 + }
393 + if ( isset( $compatible_tokens[ $tok_name ] ) ) {
394 + continue;
395 + }
396 + $custom_tokens_to_add[ $email ][ $tok_name ] = $tok_value_desc;
397 + }
398 + }
392 399
393 - $emails_to_ids = array();
394 - foreach ( $clients_to_add as $email => $client_add ) {
395 - $selected_sites = array();
396 - if ( isset( $client_add['site_ids'] ) ) {
397 - $selected_sites = $client_add['site_ids'];
398 - unset( $client_add['site_ids'] );
399 - }
400 + $emails_to_ids = array();
401 + foreach ( $clients_to_add as $email => $client_add ) {
402 + $selected_sites = array();
403 + if ( isset( $client_add['site_ids'] ) ) {
404 + $selected_sites = $client_add['site_ids'];
405 + unset( $client_add['site_ids'] );
406 + }
400 407
401 - $inserted = $this->update_client( $client_add ); // add new client.
408 + $inserted = $this->update_client( $client_add ); // add new client.
402 409
403 - if ( $inserted ) {
404 - $client_id = $inserted->client_id;
405 - $this->update_selected_sites_for_client( $client_id, $selected_sites );
406 - $emails_to_ids[ $email ] = $client_id;
407 - }
408 - }
410 + if ( $inserted ) {
411 + $client_id = $inserted->client_id;
412 + $this->update_selected_sites_for_client( $client_id, $selected_sites );
413 + $emails_to_ids[ $email ] = $client_id;
414 + }
415 + }
409 416
410 - foreach ( $emails_to_ids as $email => $client_id ) {
417 + foreach ( $emails_to_ids as $email => $client_id ) {
411 418
412 - if ( isset( $primary_contacts_to_add[ $email ] ) ) {
413 - $contact_add = $primary_contacts_to_add[ $email ];
414 - $contact_add['contact_client_id'] = $client_id;
415 - $inserted = $this->update_client_contact( $contact_add );
416 - if ( $inserted ) {
417 - $params = array(
418 - 'client_id' => $client_id, // update the client.
419 - 'primary_contact_id' => $inserted->contact_id,
420 - );
421 - $this->update_client( $params );
422 - }
423 - }
419 + if ( isset( $primary_contacts_to_add[ $email ] ) ) {
420 + $contact_add = $primary_contacts_to_add[ $email ];
421 + $contact_add['contact_client_id'] = $client_id;
422 + $inserted = $this->update_client_contact( $contact_add );
423 + if ( $inserted ) {
424 + $params = array(
425 + 'client_id' => $client_id, // update the client.
426 + 'primary_contact_id' => $inserted->contact_id,
427 + );
428 + $this->update_client( $params );
429 + }
430 + }
424 431
425 - if ( isset( $custom_tokens_to_add[ $email ] ) ) {
426 - $custom_tokens = $custom_tokens_to_add[ $email ];
427 - foreach ( $custom_tokens as $tok_name => $tok_value_desc ) {
428 - $field_id = 0;
429 - $current = $this->get_client_fields_by( 'field_name', $tok_name ); // get general field by name.
430 - if ( $current ) {
431 - $field_id = $current->field_id;
432 - } else {
433 - $field = array(
434 - 'field_name' => $tok_name,
435 - 'field_desc' => $tok_value_desc['token_desc'],
436 - 'client_id' => 0, // it is general tokens.
437 - );
438 - $new_field = $this->add_client_field( $field );
439 - if ( $new_field ) {
440 - $field_id = $new_field->field_id;
441 - }
442 - }
432 + if ( isset( $custom_tokens_to_add[ $email ] ) ) {
433 + $custom_tokens = $custom_tokens_to_add[ $email ];
434 + foreach ( $custom_tokens as $tok_name => $tok_value_desc ) {
435 + $field_id = 0;
436 + $current = $this->get_client_fields_by( 'field_name', $tok_name ); // get general field by name.
437 + if ( $current ) {
438 + $field_id = $current->field_id;
439 + } else {
440 + $field = array(
441 + 'field_name' => $tok_name,
442 + 'field_desc' => $tok_value_desc['token_desc'],
443 + 'client_id' => 0, // it is general tokens.
444 + );
445 + $new_field = $this->add_client_field( $field );
446 + if ( $new_field ) {
447 + $field_id = $new_field->field_id;
448 + }
449 + }
443 450
444 - if ( $field_id ) {
445 - $this->update_client_field_value( $field_id, $tok_value_desc['token_value'], $client_id );
446 - }
447 - }
448 - }
449 - }
450 - }
451 + if ( $field_id ) {
452 + $this->update_client_field_value( $field_id, $tok_value_desc['token_value'], $client_id );
453 + }
454 + }
455 + }
456 + }
457 + }
451 458
452 459
453 - /**
454 - * Method update_client.
455 - *
456 - * Create or update client.
457 - *
458 - * @param array $data Client data.
459 - * @param bool $throw_out Throw or return error.
460 - *
461 - * @throws MainWP_Exception On errors.
462 - *
463 - * @return bool.
464 - */
465 - public function update_client( $data, $throw_out = false ) {
466 - if ( empty( $data ) || ! is_array( $data ) ) {
467 - return false;
468 - }
460 + /**
461 + * Method update_client.
462 + *
463 + * Create or update client.
464 + *
465 + * @param array $data Client data.
466 + * @param bool $throw_out Throw or return error.
467 + *
468 + * @throws MainWP_Exception On errors.
469 + *
470 + * @return bool.
471 + */
472 + public function update_client( $data, $throw_out = false ) {
473 + if ( empty( $data ) || ! is_array( $data ) ) {
474 + return false;
475 + }
469 476
470 - $client_id = isset( $data['client_id'] ) ? (int) $data['client_id'] : 0;
477 + $client_id = isset( $data['client_id'] ) ? (int) $data['client_id'] : 0;
471 478
472 - if ( isset( $data['client_email'] ) && ! empty( $data['client_email'] ) ) {
473 - $client_existed = $this->get_wp_client_by( 'client_email', $data['client_email'], ARRAY_A );
474 - if ( is_array( $client_existed ) && isset( $client_existed['client_id'] ) && ( empty( $client_id ) || $client_id !== (int) $client_existed['client_id'] ) ) {
475 - if ( $throw_out ) {
476 - throw new MainWP_Exception( esc_html__( 'Client email exists. Please try again.', 'mainwp' ) );
477 - } else {
478 - return false;
479 - }
480 - }
481 - }
479 + if ( isset( $data['client_email'] ) && ! empty( $data['client_email'] ) ) {
480 + $client_existed = $this->get_wp_client_by( 'client_email', $data['client_email'], ARRAY_A );
481 + if ( is_array( $client_existed ) && isset( $client_existed['client_id'] ) && ( empty( $client_id ) || $client_id !== (int) $client_existed['client_id'] ) ) {
482 + if ( $throw_out ) {
483 + throw new MainWP_Exception( esc_html__( 'Client email exists. Please try again.', 'mainwp' ) );
484 + } else {
485 + return false;
486 + }
487 + }
488 + }
482 489
483 - if ( ! empty( $client_id ) ) {
484 - $this->wpdb->update( $this->table_name( 'wp_clients' ), $data, array( 'client_id' => intval( $client_id ) ) );
485 - return $this->get_wp_client_by( 'client_id', $client_id );
486 - } elseif ( $this->wpdb->insert( $this->table_name( 'wp_clients' ), $data ) ) {
487 - return $this->get_wp_client_by( 'client_id', $this->wpdb->insert_id );
488 - }
489 - return false;
490 - }
490 + if ( ! empty( $client_id ) ) {
491 + $this->wpdb->update( $this->table_name( 'wp_clients' ), $data, array( 'client_id' => intval( $client_id ) ) );
492 + return $this->get_wp_client_by( 'client_id', $client_id );
493 + } elseif ( $this->wpdb->insert( $this->table_name( 'wp_clients' ), $data ) ) {
494 + return $this->get_wp_client_by( 'client_id', $this->wpdb->insert_id );
495 + }
496 + return false;
497 + }
491 498
492 499
493 - /**
494 - * Method update_client.
495 - *
496 - * Create or update client contact.
497 - *
498 - * @param array $data Contact data.
499 - *
500 - * @return bool.
501 - */
502 - public function update_client_contact( $data ) {
500 + /**
501 + * Method update_client.
502 + *
503 + * Create or update client contact.
504 + *
505 + * @param array $data Contact data.
506 + *
507 + * @return bool.
508 + */
509 + public function update_client_contact( $data ) { // phpcs:ignore -- NOSONAR - complex.
503 510
504 - if ( empty( $data ) ) {
505 - return false;
506 - }
511 + if ( empty( $data ) ) {
512 + return false;
513 + }
507 514
508 - $contact_id = isset( $data['contact_id'] ) ? (int) $data['contact_id'] : 0;
515 + $contact_id = isset( $data['contact_id'] ) ? (int) $data['contact_id'] : 0;
509 516
510 - $contact_email = isset( $data['contact_email'] ) ? $data['contact_email'] : '';
511 - if ( ! empty( $contact_email ) ) {
512 - $existed_email = false;
513 - // check to valid email.
514 - $curret_contact = $this->get_wp_client_contact_by( 'contact_email', $contact_email );
515 - if ( $curret_contact && empty( $contact_id ) ) { // add new contact with existed email => failed.
516 - $existed_email = true;
517 - }
517 + $contact_email = isset( $data['contact_email'] ) ? $data['contact_email'] : '';
518 + if ( ! empty( $contact_email ) ) {
519 + $existed_email = false;
520 + // check to valid email.
521 + $curret_contact = $this->get_wp_client_contact_by( 'contact_email', $contact_email );
522 + if ( $curret_contact && empty( $contact_id ) ) { // add new contact with existed email => failed.
523 + $existed_email = true;
524 + }
518 525
519 - if ( $curret_contact && ! empty( $contact_id ) ) {
520 - if ( (int) $curret_contact->contact_id !== $contact_id ) { // update contact with existed email => failed.
521 - $existed_email = true;
522 - }
523 - }
526 + if ( $curret_contact && ! empty( $contact_id ) && (int) $curret_contact->contact_id !== $contact_id ) { // update contact with existed email => failed.
527 + $existed_email = true;
528 + }
524 529
525 - if ( $existed_email ) {
526 - MainWP_Utility::update_flash_message( 'contact_existed_emails', $contact_email );
527 - return false;
528 - }
529 - }
530 + if ( $existed_email ) {
531 + MainWP_Utility::update_flash_message( 'contact_existed_emails', $contact_email );
532 + return false;
533 + }
534 + }
530 535
531 - if ( ! empty( $contact_id ) ) {
532 - $this->wpdb->update( $this->table_name( 'wp_clients_contacts' ), $data, array( 'contact_id' => intval( $contact_id ) ) );
533 - return $this->get_wp_client_contact_by( 'contact_id', $contact_id );
534 - } elseif ( $this->wpdb->insert( $this->table_name( 'wp_clients_contacts' ), $data ) ) {
535 - return $this->get_wp_client_contact_by( 'contact_id', $this->wpdb->insert_id );
536 - }
537 - return false;
538 - }
536 + if ( ! empty( $contact_id ) ) {
537 + $this->wpdb->update( $this->table_name( 'wp_clients_contacts' ), $data, array( 'contact_id' => intval( $contact_id ) ) );
538 + return $this->get_wp_client_contact_by( 'contact_id', $contact_id );
539 + } elseif ( $this->wpdb->insert( $this->table_name( 'wp_clients_contacts' ), $data ) ) {
540 + return $this->get_wp_client_contact_by( 'contact_id', $this->wpdb->insert_id );
541 + }
542 + return false;
543 + }
539 544
540 - /**
541 - * Method get_wp_client_contact_by.
542 - *
543 - * Get client by.
544 - *
545 - * @param string $by by.
546 - * @param mixed $value by value.
547 - * @param mixed $obj Format data.
548 - * @param array $params other params.
549 - *
550 - * @return mixed $result results.
551 - */
552 - public function get_wp_client_contact_by( $by = 'contact_id', $value = null, $obj = OBJECT, $params = array() ) {
545 + /**
546 + * Method get_wp_client_contact_by.
547 + *
548 + * Get client by.
549 + *
550 + * @param string $by by.
551 + * @param mixed $value by value.
552 + * @param mixed $obj Format data.
553 + * @param array $params other params.
554 + *
555 + * @return mixed $result results.
556 + */
557 + public function get_wp_client_contact_by( $by = 'contact_id', $value = null, $obj = OBJECT, $params = array() ) { // phpcs:ignore -- NOSONAR - complex.
553 558
554 - $with_selected_sites = isset( $params['with_selected_sites'] ) && $params['with_selected_sites'] ? true : false;
555 - $with_tags = isset( $params['with_tags'] ) && $params['with_tags'] ? true : false;
559 + $sql = '';
560 + $table_contacts = esc_sql( $this->table_name( 'wp_clients_contacts' ) );
556 561
557 - $sql = '';
562 + if ( 'client_id' === $by && ! empty( $value ) ) {
563 + $sql = $this->wpdb->prepare( 'SELECT wc.* FROM ' . $table_contacts . ' wc WHERE wc.contact_client_id=%d ', $value );
564 + }
558 565
559 - if ( 'client_id' === $by && ! empty( $value ) ) {
560 - $sql = $this->wpdb->prepare( 'SELECT wc.* FROM ' . $this->table_name( 'wp_clients_contacts' ) . ' wc WHERE wc.contact_client_id=%d ', $value );
561 - }
566 + if ( ! empty( $sql ) ) {
567 + if ( OBJECT === $obj ) {
568 + $result = $this->wpdb->get_results( $sql, OBJECT ); // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $sql uses wpdb->prepare() or escaped table name concatenation, safe to use directly.
569 + } else {
570 + $result = $this->wpdb->get_results( $sql, ARRAY_A ); // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $sql uses wpdb->prepare() or escaped table name concatenation, safe to use directly.
571 + }
572 + return $result;
573 + }
562 574
563 - if ( ! empty( $sql ) ) {
564 - if ( OBJECT === $obj ) {
565 - $result = $this->wpdb->get_results( $sql, OBJECT );
566 - } else {
567 - $result = $this->wpdb->get_results( $sql, ARRAY_A );
568 - }
569 - return $result;
570 - }
575 + if ( 'contact_id' === $by && is_numeric( $value ) ) {
576 + $sql = $this->wpdb->prepare( 'SELECT wc.* FROM ' . $table_contacts . ' wc WHERE wc.contact_id=%d ', $value );
577 + } elseif ( 'contact_email' === $by && ! empty( $value ) ) {
578 + $sql = $this->wpdb->prepare( 'SELECT wc.* FROM ' . $table_contacts . ' wc WHERE wc.contact_email=%s ', $value );
579 + }
571 580
572 - if ( 'contact_id' === $by && is_numeric( $value ) ) {
573 - $sql = $this->wpdb->prepare( 'SELECT wc.* FROM ' . $this->table_name( 'wp_clients_contacts' ) . ' wc WHERE wc.contact_id=%d ', $value );
574 - } elseif ( 'contact_email' === $by && ! empty( $value ) ) {
575 - $sql = $this->wpdb->prepare( 'SELECT wc.* FROM ' . $this->table_name( 'wp_clients_contacts' ) . ' wc WHERE wc.contact_email=%s ', $value );
576 - }
581 + $result = null;
582 + if ( ! empty( $sql ) ) {
583 + if ( OBJECT === $obj ) {
584 + $result = $this->wpdb->get_row( $sql, OBJECT ); // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $sql uses wpdb->prepare() or escaped table name concatenation, safe to use directly.
585 + } else {
586 + $result = $this->wpdb->get_row( $sql, ARRAY_A ); // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $sql uses wpdb->prepare() or escaped table name concatenation, safe to use directly.
587 + }
588 + }
589 + return $result;
590 + }
577 591
578 - $result = null;
579 - if ( ! empty( $sql ) ) {
580 - if ( OBJECT === $obj ) {
581 - $result = $this->wpdb->get_row( $sql, OBJECT );
582 - } else {
583 - $result = $this->wpdb->get_row( $sql, ARRAY_A );
584 - }
585 - }
586 - return $result;
587 - }
588 592
593 + /**
594 + * Method delete_client.
595 + *
596 + * Delete client.
597 + *
598 + * @param int $client_id Client id of the contact.
599 + * @param int $contact_id Contact id to delete.
600 + *
601 + * @return bool Results.
602 + */
603 + public function delete_client_contact( $client_id, $contact_id ) {
604 + $current = $this->get_wp_client_contact_by( 'contact_id', $contact_id );
605 + $table_contacts = esc_sql( $this->table_name( 'wp_clients_contacts' ) );
606 + if ( $current && $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $table_contacts . ' WHERE contact_client_id=%d AND contact_id = %d', $client_id, $contact_id ) ) ) {
607 + if ( ! empty( $current->contact_image ) ) {
608 + $dirs = MainWP_System_Utility::get_mainwp_dir( 'client-images', true );
609 + $base_dir = $dirs[0];
610 + $old_file = $base_dir . '/' . $current->contact_image;
611 + MainWP_Utility::delete_file( $old_file );
612 + }
613 + return true;
614 + }
615 + return false;
616 + }
589 617
590 - /**
591 - * Method delete_client.
592 - *
593 - * Delete client.
594 - *
595 - * @param int $client_id Client id of the contact.
596 - * @param int $contact_id Contact id to delete.
597 - *
598 - * @return bool Results.
599 - */
600 - public function delete_client_contact( $client_id, $contact_id ) {
601 - $current = $this->get_wp_client_contact_by( 'contact_id', $contact_id );
602 - if ( $current && $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $this->table_name( 'wp_clients_contacts' ) . ' WHERE contact_client_id=%d AND contact_id = %d', $client_id, $contact_id ) ) ) {
603 - if ( ! empty( $current->contact_image ) ) {
604 - $dirs = MainWP_System_Utility::get_mainwp_dir( 'client-images', true );
605 - $base_dir = $dirs[0];
606 - $old_file = $base_dir . '/' . $current->contact_image;
607 - MainWP_Utility::delete_file( $old_file );
608 - }
609 - return true;
610 - }
611 - return false;
612 - }
613 618
619 + /**
620 + * Method delete_client_contacts_by_client_id.
621 + *
622 + * Delete client contacts by client id.
623 + *
624 + * @param int $client_id Client id.
625 + *
626 + * @return bool Results.
627 + */
628 + public function delete_client_contacts_by_client_id( $client_id ) {
614 629
615 - /**
616 - * Method delete_client_contacts_by_client_id.
617 - *
618 - * Delete client contacts by client id.
619 - *
620 - * @param int $client_id Client id.
621 - *
622 - * @return bool Results.
623 - */
624 - public function delete_client_contacts_by_client_id( $client_id ) {
630 + if ( empty( $client_id ) ) {
631 + return false;
632 + }
625 633
626 - if ( empty( $client_id ) ) {
627 - return false;
628 - }
634 + $client_contacts = $this->get_wp_client_contact_by( 'client_id', $client_id, ARRAY_A );
635 + if ( $client_contacts ) {
636 + foreach ( $client_contacts as $contact ) {
637 + $this->delete_client_contact( $client_id, $contact['contact_id'] );
638 + }
639 + }
640 + return true;
641 + }
629 642
630 - $client_contacts = $this->get_wp_client_contact_by( 'client_id', $client_id, ARRAY_A );
631 - if ( $client_contacts ) {
632 - foreach ( $client_contacts as $contact ) {
633 - $this->delete_client_contact( $client_id, $contact['contact_id'] );
634 - }
635 - }
636 - return true;
637 - }
638 643
644 + /**
645 + * Method get_wp_client_by.
646 + *
647 + * Get client by.
648 + *
649 + * @param string $by by.
650 + * @param mixed $value by value.
651 + * @param mixed $obj Format data.
652 + * @param array $params Others params. Supports:
653 + * - 'with_selected_sites' (bool) Include selected sites.
654 + * - 'with_tags' (bool) Include tags info.
655 + * - 'by_tags' (array) Filter by tag IDs.
656 + * - 'offset' (int) SQL offset for pagination.
657 + * - 'limit' (int) SQL limit for pagination.
658 + * - 'count_only' (bool) Return only count instead of results.
659 + *
660 + * @return mixed $result results.
661 + */
662 + public function get_wp_client_by( $by = 'client_id', $value = null, $obj = OBJECT, $params = array() ) { // phpcs:ignore -- NOSONAR - complexex function. Current complexity is the only way to achieve desired results, pull request solutions appreciated.
639 663
640 - /**
641 - * Method get_wp_client_by.
642 - *
643 - * Get client by.
644 - *
645 - * @param string $by by.
646 - * @param mixed $value by value.
647 - * @param mixed $obj Format data.
648 - * @param bool $params Others params.
649 - *
650 - * @return mixed $result results.
651 - */
652 - public function get_wp_client_by( $by = 'client_id', $value = null, $obj = OBJECT, $params = array() ) { // phpcs:ignore -- complexex function. Current complexity is the only way to achieve desired results, pull request solutions appreciated.
664 + $with_selected_sites = isset( $params['with_selected_sites'] ) && $params['with_selected_sites'] ? true : false;
665 + $with_tags = isset( $params['with_tags'] ) && $params['with_tags'] ? true : false;
666 + $group_ids = isset( $params['by_tags'] ) ? $params['by_tags'] : '';
667 + $count_only = isset( $params['count_only'] ) && $params['count_only'] ? true : false;
668 + $offset = isset( $params['offset'] ) ? intval( $params['offset'] ) : null;
669 + $limit = isset( $params['limit'] ) ? intval( $params['limit'] ) : null;
653 670
654 - $with_selected_sites = isset( $params['with_selected_sites'] ) && $params['with_selected_sites'] ? true : false;
655 - $with_tags = isset( $params['with_tags'] ) && $params['with_tags'] ? true : false;
656 - $group_ids = isset( $params['by_tags'] ) ? $params['by_tags'] : '';
671 + // valid group ids.
672 + if ( is_array( $group_ids ) ) {
673 + $group_ids = array_filter(
674 + $group_ids,
675 + function ( $e ) {
676 + if ( 'nogroups' === $e ) {
677 + return true;
678 + }
679 + return ( is_numeric( $e ) && 0 < $e ) ? true : false;
680 + }
681 + );
682 + } else {
683 + $group_ids = '';
684 + }
657 685
658 - // valid group ids.
659 - if ( is_array( $group_ids ) ) {
660 - $group_ids = array_filter(
661 - $group_ids,
662 - function ( $e ) {
663 - if ( 'nogroups' === $e ) {
664 - return true;
665 - }
666 - return ( is_numeric( $e ) && 0 < $e ) ? true : false;
667 - }
668 - );
669 - } else {
670 - $group_ids = '';
671 - }
686 + $select_sites = '';
687 + $select_tags = '';
688 + $where_clients = '';
672 689
673 - $select_sites = '';
674 - $select_tags = '';
675 - $where_clients = '';
690 + $sql = '';
676 691
677 - $sql = '';
692 + $table_wp = esc_sql( $this->table_name( 'wp' ) );
693 + $table_wp_group = esc_sql( $this->table_name( 'wp_group' ) );
694 + $table_group = esc_sql( $this->table_name( 'group' ) );
695 + $table_clients = esc_sql( $this->table_name( 'wp_clients' ) );
696 + $table_clients_contacts = esc_sql( $this->table_name( 'wp_clients_contacts' ) );
678 697
679 - if ( $with_selected_sites ) {
680 - $select_sites .= ',( SELECT GROUP_CONCAT(wp.id SEPARATOR ",") FROM ' . $this->table_name( 'wp' ) . ' wp WHERE wp.client_id = wc.client_id ) as selected_sites ';
681 - }
698 + if ( $with_selected_sites ) {
699 + $select_sites .= ',( SELECT GROUP_CONCAT(wp.id SEPARATOR ",") FROM ' . $table_wp . ' wp WHERE wp.client_id = wc.client_id ) as selected_sites ';
700 + }
682 701
683 - if ( ! empty( $group_ids ) ) {
702 + if ( ! empty( $group_ids ) ) {
684 703
685 - $join_group = '';
686 - $where_group = '';
704 + $join_group = '';
705 + $where_group = '';
687 706
688 - if ( in_array( 'nogroups', $group_ids ) ) {
689 - $join_group = ' LEFT JOIN ' . $this->table_name( 'wp_group' ) . ' wpgroup ON wp.id = wpgroup.wpid ';
690 - $group_ids = array_filter(
691 - $group_ids,
692 - function ( $e ) {
693 - return 'nogroups' !== $e;
694 - }
695 - );
696 - if ( 0 < count( $group_ids ) ) {
697 - $groups = implode( ',', $group_ids );
698 - $where_group = ' AND ( wpgroup.groupid IS NULL OR wpgroup.groupid IN (' . $groups . ') ) ';
699 - } else {
700 - $where_group = ' AND wpgroup.groupid IS NULL ';
701 - }
702 - } else {
703 - $groups = implode( ',', $group_ids );
704 - $join_group = ' JOIN ' . $this->table_name( 'wp_group' ) . ' wpgroup ON wp.id = wpgroup.wpid ';
705 - $where_group = ' AND wpgroup.groupid IN (' . $groups . ') ';
706 - }
707 + if ( in_array( 'nogroups', $group_ids ) ) {
708 + $join_group = ' LEFT JOIN ' . $table_wp_group . ' wpgroup ON wp.id = wpgroup.wpid ';
709 + $group_ids = array_filter(
710 + $group_ids,
711 + function ( $e ) {
712 + return 'nogroups' !== $e;
713 + }
714 + );
715 + if ( ! empty( $group_ids ) ) {
716 + $groups = implode( ',', array_map( 'intval', $group_ids ) );
717 + $where_group = ' AND ( wpgroup.groupid IS NULL OR wpgroup.groupid IN (' . $groups . ') ) ';
718 + } else {
719 + $where_group = ' AND wpgroup.groupid IS NULL ';
720 + }
721 + } else {
722 + $groups = implode( ',', array_map( 'intval', $group_ids ) );
723 + $join_group = ' JOIN ' . $table_wp_group . ' wpgroup ON wp.id = wpgroup.wpid ';
724 + $where_group = ' AND wpgroup.groupid IN (' . $groups . ') ';
725 + }
707 726
708 - $sql_tags = ' SELECT wp.client_id FROM ' . $this->table_name( 'wp' ) . ' wp ';
709 - $sql_tags .= $join_group;
710 - $sql_tags .= ' WHERE 1 ' . $where_group;
711 - $result_tags = $this->wpdb->get_results( $sql_tags );
727 + $sql_tags = ' SELECT wp.client_id FROM ' . $table_wp . ' wp ';
728 + $sql_tags .= $join_group;
729 + $sql_tags .= ' WHERE 1 ' . $where_group;
730 + $result_tags = $this->wpdb->get_results( $sql_tags ); // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $sql_tags built with escaped table names and validated numeric IDs, safe to use directly.
712 731
713 - if ( empty( $result_tags ) ) {
714 - return array();
715 - } else {
716 - $cli_ids = array();
717 - foreach ( $result_tags as $item ) {
718 - $cli_ids[] = $item->client_id;
719 - }
720 - $cli_ids = array_values( array_unique( $cli_ids ) );
721 - $where_clients = ' AND wc.client_id IN (' . implode( ',', $cli_ids ) . ') ';
722 - }
723 - }
732 + if ( empty( $result_tags ) ) {
733 + return $count_only ? 0 : array();
734 + } else {
735 + $cli_ids = array();
736 + foreach ( $result_tags as $item ) {
737 + $cli_ids[] = (int) $item->client_id;
738 + }
739 + $cli_ids = array_values( array_unique( $cli_ids ) );
740 + $where_clients = ' AND wc.client_id IN (' . implode( ',', $cli_ids ) . ') ';
741 + }
742 + }
724 743
725 - if ( $with_tags ) {
726 - $select_tags .= ", ( SELECT GROUP_CONCAT(gr.name ORDER BY gr.name SEPARATOR ',') FROM " . $this->table_name( 'wp' ) . ' wp ';
727 - $select_tags .= ' LEFT JOIN ' . $this->table_name( 'wp_group' ) . ' wpgr ON wp.id = wpgr.wpid ';
728 - $select_tags .= ' LEFT JOIN ' . $this->table_name( 'group' ) . ' gr ON wpgr.groupid = gr.id ';
729 - $select_tags .= ' WHERE wp.client_id = wc.client_id ) as wpgroups ';
744 + if ( $with_tags ) {
745 + $select_tags .= ", ( SELECT GROUP_CONCAT(gr.name ORDER BY gr.name SEPARATOR ',') FROM " . $table_wp . ' wp ';
746 + $select_tags .= ' LEFT JOIN ' . $table_wp_group . ' wpgr ON wp.id = wpgr.wpid ';
747 + $select_tags .= ' LEFT JOIN ' . $table_group . ' gr ON wpgr.groupid = gr.id ';
748 + $select_tags .= ' WHERE wp.client_id = wc.client_id ) as wpgroups ';
730 749
731 - $select_tags .= ", ( SELECT GROUP_CONCAT(gr.id ORDER BY gr.id SEPARATOR ',') FROM " . $this->table_name( 'wp' ) . ' wp ';
732 - $select_tags .= ' LEFT JOIN ' . $this->table_name( 'wp_group' ) . ' wpgr ON wp.id = wpgr.wpid ';
733 - $select_tags .= ' LEFT JOIN ' . $this->table_name( 'group' ) . ' gr ON wpgr.groupid = gr.id ';
734 - $select_tags .= ' WHERE wp.client_id = wc.client_id ) as wpgroupids ';
735 - }
750 + $select_tags .= ", ( SELECT GROUP_CONCAT(gr.id ORDER BY gr.id SEPARATOR ',') FROM " . $table_wp . ' wp ';
751 + $select_tags .= ' LEFT JOIN ' . $table_wp_group . ' wpgr ON wp.id = wpgr.wpid ';
752 + $select_tags .= ' LEFT JOIN ' . $table_group . ' gr ON wpgr.groupid = gr.id ';
753 + $select_tags .= ' WHERE wp.client_id = wc.client_id ) as wpgroupids ';
754 + }
736 755
737 - $join_contact = ' LEFT JOIN ' . $this->table_name( 'wp_clients_contacts' ) . ' cc ON wc.primary_contact_id = cc.contact_id ';
756 + $join_contact = ' LEFT JOIN ' . $table_clients_contacts . ' cc ON wc.primary_contact_id = cc.contact_id ';
738 757
739 - if ( 'all' === $by ) {
740 - $sql = ' SELECT wc.*, cc.* ' . $select_sites . $select_tags;
741 - $sql .= ' FROM ' . $this->table_name( 'wp_clients' ) . ' wc ';
742 - $sql .= $join_contact;
743 - $sql .= ' WHERE 1 ' . $where_clients;
744 - $sql .= ' ORDER BY wc.name';
745 - }
758 + if ( 'all' === $by ) {
759 + // Handle count-only mode for efficient pagination total.
760 + if ( $count_only ) {
761 + $sql = ' SELECT COUNT(*) ';
762 + $sql .= ' FROM ' . esc_sql( $this->table_name( 'wp_clients' ) ) . ' wc ';
763 + $sql .= ' WHERE 1 ' . $where_clients;
764 + return (int) $this->wpdb->get_var( $sql ); // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $sql uses wpdb->prepare() or escaped table name concatenation, safe to use directly.
765 + }
746 766
747 - if ( ! empty( $sql ) ) {
748 - if ( OBJECT === $obj ) {
749 - $result = $this->wpdb->get_results( $sql, OBJECT );
750 - } else {
751 - $result = $this->wpdb->get_results( $sql, ARRAY_A );
752 - }
753 - return $result;
754 - }
767 + $sql = ' SELECT wc.*, cc.* ' . $select_sites . $select_tags;
768 + $sql .= ' FROM ' . esc_sql( $this->table_name( 'wp_clients' ) ) . ' wc ';
769 + $sql .= $join_contact;
770 + $sql .= ' WHERE 1 ' . $where_clients;
771 + $sql .= ' ORDER BY wc.name';
755 772
756 - if ( 'client_id' === $by && is_numeric( $value ) ) {
757 - $sql = $this->wpdb->prepare( 'SELECT wc.*, cc.* ' . $select_sites . $select_tags . ' FROM ' . $this->table_name( 'wp_clients' ) . ' wc ' . $join_contact . ' WHERE wc.client_id=%d ', $value );
758 - } elseif ( 'client_email' === $by && ! empty( $value ) ) {
759 - $sql = $this->wpdb->prepare( 'SELECT wc.*, cc.* ' . $select_sites . $select_tags . ' FROM ' . $this->table_name( 'wp_clients' ) . ' wc ' . $join_contact . ' WHERE wc.client_email=%s ', $value );
760 - }
773 + // Add pagination if offset and limit are provided.
774 + if ( null !== $offset && null !== $limit && $limit > 0 ) {
775 + $sql .= $this->wpdb->prepare( ' LIMIT %d, %d', $offset, $limit );
776 + }
777 + }
761 778
762 - $result = null;
763 - if ( ! empty( $sql ) ) {
764 - if ( OBJECT === $obj ) {
765 - $result = $this->wpdb->get_row( $sql, OBJECT );
766 - } else {
767 - $result = $this->wpdb->get_row( $sql, ARRAY_A );
768 - }
769 - }
770 - return $result;
771 - }
779 + if ( ! empty( $sql ) ) {
780 + if ( OBJECT === $obj ) {
781 + $result = $this->wpdb->get_results( $sql, OBJECT ); // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $sql uses wpdb->prepare() or escaped table name concatenation, safe to use directly.
782 + } else {
783 + $result = $this->wpdb->get_results( $sql, ARRAY_A ); // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $sql uses wpdb->prepare() or escaped table name concatenation, safe to use directly.
784 + }
785 + return $result;
786 + }
772 787
773 - /**
774 - * Method get_wp_clients.
775 - *
776 - * Get clients.
777 - *
778 - * @param array $params params.
779 - *
780 - * @return mixed result.
781 - */
782 - public function get_wp_clients( $params = array() ) {
788 + if ( 'client_id' === $by && is_numeric( $value ) ) {
789 + $sql = $this->wpdb->prepare( 'SELECT wc.*, cc.* ' . $select_sites . $select_tags . ' FROM ' . $table_clients . ' wc ' . $join_contact . ' WHERE wc.client_id=%d ', $value );
790 + } elseif ( 'client_email' === $by && ! empty( $value ) ) {
791 + $sql = $this->wpdb->prepare( 'SELECT wc.*, cc.* ' . $select_sites . $select_tags . ' FROM ' . $table_clients . ' wc ' . $join_contact . ' WHERE wc.client_email=%s ', $value );
792 + }
783 793
784 - $custom_field = false;
785 - $with_tags = false;
786 - $with_contacts = false;
794 + $result = null;
795 + if ( ! empty( $sql ) ) {
796 + if ( OBJECT === $obj ) {
797 + $result = $this->wpdb->get_row( $sql, OBJECT ); // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $sql uses wpdb->prepare() or escaped table name concatenation, safe to use directly.
798 + } else {
799 + $result = $this->wpdb->get_row( $sql, ARRAY_A ); // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $sql uses wpdb->prepare() or escaped table name concatenation, safe to use directly.
800 + }
801 + }
802 + return $result;
803 + }
787 804
788 - $where = '';
789 - $select_tags = '';
805 + /**
806 + * Method get_wp_clients.
807 + *
808 + * Get clients.
809 + *
810 + * @param array $params params.
811 + *
812 + * @return mixed result.
813 + */
814 + public function get_wp_clients( $params = array() ) { // phpcs:ignore -- NOSONAR - complex.
790 815
791 - if ( $params && is_array( $params ) ) {
792 - $client = isset( $params['client'] ) ? sanitize_text_field( wp_unslash( $params['client'] ) ) : '';
793 - if ( '' !== $client ) {
794 - $clients = explode( ';', $client );
795 - $clientWhere = '';
796 - foreach ( $clients as $clt ) {
797 - if ( is_numeric( $clt ) ) {
798 - $clientWhere .= intval( $clt ) . ', ';
799 - }
800 - }
801 - $clientWhere = rtrim( $clientWhere, ', ' );
816 + $custom_field = false;
817 + $with_tags = false;
818 + $with_contacts = false;
819 + $count_only = false;
802 820
803 - $where .= ' AND wc.client_id IN (' . $clientWhere . ') ';
804 - }
805 - $custom_field = $params['custom_fields'] && $params['custom_fields'] ? true : false;
821 + $s = '';
822 + $exclude = array();
823 + $include = array();
824 + $limit = '';
806 825
807 - $with_tags = isset( $params['with_tags'] ) && $params['with_tags'] ? true : false;
808 - $with_contacts = isset( $params['with_contacts'] ) && $params['with_contacts'] ? true : false;
809 - }
826 + $where = '';
827 + $select_tags = '';
810 828
811 - if ( $with_tags ) {
812 - $select_tags .= ", ( SELECT GROUP_CONCAT(gr.name ORDER BY gr.name SEPARATOR ',') FROM " . $this->table_name( 'wp' ) . ' wp ';
813 - $select_tags .= ' LEFT JOIN ' . $this->table_name( 'wp_group' ) . ' wpgr ON wp.id = wpgr.wpid ';
814 - $select_tags .= ' LEFT JOIN ' . $this->table_name( 'group' ) . ' gr ON wpgr.groupid = gr.id ';
815 - $select_tags .= ' WHERE wp.client_id = wc.client_id ) as wpgroups ';
829 + $table_wp = esc_sql( $this->table_name( 'wp' ) );
830 + $table_wp_group = esc_sql( $this->table_name( 'wp_group' ) );
831 + $table_group = esc_sql( $this->table_name( 'group' ) );
832 + $table_clients = esc_sql( $this->table_name( 'wp_clients' ) );
816 833
817 - $select_tags .= ", ( SELECT GROUP_CONCAT(gr.id ORDER BY gr.id SEPARATOR ',') FROM " . $this->table_name( 'wp' ) . ' wp ';
818 - $select_tags .= ' LEFT JOIN ' . $this->table_name( 'wp_group' ) . ' wpgr ON wp.id = wpgr.wpid ';
819 - $select_tags .= ' LEFT JOIN ' . $this->table_name( 'group' ) . ' gr ON wpgr.groupid = gr.id ';
820 - $select_tags .= ' WHERE wp.client_id = wc.client_id ) as wpgroupids ';
821 - }
834 + if ( $params && is_array( $params ) ) {
835 + $client = isset( $params['client'] ) ? sanitize_text_field( wp_unslash( $params['client'] ) ) : '';
836 + if ( '' !== $client ) {
837 + $clients = preg_split( '/[;,]/', $client );
838 + $clients = array_filter( array_map( 'trim', $clients ) );
822 839
823 - $sql = ' SELECT wc.* ';
824 - $sql .= ',( SELECT GROUP_CONCAT(wp.id SEPARATOR ",") FROM ' . $this->table_name( 'wp' ) . ' wp WHERE wp.client_id = wc.client_id ) as selected_sites ' . $select_tags;
825 - $sql .= ' FROM ' . $this->table_name( 'wp_clients' ) . ' wc ';
826 - $sql .= ' WHERE 1 ' . $where . ' ORDER BY wc.name';
840 + $clientWhere = '';
841 + foreach ( $clients as $clt ) {
842 + if ( is_numeric( $clt ) ) {
843 + $clientWhere .= intval( $clt ) . ', ';
844 + }
845 + }
846 + $clientWhere = rtrim( $clientWhere, ', ' );
827 847
828 - $result = $this->wpdb->get_results( $sql, ARRAY_A );
848 + $where .= ' AND wc.client_id IN (' . $clientWhere . ') ';
849 + }
850 + $custom_field = isset( $params['custom_fields'] ) && $params['custom_fields'] ? true : false;
829 851
830 - $contact_fields = array(
831 - 'contact_id',
832 - 'contact_client_id',
833 - 'contact_email',
834 - 'contact_name',
835 - 'contact_phone',
836 - 'contact_role',
837 - 'contact_image',
838 - 'facebook',
839 - 'twitter',
840 - 'instagram',
841 - 'linkedin',
842 - );
852 + $with_tags = isset( $params['with_tags'] ) && $params['with_tags'] ? true : false;
853 + $with_contacts = isset( $params['with_contacts'] ) && $params['with_contacts'] ? true : false;
854 + $count_only = isset( $params['count_only'] ) && $params['count_only'] ? true : false;
843 855
844 - $output = array();
856 + $s = isset( $params['s'] ) ? $params['s'] : '';
857 + $exclude = isset( $params['exclude'] ) && ! empty( $params['exclude'] ) ? wp_parse_id_list( $params['exclude'] ) : array();
858 + $include = isset( $params['include'] ) && ! empty( $params['include'] ) ? wp_parse_id_list( $params['include'] ) : array();
859 + $status = isset( $params['status'] ) && ! empty( $params['status'] ) ? wp_parse_list( $params['status'] ) : array();
860 + $page = isset( $params['page'] ) ? intval( $params['page'] ) : false;
861 + $per_page = isset( $params['per_page'] ) ? intval( $params['per_page'] ) : false;
845 862
846 - foreach ( $result as $rst ) {
863 + if ( ! empty( $s ) ) {
864 + $s = trim( $s );
865 + // Use esc_like() to escape LIKE wildcards (%, _) then prepare() for SQL safety.
866 + $like = '%' . $this->wpdb->esc_like( $s ) . '%';
867 + $where .= $this->wpdb->prepare(
868 + ' AND ( wc.client_id LIKE %s OR wc.name LIKE %s OR wc.client_email LIKE %s ) ',
869 + $like,
870 + $like,
871 + $like
872 + );
873 + }
847 874
848 - if ( $custom_field ) {
849 - $custom_fields = $this->get_client_fields( true, $rst['client_id'] );
850 - if ( $custom_fields ) {
851 - foreach ( $custom_fields as $field ) {
852 - $rst[ $field->field_name ] = $field->field_value;
853 - }
854 - }
855 - }
856 - if ( $with_tags && ! empty( $rst['wpgroupids'] ) && ! empty( $rst['wpgroups'] ) ) {
857 - $wpgroupids = explode( ',', $rst['wpgroupids'] );
858 - $wpgroups = explode( ',', $rst['wpgroups'] );
875 + if ( ! empty( $exclude ) ) {
876 + $where .= ' AND wc.client_id NOT IN (' . implode( ',', $exclude ) . ') ';
877 + }
859 878
860 - $tags = array();
861 - if ( is_array( $wpgroupids ) ) {
862 - foreach ( $wpgroupids as $gidx => $groupid ) {
863 - if ( $groupid && ! isset( $tags[ $groupid ] ) ) {
864 - $tags[ $groupid ] = isset( $wpgroups[ $gidx ] ) ? $wpgroups[ $gidx ] : '';
865 - }
866 - }
867 - }
879 + if ( ! empty( $include ) ) {
880 + $where .= ' AND wc.client_id IN (' . implode( ',', $include ) . ') ';
881 + }
868 882
869 - $rst['tags'] = $tags;
870 - }
883 + if ( ! empty( $status ) ) {
884 + $suspended_status = array_map(
885 + function ( $value ) {
886 + $map_status_db = array(
887 + 'active' => 0,
888 + 'suspended' => 1,
889 + 'lead' => 2,
890 + 'lost' => 3,
891 + );
892 + return isset( $map_status_db[ $value ] ) ? $map_status_db[ $value ] : '';
893 + },
894 + $status
895 + );
896 + $suspended_status = array_filter(
897 + $suspended_status,
898 + function ( $value ) {
899 + return '' !== $value;
900 + }
901 + );
902 + if ( ! empty( $suspended_status ) ) {
903 + $where .= ' AND wc.suspended IN (' . implode( ',', $suspended_status ) . ') ';
904 + }
905 + }
871 906
872 - if ( $with_contacts ) {
873 - $client_contacts = $this->get_wp_client_contact_by( 'client_id', $rst['client_id'], ARRAY_A );
907 + if ( ! empty( $page ) && ! empty( $per_page ) ) {
908 + $limit = ' LIMIT ' . ( $page - 1 ) * $per_page . ',' . $per_page;
909 + }
910 + }
874 911
875 - $contacts = array();
912 + if ( $with_tags ) {
913 + $select_tags .= ", ( SELECT GROUP_CONCAT(gr.name ORDER BY gr.name SEPARATOR ',') FROM " . $table_wp . ' wp ';
914 + $select_tags .= ' LEFT JOIN ' . $table_wp_group . ' wpgr ON wp.id = wpgr.wpid ';
915 + $select_tags .= ' LEFT JOIN ' . $table_group . ' gr ON wpgr.groupid = gr.id ';
916 + $select_tags .= ' WHERE wp.client_id = wc.client_id ) as wpgroups ';
876 917
877 - if ( is_array( $client_contacts ) ) {
878 - foreach ( $client_contacts as $gidx => $contact ) {
879 - $contacts[ $contact['contact_id'] ] = MainWP_Utility::map_fields( $contact, $contact_fields, false );
880 - }
881 - }
882 - $rst['contacts'] = $contacts;
883 - }
918 + $select_tags .= ", ( SELECT GROUP_CONCAT(gr.id ORDER BY gr.id SEPARATOR ',') FROM " . $table_wp . ' wp ';
919 + $select_tags .= ' LEFT JOIN ' . $table_wp_group . ' wpgr ON wp.id = wpgr.wpid ';
920 + $select_tags .= ' LEFT JOIN ' . $table_group . ' gr ON wpgr.groupid = gr.id ';
921 + $select_tags .= ' WHERE wp.client_id = wc.client_id ) as wpgroupids ';
922 + }
884 923
885 - $output[] = $rst;
886 - }
887 - return $output;
888 - }
924 + if ( $count_only ) {
925 + $sql = ' SELECT count(*) ';
926 + $sql .= ' FROM ' . $table_clients . ' wc ';
927 + $sql .= ' WHERE 1 ' . $where;
928 + return $this->wpdb->get_var( $sql ); // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $sql built with escaped table names, safe to use directly.
929 + } else {
930 + $sql = ' SELECT wc.* ';
931 + $sql .= ',( SELECT GROUP_CONCAT(wp.id SEPARATOR ",") FROM ' . $table_wp . ' wp WHERE wp.client_id = wc.client_id ) as selected_sites ' . $select_tags;
932 + $sql .= ' FROM ' . $table_clients . ' wc ';
933 + $sql .= ' WHERE 1 ' . $where . ' ORDER BY wc.name ' . $limit;
934 + }
889 935
890 - /**
891 - * Method update_selected_sites_for_client.
892 - *
893 - * Update client.
894 - *
895 - * @param int $client_id client id.
896 - * @param array $site_ids site ids.
897 - *
898 - * @return bool true|false.
899 - */
900 - public function update_selected_sites_for_client( $client_id, $site_ids ) {
901 - if ( empty( $client_id ) ) {
902 - return false;
903 - }
936 + $result = $this->wpdb->get_results( $sql, ARRAY_A ); // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $sql built with escaped table names, safe to use directly.
904 937
905 - $site_ids = array_filter(
906 - $site_ids,
907 - function ( $e ) {
908 - return ( is_numeric( $e ) && 0 < $e ) ? true : false;
909 - }
910 - );
938 + $contact_fields = array(
939 + 'contact_id',
940 + 'contact_client_id',
941 + 'contact_email',
942 + 'contact_name',
943 + 'contact_phone',
944 + 'contact_role',
945 + 'contact_image',
946 + 'facebook',
947 + 'twitter',
948 + 'instagram',
949 + 'linkedin',
950 + );
911 951
912 - if ( is_array( $site_ids ) && count( $site_ids ) > 0 ) {
913 - $this->wpdb->query( $this->wpdb->prepare( 'UPDATE ' . $this->table_name( 'wp' ) . ' SET client_id=0 WHERE client_id=%d AND id NOT IN (' . implode( ',', $site_ids ) . ')', $client_id ) );
914 - $this->wpdb->query( $this->wpdb->prepare( 'UPDATE ' . $this->table_name( 'wp' ) . ' SET client_id=%d WHERE id IN (' . implode( ',', $site_ids ) . ')', $client_id ) );
915 - return true;
916 - } else {
917 - $this->wpdb->query( $this->wpdb->prepare( 'UPDATE ' . $this->table_name( 'wp' ) . ' SET client_id=0 WHERE client_id=%d ', $client_id ) );
918 - return true;
919 - }
920 - return false;
921 - }
952 + $output = array();
922 953
923 - /**
924 - * Method delete_client.
925 - *
926 - * Delete client.
927 - *
928 - * @param int $client_id Client id to delete.
929 - * @return bool Results.
930 - */
931 - public function delete_client( $client_id ) {
954 + foreach ( $result as $rst ) {
932 955
933 - $current = $this->get_wp_client_by( 'client_id', $client_id );
934 - if ( $current && $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $this->table_name( 'wp_clients' ) . ' WHERE client_id=%d ', $client_id ) ) ) {
935 - $this->wpdb->query( $this->wpdb->prepare( 'UPDATE ' . $this->table_name( 'wp' ) . ' SET client_id=0 WHERE client_id=%d ', $client_id ) );
936 - $fields = $this->get_client_fields_by( 'client_id', $client_id );
937 - if ( $fields ) {
938 - foreach ( $fields as $field ) {
939 - $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $this->table_name( 'wp_clients_fields' ) . ' WHERE field_id=%d ', $field->field_id ) );
940 - $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $this->table_name( 'wp_clients_field_values' ) . ' WHERE field_id=%d AND value_client_id=%d ', $field->field_id, $client_id ) );
941 - }
942 - }
956 + if ( $custom_field ) {
957 + $custom_fields = $this->get_client_fields( true, $rst['client_id'] );
958 + if ( $custom_fields ) {
959 + foreach ( $custom_fields as $field ) {
960 + $rst[ $field->field_name ] = $field->field_value;
961 + }
962 + }
963 + }
964 + if ( $with_tags && ! empty( $rst['wpgroupids'] ) && ! empty( $rst['wpgroups'] ) ) {
965 + $wpgroupids = explode( ',', $rst['wpgroupids'] );
966 + $wpgroups = explode( ',', $rst['wpgroups'] );
943 967
944 - if ( ! empty( $current->image ) ) {
945 - $dirs = MainWP_System_Utility::get_mainwp_dir( 'client-images', true );
946 - $base_dir = $dirs[0];
947 - $old_file = $base_dir . '/' . $current->image;
948 - MainWP_Utility::delete_file( $old_file );
949 - }
968 + $tags = array();
969 + if ( is_array( $wpgroupids ) ) {
970 + foreach ( $wpgroupids as $gidx => $groupid ) {
971 + if ( $groupid && ! isset( $tags[ $groupid ] ) ) {
972 + $tags[ $groupid ] = isset( $wpgroups[ $gidx ] ) ? $wpgroups[ $gidx ] : '';
973 + }
974 + }
975 + }
950 976
951 - $this->delete_client_contacts_by_client_id( $client_id );
977 + $rst['tags'] = $tags;
978 + }
952 979
953 - /**
954 - * Delete client
955 - *
956 - * Fires after delete a client.
957 - *
958 - * @param object $current client deleted.
959 - *
960 - * @since 4.5.1.1
961 - */
962 - do_action( 'mainwp_client_deleted', $current );
980 + if ( $with_contacts ) {
981 + $client_contacts = $this->get_wp_client_contact_by( 'client_id', $rst['client_id'], ARRAY_A );
963 982
964 - return true;
965 - }
966 - return false;
967 - }
983 + $contacts = array();
968 984
969 - /**
970 - * Method get_websites_by_client_ids.
971 - *
972 - * Get websites by client.
973 - *
974 - * @param int $client_ids Client ids.
975 - * @param array $params other params.
976 - *
977 - * @return mixed $result Results.
978 - */
979 - public function get_websites_by_client_ids( $client_ids, $params = array() ) {
985 + if ( is_array( $client_contacts ) ) {
986 + foreach ( $client_contacts as $gidx => $contact ) {
987 + $contacts[ $contact['contact_id'] ] = MainWP_Utility::map_fields( $contact, $contact_fields, false );
988 + }
989 + }
990 + $rst['contacts'] = $contacts;
991 + }
980 992
981 - if ( empty( $client_ids ) ) {
982 - return false;
983 - }
993 + $output[] = $rst;
994 + }
995 + return $output;
996 + }
984 997
985 - if ( ! is_array( $params ) ) {
986 - $params = array();
987 - }
998 + /**
999 + * Method update_selected_sites_for_client.
1000 + *
1001 + * Update client.
1002 + *
1003 + * @param int $client_id client id.
1004 + * @param array $site_ids site ids.
1005 + *
1006 + * @return bool true|false.
1007 + */
1008 + public function update_selected_sites_for_client( $client_id, $site_ids ) {
1009 + if ( empty( $client_id ) ) {
1010 + return false;
1011 + }
988 1012
989 - $client = '';
990 - if ( is_array( $client_ids ) ) {
991 - // valid client ids.
992 - $client_ids = array_filter(
993 - $client_ids,
994 - function ( $e ) {
995 - return is_numeric( $e ) && ! empty( $e ) ? true : false; // to valid client ids.
996 - }
997 - );
998 - $client = implode( ';', $client_ids );
999 - } else {
1000 - $client = $client_ids;
1001 - }
1013 + $site_ids = array_filter(
1014 + $site_ids,
1015 + function ( $e ) {
1016 + return ( is_numeric( $e ) && 0 < $e ) ? true : false;
1017 + }
1018 + );
1002 1019
1003 - $params['client'] = $client;
1020 + $table_wp = esc_sql( $this->table_name( 'wp' ) );
1004 1021
1005 - return MainWP_DB::instance()->get_websites_for_current_user( $params );
1006 - }
1022 + if ( is_array( $site_ids ) && ! empty( $site_ids ) ) {
1023 + $safe_site_ids = implode( ',', array_map( 'intval', $site_ids ) );
1024 + $this->wpdb->query( $this->wpdb->prepare( 'UPDATE ' . $table_wp . ' SET client_id=0 WHERE client_id=%d AND id NOT IN (' . $safe_site_ids . ')', $client_id ) );
1025 + $this->wpdb->query( $this->wpdb->prepare( 'UPDATE ' . $table_wp . ' SET client_id=%d WHERE id IN (' . $safe_site_ids . ')', $client_id ) );
1026 + return true;
1027 + } else {
1028 + $this->wpdb->query( $this->wpdb->prepare( 'UPDATE ' . $table_wp . ' SET client_id=0 WHERE client_id=%d ', $client_id ) );
1029 + return true;
1030 + }
1031 + }
1007 1032
1008 - /**
1009 - * Method get_number_sites_of_client.
1010 - *
1011 - * Get client by.
1012 - *
1013 - * @param int $client_id Client id.
1014 - *
1015 - * @return int Number of sites.
1016 - */
1017 - public function get_number_sites_of_client( $client_id ) {
1018 - if ( empty( $client_id ) ) {
1019 - return false;
1020 - }
1021 - return $this->wpdb->get_var( $this->wpdb->prepare( 'SELECT COUNT(wp.id) FROM ' . $this->table_name( 'wp' ) . ' wp WHERE wp.client_id =%d', $client_id ) );
1022 - }
1033 + /**
1034 + * Method delete_client.
1035 + *
1036 + * Delete client.
1037 + *
1038 + * @param int $client_id Client id to delete.
1039 + * @return bool Results.
1040 + */
1041 + public function delete_client( $client_id ) {
1023 1042
1024 - /**
1025 - * Method count_total_clients.
1026 - *
1027 - * Count total of Clients.
1028 - *
1029 - * @return int Total number.
1030 - */
1031 - public function count_total_clients() {
1032 - return $this->wpdb->get_var( 'SELECT COUNT(client_id) FROM ' . $this->table_name( 'wp_clients' ) );
1033 - }
1043 + $current = $this->get_wp_client_by( 'client_id', $client_id );
1044 + $table_clients = esc_sql( $this->table_name( 'wp_clients' ) );
1045 + $table_wp = esc_sql( $this->table_name( 'wp' ) );
1046 + $table_fields = esc_sql( $this->table_name( 'wp_clients_fields' ) );
1047 + $table_field_values = esc_sql( $this->table_name( 'wp_clients_field_values' ) );
1034 1048
1049 + if ( $current && $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $table_clients . ' WHERE client_id=%d ', $client_id ) ) ) {
1050 + $this->wpdb->query( $this->wpdb->prepare( 'UPDATE ' . $table_wp . ' SET client_id=0 WHERE client_id=%d ', $client_id ) );
1051 + $fields = $this->get_client_fields_by( 'client_id', $client_id );
1052 + if ( $fields ) {
1053 + foreach ( $fields as $field ) {
1054 + $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $table_fields . ' WHERE field_id=%d ', $field->field_id ) );
1055 + $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $table_field_values . ' WHERE field_id=%d AND value_client_id=%d ', $field->field_id, $client_id ) );
1056 + }
1057 + }
1035 1058
1036 - /**
1037 - * Method add_client_field.
1038 - *
1039 - * Add client field.
1040 - *
1041 - * @param mixed $field Client fields data.
1042 - *
1043 - * @return mixed bool|results.
1044 - */
1045 - public function add_client_field( $field ) {
1046 - if ( ! empty( $field['field_name'] ) && isset( $field['client_id'] ) ) {
1047 - if ( $this->get_client_fields_by( 'field_name', $field['field_name'], $field['client_id'] ) ) { // field name existed for the client can not create.
1048 - return false;
1049 - }
1050 - if ( $this->wpdb->insert( $this->table_name( 'wp_clients_fields' ), $field ) ) {
1051 - return $this->get_client_fields_by( 'field_id', $this->wpdb->insert_id );
1052 - }
1053 - }
1054 - return false;
1055 - }
1059 + if ( ! empty( $current->image ) ) {
1060 + $dirs = MainWP_System_Utility::get_mainwp_dir( 'client-images', true );
1061 + $base_dir = $dirs[0];
1062 + $old_file = $base_dir . '/' . $current->image;
1063 + MainWP_Utility::delete_file( $old_file );
1064 + }
1056 1065
1057 - /**
1058 - * Method update_client_field.
1059 - *
1060 - * Update client field.
1061 - *
1062 - * @param int $field_id field id.
1063 - * @param array $field field data.
1064 - *
1065 - * @return mixed|false field.
1066 - */
1067 - public function update_client_field( $field_id, $field ) {
1068 - if ( $field_id && ! empty( $field['field_name'] ) ) {
1069 - $current = $this->get_client_fields_by( 'field_id', $field_id );
1070 - if ( $current ) {
1071 - if ( $this->wpdb->update( $this->table_name( 'wp_clients_fields' ), $field, array( 'field_id' => $field_id ) ) ) {
1072 - return $this->get_client_fields_by( 'field_id', $current->field_id );
1073 - }
1074 - }
1075 - }
1076 - return false;
1077 - }
1066 + $this->delete_client_contacts_by_client_id( $client_id );
1078 1067
1079 - /**
1080 - * Method update_client_field_value.
1081 - *
1082 - * Update client field value.
1083 - *
1084 - * @param int $field_id field id.
1085 - * @param mixed $value field value.
1086 - * @param int $client_id client id.
1087 - *
1088 - * @return mixed|false field data.
1089 - */
1090 - public function update_client_field_value( $field_id, $value, $client_id ) {
1091 - if ( ! empty( $field_id ) ) {
1092 - $row = $this->wpdb->get_row( $this->wpdb->prepare( 'SELECT * FROM ' . $this->table_name( 'wp_clients_field_values' ) . ' WHERE field_id = %d AND value_client_id=%d ', $field_id, $client_id ) );
1093 - if ( $row ) {
1094 - if ( $row->field_value != $value ) { //phpcs:ignore -- to valid.
1095 - $this->wpdb->update( $this->table_name( 'wp_clients_field_values' ), array( 'field_value' => $value ), array( 'value_id' => $row->value_id ) );
1096 - }
1097 - return true;
1098 - } else {
1099 - return $this->wpdb->insert(
1100 - $this->table_name( 'wp_clients_field_values' ),
1101 - array(
1102 - 'field_id' => $field_id,
1103 - 'field_value' => $value,
1104 - 'value_client_id' => $client_id,
1105 - )
1106 - );
1107 - }
1108 - }
1109 - return false;
1110 - }
1068 + $snapshot_info = $this->get_clients_snapshot_info();
1111 1069
1112 - /**
1113 - * Method get_client_fields_by.
1114 - *
1115 - * Get client field.
1116 - *
1117 - * @param string $by by.
1118 - * @param mixed $value field value.
1119 - * @param int $client_id client id.
1120 - *
1121 - * @return mixed|null $field field data.
1122 - */
1123 - public function get_client_fields_by( $by = 'field_id', $value = null, $client_id = 0 ) {
1070 + /**
1071 + * Delete client
1072 + *
1073 + * Fires after delete a client.
1074 + *
1075 + * @param object $current client deleted.
1076 + *
1077 + * @since 4.5.1.1
1078 + *
1079 + * @since 6.0 Added $snapshot_info parameter.
1080 + */
1081 + do_action( 'mainwp_client_deleted', $current, $snapshot_info );
1124 1082
1125 - if ( empty( $by ) || empty( $value ) ) {
1126 - return null;
1127 - }
1083 + return true;
1084 + }
1085 + return false;
1086 + }
1128 1087
1129 - $sql = '';
1130 1088
1131 - if ( 'client_id' === $by ) {
1132 - $sql = $this->wpdb->prepare( 'SELECT * FROM ' . $this->table_name( 'wp_clients_fields' ) . ' WHERE `client_id`=%d ', $value );
1133 - return $this->wpdb->get_results( $sql );
1134 - }
1089 + /**
1090 + * Get clients snapshot info.
1091 + *
1092 + * @return array
1093 + */
1094 + public function get_clients_snapshot_info() {
1135 1095
1136 - if ( 'field_name' === $by ) {
1137 - $value = str_replace( array( '[', ']' ), '', $value );
1138 - }
1096 + $total_clients = $this->get_wp_clients( array( 'count_only' => true ) );
1097 + $total_active_clients = $this->get_wp_clients(
1098 + array(
1099 + 'status' => '0',
1100 + 'count_only' => true,
1101 + )
1102 + );
1103 + $total_suspended = $this->get_wp_clients(
1104 + array(
1105 + 'status' => '1',
1106 + 'count_only' => true,
1107 + )
1108 + );
1109 + $count_sites = MainWP_DB::instance()->get_websites_count();
1110 + $avg_sites_per_client = $total_clients && $count_sites ? round( $count_sites / $total_clients, 2 ) : 0;
1139 1111
1140 - if ( 'field_id' === $by ) {
1141 - $sql = $this->wpdb->prepare( 'SELECT * FROM ' . $this->table_name( 'wp_clients_fields' ) . ' WHERE `field_id`=%d', $value );
1142 - } elseif ( 'field_name' === $by ) {
1143 - $sql = $this->wpdb->prepare( 'SELECT * FROM ' . $this->table_name( 'wp_clients_fields' ) . ' WHERE `field_name` = %s AND `client_id`=%d ', $value, $client_id );
1144 - }
1112 + return array(
1113 + 'clients_active_count' => $total_active_clients,
1114 + 'clients_inactive_count' => $total_suspended,
1115 + 'avg_sites_per_client' => $avg_sites_per_client,
1116 + );
1117 + }
1145 1118
1146 - $field = null;
1147 1119
1148 - if ( ! empty( $sql ) ) {
1149 - $field = $this->wpdb->get_row( $sql );
1150 - }
1120 + /**
1121 + * Method get_websites_by_client_ids.
1122 + *
1123 + * Get websites by client.
1124 + *
1125 + * @param array $client_ids Client ids.
1126 + * @param array $params other params.
1127 + *
1128 + * @return mixed $result Results.
1129 + */
1130 + public function get_websites_by_client_ids( $client_ids, $params = array() ) {
1151 1131
1152 - return $field;
1153 - }
1132 + if ( empty( $client_ids ) ) {
1133 + return false;
1134 + }
1154 1135
1155 - /**
1156 - * Method get_client_fields()
1157 - *
1158 - * Get client fields.
1159 - *
1160 - * @param bool $general Get general fields OR not.
1161 - * @param int $client_id Client id.
1162 - * @param bool $field_name_index index result with field name.
1163 - *
1164 - * @return mixed results.
1165 - */
1166 - public function get_client_fields( $general = true, $client_id = 0, $field_name_index = false ) {
1167 - $where = '';
1136 + if ( ! is_array( $params ) ) {
1137 + $params = array();
1138 + }
1168 1139
1169 - if ( $client_id ) {
1170 - if ( true === $general ) {
1171 - $where = ' f.client_id = ' . intval( $client_id ) . ' OR ( f.client_id = 0 AND ( v.value_client_id IS NULL OR v.value_client_id = ' . intval( $client_id ) . ') ) ';
1172 - } else {
1173 - $where = ' f.client_id = ' . intval( $client_id );
1174 - }
1175 - } elseif ( true === $general ) {
1176 - $where = ' f.client_id = 0';
1177 - }
1140 + $client = '';
1141 + if ( is_array( $client_ids ) ) {
1142 + // valid client ids.
1143 + $client_ids = array_filter(
1144 + $client_ids,
1145 + function ( $e ) {
1146 + return is_numeric( $e ) && ! empty( $e ) ? true : false; // to valid client ids.
1147 + }
1148 + );
1149 + $client = implode( ';', $client_ids );
1150 + } else {
1151 + $client = $client_ids;
1152 + }
1178 1153
1179 - if ( '' === $where ) {
1180 - return false;
1181 - }
1154 + $params['client'] = $client;
1182 1155
1183 - $gene_results = array();
1156 + return MainWP_DB::instance()->get_websites_for_current_user( $params );
1157 + }
1184 1158
1185 - if ( $general ) {
1186 - // to fix: missing general fields for client without client fields values.
1187 - $gene_sql = 'SELECT f.* FROM ' . $this->table_name( 'wp_clients_fields' ) . ' f WHERE f.client_id = 0 ORDER BY f.field_name ';
1188 - $gene_results = $this->wpdb->get_results( $gene_sql );
1189 - }
1159 + /**
1160 + * Method get_number_sites_of_client.
1161 + *
1162 + * Get client by.
1163 + *
1164 + * @param int $client_id Client id.
1165 + *
1166 + * @return int Number of sites.
1167 + */
1168 + public function get_number_sites_of_client( $client_id ) {
1169 + if ( empty( $client_id ) ) {
1170 + return false;
1171 + }
1172 + $table_wp = esc_sql( $this->table_name( 'wp' ) );
1173 + return $this->wpdb->get_var( $this->wpdb->prepare( 'SELECT COUNT(wp.id) FROM ' . $table_wp . ' wp WHERE wp.client_id =%d', $client_id ) );
1174 + }
1190 1175
1191 - if ( $client_id ) { // get fields values of client.
1192 - $sql = 'SELECT f.*, v.field_value as field_value FROM ' . $this->table_name( 'wp_clients_fields' ) . ' f LEFT JOIN ' .
1193 - $this->table_name( 'wp_clients_field_values' ) . ' v ON f.field_id = v.field_id WHERE ' . $where . ' ORDER BY f.field_name ';
1194 - } else {
1195 - $sql = 'SELECT f.* FROM ' . $this->table_name( 'wp_clients_fields' ) . ' f WHERE ' . $where . ' ORDER BY f.field_name '; // value_client_id to compatible result.
1196 - }
1176 + /**
1177 + * Method count_total_clients.
1178 + *
1179 + * Count total of Clients.
1180 + *
1181 + * @return int Total number.
1182 + */
1183 + public function count_total_clients() {
1184 + $table_clients = esc_sql( $this->table_name( 'wp_clients' ) );
1185 + return $this->wpdb->get_var( 'SELECT COUNT(client_id) FROM ' . $table_clients );
1186 + }
1197 1187
1198 - $results = $this->wpdb->get_results( $sql );
1199 1188
1200 - $fields_list = array();
1201 - if ( $field_name_index ) {
1202 - if ( $results ) {
1203 - foreach ( $results as $item ) {
1204 - $fields_list[ $item->field_name ] = $item;
1205 - }
1206 - }
1207 - if ( $gene_results ) {
1208 - foreach ( $gene_results as $gene_item ) {
1209 - if ( ! isset( $fields_list[ $gene_item->field_name ] ) ) {
1210 - $gene_item->field_value = '';
1211 - $fields_list[ $gene_item->field_name ] = $gene_item;
1212 - }
1213 - }
1214 - }
1215 - } else {
1216 - $check_list = array();
1217 - if ( $results ) {
1218 - foreach ( $results as $item ) {
1219 - $check_list[ $item->field_name ] = true;
1220 - $fields_list[] = $item;
1221 - }
1222 - }
1223 - if ( $gene_results ) {
1224 - foreach ( $gene_results as $gene_item ) {
1225 - if ( ! isset( $check_list[ $gene_item->field_name ] ) ) {
1226 - $check_list[ $gene_item->field_name ] = true;
1227 - $gene_item->field_value = '';
1228 - $fields_list[] = $gene_item;
1229 - }
1230 - }
1231 - }
1232 - }
1233 - return $fields_list;
1234 - }
1189 + /**
1190 + * Method add_client_field.
1191 + *
1192 + * Add client field.
1193 + *
1194 + * @param mixed $field Client fields data.
1195 + *
1196 + * @return mixed bool|results.
1197 + */
1198 + public function add_client_field( $field ) {
1199 + // "0" is a name the column stores, so the write is refused only for a name that is missing
1200 + // or empty, not for every name PHP reads as falsy. A name that is not a string is refused
1201 + // outright: false is set and is not '', and it would reach the column as an empty name.
1202 + if ( isset( $field['field_name'] ) && is_string( $field['field_name'] ) && '' !== $field['field_name'] && isset( $field['client_id'] ) ) {
1203 + if ( $this->get_client_fields_by( 'field_name', $field['field_name'], $field['client_id'] ) ) { // field name existed for the client can not create.
1204 + return false;
1205 + }
1206 + if ( $this->wpdb->insert( $this->table_name( 'wp_clients_fields' ), $field ) ) {
1207 + return $this->get_client_fields_by( 'field_id', $this->wpdb->insert_id );
1208 + }
1209 + }
1210 + return false;
1211 + }
1235 1212
1236 - /**
1237 - * Suspend - Unsuspended websites.
1238 - *
1239 - * @param int $client_id Client id.
1240 - * @param int $suspend_val Suspend value: 0 or 1.
1241 - *
1242 - * @return int|boolean The result.
1243 - */
1244 - public function suspend_unsuspend_websites_by_client_id( $client_id, $suspend_val ) {
1245 - if ( empty( $client_id ) ) {
1246 - return false;
1247 - }
1248 - return $this->wpdb->query( $this->wpdb->prepare( 'UPDATE ' . $this->table_name( 'wp' ) . ' SET suspended=%d WHERE client_id=%d ', $suspend_val, $client_id ) );
1249 - }
1213 + /**
1214 + * Method update_client_field.
1215 + *
1216 + * Update client field.
1217 + *
1218 + * @param int $field_id field id.
1219 + * @param array $field field data.
1220 + *
1221 + * @return mixed|false field.
1222 + */
1223 + public function update_client_field( $field_id, $field ) {
1224 + // Same as the add above: a rename to "0" is a rename, not a name left out, and a name that
1225 + // is not a string would be written over the stored name as an empty one.
1226 + if ( $field_id && isset( $field['field_name'] ) && is_string( $field['field_name'] ) && '' !== $field['field_name'] ) {
1227 + $current = $this->get_client_fields_by( 'field_id', $field_id );
1228 + if ( $current && $this->wpdb->update( $this->table_name( 'wp_clients_fields' ), $field, array( 'field_id' => $field_id ) ) ) {
1229 + return $this->get_client_fields_by( 'field_id', $current->field_id );
1230 + }
1231 + }
1232 + return false;
1233 + }
1250 1234
1251 - /**
1252 - * Method delete_client_field_by.
1253 - *
1254 - * Delete client field by.
1255 - *
1256 - * @param string $by by.
1257 - * @param mixed $value field value.
1258 - * @param int $client_id client id.
1259 - *
1260 - * @return bool Deleted or not.
1261 - */
1262 - public function delete_client_field_by( $by = 'field_id', $value = false, $client_id = false ) {
1235 + /**
1236 + * Method update_client_field_value.
1237 + *
1238 + * Update client field value.
1239 + *
1240 + * @param int $field_id field id.
1241 + * @param mixed $value field value.
1242 + * @param int $client_id client id.
1243 + *
1244 + * @return mixed|false field data.
1245 + */
1246 + public function update_client_field_value( $field_id, $value, $client_id ) {
1247 + if ( ! empty( $field_id ) ) {
1248 + $table_field_values = esc_sql( $this->table_name( 'wp_clients_field_values' ) );
1249 + $row = $this->wpdb->get_row( $this->wpdb->prepare( 'SELECT * FROM ' . $table_field_values . ' WHERE field_id = %d AND value_client_id=%d ', $field_id, $client_id ) );
1250 + if ( $row ) {
1251 + if ( $row->field_value != $value ) { //phpcs:ignore -- to valid.
1252 + $this->wpdb->update( $table_field_values, array( 'field_value' => $value ), array( 'value_id' => $row->value_id ) );
1253 + }
1254 + return true;
1255 + } else {
1256 + return $this->wpdb->insert(
1257 + $table_field_values,
1258 + array(
1259 + 'field_id' => $field_id,
1260 + 'field_value' => $value,
1261 + 'value_client_id' => $client_id,
1262 + )
1263 + );
1264 + }
1265 + }
1266 + return false;
1267 + }
1263 1268
1264 - if ( 'field_id' === $by ) {
1265 - if ( $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $this->table_name( 'wp_clients_fields' ) . ' WHERE field_id=%d AND client_id=%d', $value, $client_id ) ) ) { // delete individual or general client field.
1266 - if ( $client_id > 0 ) { // individual field value.
1267 - $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $this->table_name( 'wp_clients_field_values' ) . ' WHERE field_id=%d AND value_client_id=%d', $value, $client_id ) ); // delete individual tokens values, for one client.
1268 - } else {
1269 - $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $this->table_name( 'wp_clients_field_values' ) . ' WHERE field_id=%d', $value ) ); // delete general tokens values, multi clients (value_client_id).
1270 - }
1271 - return true;
1272 - }
1273 - }
1269 + /**
1270 + * Method get_client_fields_by.
1271 + *
1272 + * Get client field.
1273 + *
1274 + * @param string $by by.
1275 + * @param mixed $value field value.
1276 + * @param int $client_id client id.
1277 + *
1278 + * @return mixed|null $field field data.
1279 + */
1280 + public function get_client_fields_by( $by = 'field_id', $value = null, $client_id = 0 ) {
1274 1281
1275 - return false;
1276 - }
1282 + // "0" is a name the column stores, so a falsy test here would make a field named "0" unfindable
1283 + // and let a second one be created under the same name. Only the name lookup takes that
1284 + // exception: every other column keeps refusing a falsy value, so a client_id of 0 stays "no
1285 + // client" instead of matching every general field.
1286 + $missing = 'field_name' === $by ? ( null === $value || '' === $value ) : empty( $value );
1277 1287
1278 - /**
1279 - * Method pro_reports_get_tokens()
1280 - *
1281 - * Get pro reports get tokens data.
1282 - *
1283 - * @return mixed results.
1284 - */
1285 - public function pro_reports_get_tokens() {
1286 - return $this->wpdb->get_results( 'SELECT * FROM ' . $this->table_name( 'pro_reports_token' ) . ' WHERE 1 = 1 ORDER BY type DESC, token_name ASC' );
1287 - }
1288 + if ( empty( $by ) || $missing ) {
1289 + return null;
1290 + }
1288 1291
1289 - /**
1290 - * Method pro_reports_get_site_token_values()
1291 - *
1292 - * Get pro reports get tokens values data.
1293 - *
1294 - * @return mixed results.
1295 - */
1296 - public function pro_reports_get_site_token_values() {
1297 - return $this->wpdb->get_results( ' SELECT * FROM ' . $this->table_name( 'pro_reports_site_token' ) . ' WHERE 1 ' );
1298 - }
1292 + $sql = '';
1293 + $table_fields = esc_sql( $this->table_name( 'wp_clients_fields' ) );
1299 1294
1300 - /**
1301 - * Method client_reports_get_tokens()
1302 - *
1303 - * Get client reports get tokens data.
1304 - *
1305 - * @return mixed results.
1306 - */
1307 - public function client_reports_get_tokens() {
1308 - return $this->wpdb->get_results( 'SELECT * FROM ' . $this->table_name( 'client_report_token' ) . ' WHERE 1 = 1 ORDER BY token_name ASC' );
1309 - }
1295 + if ( 'client_id' === $by ) {
1296 + $sql = $this->wpdb->prepare( 'SELECT * FROM ' . $table_fields . ' WHERE `client_id`=%d ', $value );
1297 + return $this->wpdb->get_results( $sql ); // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $sql uses wpdb->prepare() with escaped table name, safe to use directly.
1298 + }
1310 1299
1311 - /**
1312 - * Method client_reports_get_site_token_values()
1313 - *
1314 - * Get client reports get tokens values data.
1315 - *
1316 - * @return mixed results.
1317 - */
1318 - public function client_reports_get_site_token_values() {
1319 - return $this->wpdb->get_results( ' SELECT * FROM ' . $this->table_name( 'client_report_site_token' ) . ' WHERE 1 ' );
1320 - }
1300 + if ( 'field_name' === $by ) {
1301 + $value = str_replace( array( '[', ']' ), '', $value );
1302 + }
1303 +
1304 + if ( 'field_id' === $by ) {
1305 + $sql = $this->wpdb->prepare( 'SELECT * FROM ' . $table_fields . ' WHERE `field_id`=%d', $value );
1306 + } elseif ( 'field_name' === $by ) {
1307 + $sql = $this->wpdb->prepare( 'SELECT * FROM ' . $table_fields . ' WHERE `field_name` = %s AND `client_id`=%d ', $value, $client_id );
1308 + }
1309 +
1310 + $field = null;
1311 +
1312 + if ( ! empty( $sql ) ) {
1313 + $field = $this->wpdb->get_row( $sql ); // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $sql uses wpdb->prepare() with escaped table name, safe to use directly.
1314 + }
1315 +
1316 + return $field;
1317 + }
1318 +
1319 + /**
1320 + * Method get_client_fields_by_params.
1321 + *
1322 + * Get client fields by params.
1323 + *
1324 + * @param array $params params.
1325 + * @param string $obj OBJECT|ARRAY_A.
1326 + *
1327 + * @return mixed|null $fields fields data.
1328 + */
1329 + public function get_client_fields_by_params( $params = array(), $obj = OBJECT ) { // phpcs:ignore -- NOSONAR - complex.
1330 +
1331 + if ( ! is_array( $params ) ) {
1332 + $params = array();
1333 + }
1334 +
1335 + // Initialize custom_where if it does not exist.
1336 + $where = '';
1337 + $limit = '';
1338 + $orderby = 'clients_fields.field_id DESC';
1339 +
1340 + // Parse exclude and include lists.
1341 + $parse_lists = static function ( $lists ) {
1342 + // Convert string to array.
1343 + if ( is_string( $lists ) ) {
1344 + $lists = array_map( 'trim', explode( ',', $lists ) );
1345 + }
1346 +
1347 + // Out default.
1348 + $out = array(
1349 + 'ids' => array(),
1350 + 'names' => array(),
1351 + );
1352 +
1353 + foreach ( (array) $lists as $v ) {
1354 + if ( '' === $v || null === $v ) {
1355 + continue;
1356 + }
1357 +
1358 + if ( is_int( $v ) || ( is_string( $v ) && ctype_digit( $v ) ) ) {
1359 + $out['ids'][] = (int) $v;
1360 + } else {
1361 + $out['names'][] = (string) $v;
1362 + }
1363 + }
1364 + return $out;
1365 + };
1366 +
1367 + // Handle exclude.
1368 + if ( isset( $params['exclude'] ) && ! empty( $params['exclude'] ) ) {
1369 + ['ids' => $ids, 'names' => $names] = $parse_lists( $params['exclude'] );
1370 + $sub_conditions = array();
1371 + $sub_conditions[] = empty( $ids ) ? '' : $this->wpdb->prepare( 'clients_fields.field_id NOT IN (' . implode( ',', array_fill( 0, count( $ids ), '%d' ) ) . ')', ...$ids );
1372 + $sub_conditions[] = empty( $names ) ? '' : $this->wpdb->prepare( 'clients_fields.field_name NOT IN (' . implode( ',', array_fill( 0, count( $names ), '%s' ) ) . ')', ...$names );
1373 + $sub_conditions = array_filter( $sub_conditions );
1374 + $where .= empty( $sub_conditions ) ? '' : ' AND (' . implode( ' AND ', $sub_conditions ) . ')';
1375 + }
1376 +
1377 + // Handle include.
1378 + if ( isset( $params['include'] ) && ! empty( $params['include'] ) ) {
1379 + ['ids' => $ids, 'names' => $names] = $parse_lists( $params['include'] );
1380 + $sub_conditions = array();
1381 + $sub_conditions[] = empty( $ids ) ? '' : $this->wpdb->prepare( 'clients_fields.field_id IN (' . implode( ',', array_fill( 0, count( $ids ), '%d' ) ) . ')', ...$ids );
1382 + $sub_conditions[] = empty( $names ) ? '' : $this->wpdb->prepare( 'clients_fields.field_name IN (' . implode( ',', array_fill( 0, count( $names ), '%s' ) ) . ')', ...$names );
1383 + $sub_conditions = array_filter( $sub_conditions );
1384 + $where .= empty( $sub_conditions ) ? '' : ' AND (' . implode( ' AND ', $sub_conditions ) . ')';
1385 + }
1386 +
1387 + // Handle search.
1388 + if ( isset( $params['search'] ) && ! empty( $params['search'] ) ) {
1389 + $search_term = $this->escape( htmlspecialchars( $params['search'] ) );
1390 + $where .= ' AND clients_fields.field_name LIKE "%' . $search_term . '%"';
1391 + }
1392 +
1393 + // Handle exact field name. The value is queried as it is stored, with no bracket stripping, so
1394 + // the column collation decides equality the same way the unique index does. An empty string
1395 + // filters on an empty name; pass null to leave the filter off.
1396 + if ( isset( $params['field_name_exact'] ) && is_string( $params['field_name_exact'] ) ) {
1397 + $where .= $this->wpdb->prepare( ' AND clients_fields.field_name = %s', $params['field_name_exact'] );
1398 + }
1399 +
1400 + // Handle client id.
1401 + if ( isset( $params['client_id'] ) && ! empty( $params['client_id'] ) ) {
1402 + $client_ids = wp_parse_id_list( $params['client_id'] );
1403 + $where .= empty( $client_ids ) ? '' : ' AND clients_fields.client_id IN (' . implode( ',', $client_ids ) . ')';
1404 + }
1405 +
1406 + // Handel page and per_page.
1407 + $page = '';
1408 + $per_page = '';
1409 + if ( isset( $params['page'] ) && ! empty( $params['page'] ) ) {
1410 + $page = (int) $params['page'];
1411 + }
1412 +
1413 + if ( isset( $params['per_page'] ) && ! empty( $params['per_page'] ) ) {
1414 + $per_page = (int) $params['per_page'];
1415 + }
1416 +
1417 + if ( ! empty( $page ) && ! empty( $per_page ) ) {
1418 + $limit = ' LIMIT ' . ( $page - 1 ) * $per_page . ', ' . $per_page;
1419 + }
1420 +
1421 + // Build SQL.
1422 + $sql = 'SELECT * FROM ' . $this->table_name( 'wp_clients_fields' ) . ' clients_fields WHERE 1=1 ' . $where . ' ORDER BY ' . $orderby . $limit;
1423 +
1424 + return $this->wpdb->get_results( $sql, $obj ); // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $sql built with wpdb->prepare() and escaped table name, safe to use directly.
1425 + }
1426 +
1427 + /**
1428 + * Method get_client_fields()
1429 + *
1430 + * Get client fields.
1431 + *
1432 + * @param bool $general Get general fields OR not.
1433 + * @param int $client_id Client id.
1434 + * @param bool $field_name_index index result with field name.
1435 + *
1436 + * @return mixed results.
1437 + */
1438 + public function get_client_fields( $general = true, $client_id = 0, $field_name_index = false ) { // phpcs:ignore -- NOSONAR - complex.
1439 + $where = '';
1440 +
1441 + if ( $client_id ) {
1442 + if ( true === $general ) {
1443 + $where = ' f.client_id = ' . intval( $client_id ) . ' OR ( f.client_id = 0 AND ( v.value_client_id IS NULL OR v.value_client_id = ' . intval( $client_id ) . ') ) ';
1444 + } else {
1445 + $where = ' f.client_id = ' . intval( $client_id );
1446 + }
1447 + } elseif ( true === $general ) {
1448 + $where = ' f.client_id = 0';
1449 + }
1450 +
1451 + if ( '' === $where ) {
1452 + return false;
1453 + }
1454 +
1455 + $gene_results = array();
1456 + $table_fields = esc_sql( $this->table_name( 'wp_clients_fields' ) );
1457 + $table_field_values = esc_sql( $this->table_name( 'wp_clients_field_values' ) );
1458 +
1459 + if ( $general ) {
1460 + $gene_sql = 'SELECT f.* FROM ' . $table_fields . ' f WHERE f.client_id = 0 ORDER BY f.field_name ';
1461 + $gene_results = $this->wpdb->get_results( $gene_sql ); // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $gene_sql built with escaped table names and hardcoded WHERE condition, safe to use directly.
1462 + }
1463 +
1464 + if ( $client_id ) { // get fields values of client.
1465 + $sql = 'SELECT f.*, v.field_value as field_value FROM ' . $table_fields . ' f LEFT JOIN ' .
1466 + $table_field_values . ' v ON f.field_id = v.field_id WHERE ' . $where . ' ORDER BY f.field_name ';
1467 + } else {
1468 + $sql = 'SELECT f.* FROM ' . $table_fields . ' f WHERE ' . $where . ' ORDER BY f.field_name '; // value_client_id to compatible result.
1469 + }
1470 +
1471 + $results = $this->wpdb->get_results( $sql ); // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $sql built with escaped table names and validated numeric values in $where clause, safe to use directly.
1472 +
1473 + $fields_list = array();
1474 + if ( $field_name_index ) {
1475 + if ( $results ) {
1476 + foreach ( $results as $item ) {
1477 + $fields_list[ $item->field_name ] = $item;
1478 + }
1479 + }
1480 + if ( $gene_results ) {
1481 + foreach ( $gene_results as $gene_item ) {
1482 + if ( ! isset( $fields_list[ $gene_item->field_name ] ) ) {
1483 + $gene_item->field_value = '';
1484 + $fields_list[ $gene_item->field_name ] = $gene_item;
1485 + }
1486 + }
1487 + }
1488 + } else {
1489 + $check_list = array();
1490 + if ( $results ) {
1491 + foreach ( $results as $item ) {
1492 + $check_list[ $item->field_name ] = true;
1493 + $fields_list[] = $item;
1494 + }
1495 + }
1496 + if ( $gene_results ) {
1497 + foreach ( $gene_results as $gene_item ) {
1498 + if ( ! isset( $check_list[ $gene_item->field_name ] ) ) {
1499 + $check_list[ $gene_item->field_name ] = true;
1500 + $gene_item->field_value = '';
1501 + $fields_list[] = $gene_item;
1502 + }
1503 + }
1504 + }
1505 + }
1506 + return $fields_list;
1507 + }
1508 +
1509 + /**
1510 + * Suspend - Unsuspended websites.
1511 + *
1512 + * @param int $client_id Client id.
1513 + * @param int $suspend_val Suspend value: 0 or 1.
1514 + *
1515 + * @return int|boolean The result.
1516 + */
1517 + public function suspend_unsuspend_websites_by_client_id( $client_id, $suspend_val ) {
1518 + if ( empty( $client_id ) ) {
1519 + return false;
1520 + }
1521 + $table_wp = esc_sql( $this->table_name( 'wp' ) );
1522 + return $this->wpdb->query( $this->wpdb->prepare( 'UPDATE ' . $table_wp . ' SET suspended=%d WHERE client_id=%d ', $suspend_val, $client_id ) );
1523 + }
1524 +
1525 + /**
1526 + * Method delete_client_field_by.
1527 + *
1528 + * Delete client field by.
1529 + *
1530 + * @param string $by by.
1531 + * @param mixed $value field value.
1532 + * @param int $client_id client id.
1533 + *
1534 + * @return bool Deleted or not.
1535 + */
1536 + public function delete_client_field_by( $by = 'field_id', $value = false, $client_id = false ) {
1537 +
1538 + $table_fields = esc_sql( $this->table_name( 'wp_clients_fields' ) );
1539 + $table_field_values = esc_sql( $this->table_name( 'wp_clients_field_values' ) );
1540 +
1541 + if ( 'field_id' === $by && $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $table_fields . ' WHERE field_id=%d AND client_id=%d', $value, $client_id ) ) ) { // delete individual or general client field.
1542 + if ( $client_id > 0 ) { // individual field value.
1543 + $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $table_field_values . ' WHERE field_id=%d AND value_client_id=%d', $value, $client_id ) ); // delete individual tokens values, for one client.
1544 + } else {
1545 + $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $table_field_values . ' WHERE field_id=%d', $value ) ); // delete general tokens values, multi clients (value_client_id).
1546 + }
1547 + return true;
1548 + }
1549 +
1550 + return false;
1551 + }
1552 +
1553 + /**
1554 + * Method pro_reports_get_tokens()
1555 + *
1556 + * Get pro reports get tokens data.
1557 + *
1558 + * @return mixed results.
1559 + */
1560 + public function pro_reports_get_tokens() {
1561 + $table_token = esc_sql( $this->table_name( 'pro_reports_token' ) );
1562 + return $this->wpdb->get_results( 'SELECT * FROM ' . $table_token . ' WHERE 1 = 1 ORDER BY type DESC, token_name ASC' );
1563 + }
1564 +
1565 + /**
1566 + * Method pro_reports_get_site_token_values()
1567 + *
1568 + * Get pro reports get tokens values data.
1569 + *
1570 + * @return mixed results.
1571 + */
1572 + public function pro_reports_get_site_token_values() {
1573 + $table_site_token = esc_sql( $this->table_name( 'pro_reports_site_token' ) );
1574 + return $this->wpdb->get_results( ' SELECT * FROM ' . $table_site_token . ' WHERE 1 ' );
1575 + }
1576 +
1577 + /**
1578 + * Method client_reports_get_tokens()
1579 + *
1580 + * Get client reports get tokens data.
1581 + *
1582 + * @return mixed results.
1583 + */
1584 + public function client_reports_get_tokens() {
1585 + $table_token = esc_sql( $this->table_name( 'client_report_token' ) );
1586 + return $this->wpdb->get_results( 'SELECT * FROM ' . $table_token . ' WHERE 1 = 1 ORDER BY token_name ASC' );
1587 + }
1588 +
1589 + /**
1590 + * Method client_reports_get_site_token_values()
1591 + *
1592 + * Get client reports get tokens values data.
1593 + *
1594 + * @return mixed results.
1595 + */
1596 + public function client_reports_get_site_token_values() {
1597 + $table_site_token = esc_sql( $this->table_name( 'client_report_site_token' ) );
1598 + return $this->wpdb->get_results( ' SELECT * FROM ' . $table_site_token . ' WHERE 1 ' );
1599 + }
1321 1600 }