PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.2.2
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.2.2
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 -1128 4.6.0.1 → 6.2.2 View file →
@@ -8,1312 +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 - client_email varchar(191) NOT NULL,
80 - client_phone varchar(100) NOT NULL default '',
81 - client_facebook varchar(255) NOT NULL default '',
82 - client_twitter varchar(255) NOT NULL default '',
83 - client_instagram varchar(255) NOT NULL default '',
84 - client_linkedin varchar(255) NOT NULL default '',
85 - created int(11) NOT NULL DEFAULT 0,
86 - `suspended` tinyint(1) NOT NULL DEFAULT 0,
87 - 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";
88 94
89 - if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.61', '<=' ) ) {
90 - $tbl .= ',
91 - PRIMARY KEY (client_id)';
92 - }
93 - $tbl .= ') ' . $charset_collate;
94 - $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;
95 101
96 - $tbl = 'CREATE TABLE ' . $this->table_name( 'wp_clients_fields' ) . ' (
97 - field_id int(11) NOT NULL auto_increment,
98 - field_name varchar(191) NOT NULL DEFAULT "",
99 - field_desc varchar(255) NOT NULL DEFAULT "",
100 - client_id int(11) NOT NULL,
101 - 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)';
102 108
103 - if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.61', '<=' ) ) {
104 - $tbl .= ',
105 - PRIMARY KEY (`field_id`) ';
106 - }
109 + if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.61', '<=' ) ) {
110 + $tbl .= ',
111 + PRIMARY KEY (`field_id`) ';
112 + }
107 113
108 - $tbl .= ') ' . $charset_collate;
109 - $sql[] = $tbl;
114 + $tbl .= ') ' . $charset_collate;
115 + $sql[] = $tbl;
110 116
111 - $tbl = 'CREATE TABLE ' . $this->table_name( 'wp_clients_field_values' ) . ' (
112 - value_id int(11) NOT NULL auto_increment,
113 - field_id int(11) NOT NULL,
114 - field_value longtext NOT NULL DEFAULT "",
115 - value_client_id int(11) NOT NULL,
116 - 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)';
117 123
118 - if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.61', '<=' ) ) {
119 - $tbl .= ',
120 - PRIMARY KEY (`value_id`) ';
121 - }
124 + if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.61', '<=' ) ) {
125 + $tbl .= ',
126 + PRIMARY KEY (`value_id`) ';
127 + }
122 128
123 - $tbl .= ') ' . $charset_collate;
124 - $sql[] = $tbl;
129 + $tbl .= ') ' . $charset_collate;
130 + $sql[] = $tbl;
125 131
126 - $tbl = 'CREATE TABLE ' . $this->table_name( 'wp_clients_contacts' ) . ' (
127 - contact_id int(11) NOT NULL auto_increment,
128 - contact_client_id int(11) NOT NULL,
129 - contact_email varchar(191) NOT NULL,
130 - contact_image varchar(255) NOT NULL default "",
131 - contact_name varchar(255) NOT NULL,
132 - contact_phone varchar(100) NOT NULL default "",
133 - contact_role varchar(255) NOT NULL default "",
134 - facebook varchar(255) NOT NULL default "",
135 - twitter varchar(255) NOT NULL default "",
136 - instagram varchar(255) NOT NULL default "",
137 - linkedin varchar(255) NOT NULL default "",
138 - 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)';
139 146
140 - if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.69', '<=' ) ) {
141 - $tbl .= ',
142 - PRIMARY KEY (contact_id)';
143 - }
144 - $tbl .= ') ' . $charset_collate;
145 - $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;
146 153
147 - return $sql;
148 - }
154 + return $sql;
155 + }
149 156
150 - /**
151 - * Method check_to_updates_reports_data_861()
152 - *
153 - * Check version less than 8.61 to import reports data.
154 - *
155 - * @param string $currentVersion Current db Version.
156 - *
157 - * @return void.
158 - */
159 - 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 ) {
160 167
161 - $convert_pro_reports_dt = false;
162 - $convert_client_reports_dt = false;
163 - if ( is_plugin_active( 'mainwp-pro-reports-extension/mainwp-pro-reports-extension.php' ) ) {
164 - $convert_pro_reports_dt = true;
165 - } elseif ( is_plugin_active( 'mainwp-client-reports-extension/mainwp-client-reports-extension.php' ) ) {
166 - $convert_client_reports_dt = true;
167 - }
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 + }
168 175
169 - if ( ! $convert_pro_reports_dt && ! $convert_client_reports_dt ) {
170 - $rslt = $this->query( "SHOW TABLES LIKE '" . $this->table_name( 'pro_reports_token' ) . "'" );
171 - if ( self::num_rows( $rslt ) ) {
172 - $convert_pro_reports_dt = true;
173 - }
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 + }
174 182
175 - $rslt = $this->query( "SHOW TABLES LIKE '" . $this->table_name( 'client_report_token' ) . "'" );
176 - if ( self::num_rows( $rslt ) ) {
177 - $convert_client_reports_dt = true;
178 - }
179 - }
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 + }
180 189
181 - $this->insert_client_fields_861( $currentVersion );
190 + $this->insert_client_fields_861( $currentVersion );
182 191
183 - if ( $convert_pro_reports_dt ) {
184 - $this->pro_reports_check_updates_861( $currentVersion );
185 - } elseif ( $convert_client_reports_dt ) {
186 - $this->client_reports_check_updates_861( $currentVersion );
187 - }
188 - }
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 + }
189 198
190 - /**
191 - * Method insert_client_fields_861()
192 - *
193 - * Check version less than 8.61 to import client reports data.
194 - *
195 - * @param string $currentVersion Current db Version.
196 - *
197 - * @return null.
198 - */
199 - 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 ) {
200 209
201 - if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.61', '>' ) ) {
202 - return;
203 - }
210 + if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.61', '>' ) ) {
211 + return;
212 + }
204 213
205 - $default_tokens = array(
206 - 'client.name' => 'Displays the Client Name',
207 - 'client.contact.name' => 'Displays the Client Contact Name',
208 - 'client.contact.address.1' => 'Displays the Client Contact Address 1',
209 - 'client.contact.address.2' => 'Displays the Client Contact Address 2',
210 - 'client.city' => 'Displays the Client City',
211 - 'client.state' => 'Displays the Client State',
212 - 'client.zip' => 'Displays the Client Zip',
213 - 'client.phone' => 'Displays the Client Phone',
214 - 'client.email' => 'Displays the Client Email',
215 - 'client.note' => 'Displays the Client Note',
216 - );
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 + );
217 226
218 - // create or update default token.
219 - foreach ( $default_tokens as $field_name => $field_desc ) {
220 - $current = $this->get_client_fields_by( 'field_name', $field_name );
221 - if ( $current ) {
222 - $this->update_client_field(
223 - $current->field_id,
224 - array(
225 - 'field_name' => $field_name,
226 - 'field_desc' => $field_desc,
227 - )
228 - );
229 - } else {
230 - $this->add_client_field(
231 - array(
232 - 'field_name' => $field_name,
233 - 'field_desc' => $field_desc,
234 - 'client_id' => 0,
235 - )
236 - );
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 + );
237 246
238 - }
239 - }
240 - }
247 + }
248 + }
249 + }
241 250
242 - /**
243 - * Method client_reports_check_updates_861()
244 - *
245 - * Check version less than 8.61 to import client reports data.
246 - *
247 - * @param string $currentVersion Current db Version.
248 - *
249 - * @return null.
250 - */
251 - 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 ) {
252 261
253 - if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.61', '>' ) ) {
254 - return;
255 - }
262 + if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.61', '>' ) ) {
263 + return;
264 + }
256 265
257 - $tokens = $this->client_reports_get_tokens();
258 - $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();
259 268
260 - $this->reports_check_updates_861( $tokens, $sites_tokens_values );
261 - }
269 + $this->reports_check_updates_861( $tokens, $sites_tokens_values );
270 + }
262 271
263 - /**
264 - * Method pro_reports_check_updates_861()
265 - *
266 - * Check version less than 8.61 to import pro reports data.
267 - *
268 - * @param string $currentVersion Current db Version.
269 - *
270 - * @return null.
271 - */
272 - 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 ) {
273 282
274 - if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.61', '>' ) ) {
275 - return;
276 - }
283 + if ( empty( $currentVersion ) || version_compare( $currentVersion, '8.61', '>' ) ) {
284 + return;
285 + }
277 286
278 - $tokens = $this->pro_reports_get_tokens();
279 - $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();
280 289
281 - $this->reports_check_updates_861( $tokens, $sites_tokens_values );
282 - }
290 + $this->reports_check_updates_861( $tokens, $sites_tokens_values );
291 + }
283 292
284 293
285 - /**
286 - * Method reports_check_updates_861()
287 - *
288 - * Check version less than 8.61 to import reports data.
289 - *
290 - * @param array $tokens Tokens.
291 - * @param array $sites_tokens_values Tokens values.
292 - *
293 - * @return void.
294 - */
295 - 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.
296 305
297 - $default_client_fields = MainWP_Client_Handler::get_default_client_fields();
298 - $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();
299 308
300 - $compatible_tokens = MainWP_Client_Handler::get_compatible_tokens();
309 + $compatible_tokens = MainWP_Client_Handler::get_compatible_tokens();
301 310
302 - $ids_to_tokens = array();
311 + $ids_to_tokens = array();
303 312
304 - if ( $tokens ) {
305 - foreach ( $tokens as $token ) {
306 - $tok_name = $token->token_name;
307 - $ids_to_tokens[ $token->id ] = array(
308 - 'token_name' => $tok_name,
309 - 'token_desc' => $token->token_description,
310 - );
311 - }
312 - }
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 + }
313 322
314 - $ids_to_tokens_values = array();
323 + $ids_to_tokens_values = array();
315 324
316 - if ( $sites_tokens_values ) {
317 - foreach ( $sites_tokens_values as $token ) {
318 - if ( ! isset( $ids_to_tokens[ $token->token_id ] ) ) {
319 - continue;
320 - }
321 - if ( empty( $token->token_value ) ) {
322 - continue;
323 - }
324 - $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'];
325 334
326 - $ids_to_tokens_values[ $token->site_id ][ $tok_name ] = array(
327 - 'token_value' => $token->token_value,
328 - 'token_desc' => $ids_to_tokens[ $token->token_id ]['token_desc'],
329 - );
330 - }
331 - }
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 + }
332 341
333 - $clients_to_add = array();
334 - $primary_contacts_to_add = array();
335 - $custom_tokens_to_add = array();
342 + $clients_to_add = array();
343 + $primary_contacts_to_add = array();
344 + $custom_tokens_to_add = array();
336 345
337 - foreach ( $ids_to_tokens_values as $site_id => $tokens ) {
346 + foreach ( $ids_to_tokens_values as $site_id => $tokens ) {
338 347
339 - if ( empty( $tokens['client.email'] ) ) {
340 - continue;
341 - }
348 + if ( empty( $tokens['client.email'] ) ) {
349 + continue;
350 + }
342 351
343 - $email = $tokens['client.email']['token_value'];
352 + $email = $tokens['client.email']['token_value'];
344 353
345 - if ( ! isset( $clients_to_add[ $email ] ) ) {
346 - $clients_to_add[ $email ] = array();
347 - }
354 + if ( ! isset( $clients_to_add[ $email ] ) ) {
355 + $clients_to_add[ $email ] = array();
356 + }
348 357
349 - if ( ! isset( $clients_to_add[ $email ]['site_ids'] ) ) {
350 - $clients_to_add[ $email ]['site_ids'] = array();
351 - }
358 + if ( ! isset( $clients_to_add[ $email ]['site_ids'] ) ) {
359 + $clients_to_add[ $email ]['site_ids'] = array();
360 + }
352 361
353 - $clients_to_add[ $email ]['site_ids'][] = $site_id;
362 + $clients_to_add[ $email ]['site_ids'][] = $site_id;
354 363
355 - // prepare clients to add.
356 - foreach ( $default_client_fields as $field_name => $field ) {
357 - if ( ! isset( $tokens[ $field_name ] ) ) {
358 - continue;
359 - }
360 - $clients_to_add[ $email ][ $field['db_field'] ] = $tokens[ $field_name ]['token_value'];
361 - }
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 + }
362 371
363 - $flip_compatible_tokens = array_flip( $compatible_tokens ); // flip: new_token_name => old_token_name.
364 - // prepare primary contacts to add.
365 - 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 ) {
366 375
367 - // $field_name - new_token_name.
368 - // $tok_name - old_token_name.
369 - $tok_name = isset( $flip_compatible_tokens[ $field_name ] ) ? $flip_compatible_tokens[ $field_name ] : $field_name;
370 - if ( ! isset( $tokens[ $tok_name ] ) ) {
371 - continue;
372 - }
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 + }
373 382
374 - $primary_contacts_to_add[ $email ][ $field['db_field'] ] = $tokens[ $tok_name ]['token_value'];
375 - }
383 + $primary_contacts_to_add[ $email ][ $field['db_field'] ] = $tokens[ $tok_name ]['token_value'];
384 + }
376 385
377 - foreach ( $tokens as $tok_name => $tok_value_desc ) {
378 - if ( isset( $default_client_fields[ $tok_name ] ) || isset( $default_contact_fields[ $tok_name ] ) ) {
379 - continue;
380 - }
381 - if ( 'client.site.url' === $tok_name || 'client.site.name' === $tok_name ) { // avoid those tokens.
382 - continue;
383 - }
384 - if ( isset( $compatible_tokens[ $tok_name ] ) ) {
385 - continue;
386 - }
387 - $custom_tokens_to_add[ $email ][ $tok_name ] = $tok_value_desc;
388 - }
389 - }
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 + }
390 399
391 - $emails_to_ids = array();
392 - foreach ( $clients_to_add as $email => $client_add ) {
393 - $selected_sites = array();
394 - if ( isset( $client_add['site_ids'] ) ) {
395 - $selected_sites = $client_add['site_ids'];
396 - unset( $client_add['site_ids'] );
397 - }
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 + }
398 407
399 - $inserted = $this->update_client( $client_add ); // add new client.
408 + $inserted = $this->update_client( $client_add ); // add new client.
400 409
401 - if ( $inserted ) {
402 - $client_id = $inserted->client_id;
403 - $this->update_selected_sites_for_client( $client_id, $selected_sites );
404 - $emails_to_ids[ $email ] = $client_id;
405 - }
406 - }
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 + }
407 416
408 - foreach ( $emails_to_ids as $email => $client_id ) {
417 + foreach ( $emails_to_ids as $email => $client_id ) {
409 418
410 - if ( isset( $primary_contacts_to_add[ $email ] ) ) {
411 - $contact_add = $primary_contacts_to_add[ $email ];
412 - $contact_add['contact_client_id'] = $client_id;
413 - $inserted = $this->update_client_contact( $contact_add );
414 - if ( $inserted ) {
415 - $params = array(
416 - 'client_id' => $client_id, // update the client.
417 - 'primary_contact_id' => $inserted->contact_id,
418 - );
419 - $this->update_client( $params );
420 - }
421 - }
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 + }
422 431
423 - if ( isset( $custom_tokens_to_add[ $email ] ) ) {
424 - $custom_tokens = $custom_tokens_to_add[ $email ];
425 - foreach ( $custom_tokens as $tok_name => $tok_value_desc ) {
426 - $field_id = 0;
427 - $current = $this->get_client_fields_by( 'field_name', $tok_name ); // get general field by name.
428 - if ( $current ) {
429 - $field_id = $current->field_id;
430 - } else {
431 - $field = array(
432 - 'field_name' => $tok_name,
433 - 'field_desc' => $tok_value_desc['token_desc'],
434 - 'client_id' => 0, // it is general tokens.
435 - );
436 - $new_field = $this->add_client_field( $field );
437 - if ( $new_field ) {
438 - $field_id = $new_field->field_id;
439 - }
440 - }
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 + }
441 450
442 - if ( $field_id ) {
443 - $this->update_client_field_value( $field_id, $tok_value_desc['token_value'], $client_id );
444 - }
445 - }
446 - }
447 - }
448 - }
451 + if ( $field_id ) {
452 + $this->update_client_field_value( $field_id, $tok_value_desc['token_value'], $client_id );
453 + }
454 + }
455 + }
456 + }
457 + }
449 458
450 459
451 - /**
452 - * Method update_client.
453 - *
454 - * Create or update client.
455 - *
456 - * @param array $data Client data.
457 - * @param bool $throw_out Throw or return error.
458 - *
459 - * @throws MainWP_Exception On errors.
460 - *
461 - * @return bool.
462 - */
463 - public function update_client( $data, $throw_out = false ) {
464 - if ( empty( $data ) || ! is_array( $data ) ) {
465 - return false;
466 - }
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 + }
467 476
468 - $client_id = isset( $data['client_id'] ) ? (int) $data['client_id'] : 0;
477 + $client_id = isset( $data['client_id'] ) ? (int) $data['client_id'] : 0;
469 478
470 - if ( isset( $data['client_email'] ) && ! empty( $data['client_email'] ) ) {
471 - $client_existed = $this->get_wp_client_by( 'client_email', $data['client_email'], ARRAY_A );
472 - if ( is_array( $client_existed ) && isset( $client_existed['client_id'] ) && ( empty( $client_id ) || $client_id !== (int) $client_existed['client_id'] ) ) {
473 - if ( $throw_out ) {
474 - throw new MainWP_Exception( esc_html__( 'Client email exists. Please try again.', 'mainwp' ) );
475 - } else {
476 - return false;
477 - }
478 - }
479 - }
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 + }
480 489
481 - if ( ! empty( $client_id ) ) {
482 - $this->wpdb->update( $this->table_name( 'wp_clients' ), $data, array( 'client_id' => intval( $client_id ) ) );
483 - return $this->get_wp_client_by( 'client_id', $client_id );
484 - } elseif ( $this->wpdb->insert( $this->table_name( 'wp_clients' ), $data ) ) {
485 - return $this->get_wp_client_by( 'client_id', $this->wpdb->insert_id );
486 - }
487 - return false;
488 - }
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 + }
489 498
490 499
491 - /**
492 - * Method update_client.
493 - *
494 - * Create or update client contact.
495 - *
496 - * @param array $data Contact data.
497 - *
498 - * @return bool.
499 - */
500 - 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.
501 510
502 - if ( empty( $data ) ) {
503 - return false;
504 - }
511 + if ( empty( $data ) ) {
512 + return false;
513 + }
505 514
506 - $contact_id = isset( $data['contact_id'] ) ? (int) $data['contact_id'] : 0;
515 + $contact_id = isset( $data['contact_id'] ) ? (int) $data['contact_id'] : 0;
507 516
508 - $contact_email = isset( $data['contact_email'] ) ? $data['contact_email'] : '';
509 - if ( ! empty( $contact_email ) ) {
510 - $existed_email = false;
511 - // check to valid email.
512 - $curret_contact = $this->get_wp_client_contact_by( 'contact_email', $contact_email );
513 - if ( $curret_contact && empty( $contact_id ) ) { // add new contact with existed email => failed.
514 - $existed_email = true;
515 - }
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 + }
516 525
517 - if ( $curret_contact && ! empty( $contact_id ) ) {
518 - if ( (int) $curret_contact->contact_id !== $contact_id ) { // update contact with existed email => failed.
519 - $existed_email = true;
520 - }
521 - }
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 + }
522 529
523 - if ( $existed_email ) {
524 - MainWP_Utility::update_flash_message( 'contact_existed_emails', $contact_email );
525 - return false;
526 - }
527 - }
530 + if ( $existed_email ) {
531 + MainWP_Utility::update_flash_message( 'contact_existed_emails', $contact_email );
532 + return false;
533 + }
534 + }
528 535
529 - if ( ! empty( $contact_id ) ) {
530 - $this->wpdb->update( $this->table_name( 'wp_clients_contacts' ), $data, array( 'contact_id' => intval( $contact_id ) ) );
531 - return $this->get_wp_client_contact_by( 'contact_id', $contact_id );
532 - } elseif ( $this->wpdb->insert( $this->table_name( 'wp_clients_contacts' ), $data ) ) {
533 - return $this->get_wp_client_contact_by( 'contact_id', $this->wpdb->insert_id );
534 - }
535 - return false;
536 - }
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 + }
537 544
538 - /**
539 - * Method get_wp_client_contact_by.
540 - *
541 - * Get client by.
542 - *
543 - * @param string $by by.
544 - * @param mixed $value by value.
545 - * @param mixed $obj Format data.
546 - * @param array $params other params.
547 - *
548 - * @return mixed $result results.
549 - */
550 - 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.
551 558
552 - $with_selected_sites = isset( $params['with_selected_sites'] ) && $params['with_selected_sites'] ? true : false;
553 - $with_tags = isset( $params['with_tags'] ) && $params['with_tags'] ? true : false;
559 + $sql = '';
560 + $table_contacts = esc_sql( $this->table_name( 'wp_clients_contacts' ) );
554 561
555 - $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 + }
556 565
557 - if ( 'client_id' === $by && ! empty( $value ) ) {
558 - $sql = $this->wpdb->prepare( 'SELECT wc.* FROM ' . $this->table_name( 'wp_clients_contacts' ) . ' wc WHERE wc.contact_client_id=%d ', $value );
559 - }
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 + }
560 574
561 - if ( ! empty( $sql ) ) {
562 - if ( OBJECT === $obj ) {
563 - $result = $this->wpdb->get_results( $sql, OBJECT );
564 - } else {
565 - $result = $this->wpdb->get_results( $sql, ARRAY_A );
566 - }
567 - return $result;
568 - }
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 + }
569 580
570 - if ( 'contact_id' === $by && is_numeric( $value ) ) {
571 - $sql = $this->wpdb->prepare( 'SELECT wc.* FROM ' . $this->table_name( 'wp_clients_contacts' ) . ' wc WHERE wc.contact_id=%d ', $value );
572 - } elseif ( 'contact_email' === $by && ! empty( $value ) ) {
573 - $sql = $this->wpdb->prepare( 'SELECT wc.* FROM ' . $this->table_name( 'wp_clients_contacts' ) . ' wc WHERE wc.contact_email=%s ', $value );
574 - }
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 + }
575 591
576 - $result = null;
577 - if ( ! empty( $sql ) ) {
578 - if ( OBJECT === $obj ) {
579 - $result = $this->wpdb->get_row( $sql, OBJECT );
580 - } else {
581 - $result = $this->wpdb->get_row( $sql, ARRAY_A );
582 - }
583 - }
584 - return $result;
585 - }
586 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 + }
587 617
588 - /**
589 - * Method delete_client.
590 - *
591 - * Delete client.
592 - *
593 - * @param int $client_id Client id of the contact.
594 - * @param int $contact_id Contact id to delete.
595 - *
596 - * @return bool Results.
597 - */
598 - public function delete_client_contact( $client_id, $contact_id ) {
599 - $current = $this->get_wp_client_contact_by( 'contact_id', $contact_id );
600 - 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 ) ) ) {
601 - if ( ! empty( $current->contact_image ) ) {
602 - $dirs = MainWP_System_Utility::get_mainwp_dir( 'client-images', true );
603 - $base_dir = $dirs[0];
604 - $old_file = $base_dir . '/' . $current->contact_image;
605 - MainWP_Utility::delete_file( $old_file );
606 - }
607 - return true;
608 - }
609 - return false;
610 - }
611 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 ) {
612 629
613 - /**
614 - * Method delete_client_contacts_by_client_id.
615 - *
616 - * Delete client contacts by client id.
617 - *
618 - * @param int $client_id Client id.
619 - *
620 - * @return bool Results.
621 - */
622 - public function delete_client_contacts_by_client_id( $client_id ) {
630 + if ( empty( $client_id ) ) {
631 + return false;
632 + }
623 633
624 - if ( empty( $client_id ) ) {
625 - return false;
626 - }
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 + }
627 642
628 - $client_contacts = $this->get_wp_client_contact_by( 'client_id', $client_id, ARRAY_A );
629 - if ( $client_contacts ) {
630 - foreach ( $client_contacts as $contact ) {
631 - $this->delete_client_contact( $client_id, $contact['contact_id'] );
632 - }
633 - }
634 - return true;
635 - }
636 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.
637 663
638 - /**
639 - * Method get_wp_client_by.
640 - *
641 - * Get client by.
642 - *
643 - * @param string $by by.
644 - * @param mixed $value by value.
645 - * @param mixed $obj Format data.
646 - * @param bool $params Others params.
647 - *
648 - * @return mixed $result results.
649 - */
650 - 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;
651 670
652 - $with_selected_sites = isset( $params['with_selected_sites'] ) && $params['with_selected_sites'] ? true : false;
653 - $with_tags = isset( $params['with_tags'] ) && $params['with_tags'] ? true : false;
654 - $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 + }
655 685
656 - // valid group ids.
657 - if ( is_array( $group_ids ) ) {
658 - $group_ids = array_filter(
659 - $group_ids,
660 - function ( $e ) {
661 - if ( 'nogroups' === $e ) {
662 - return true;
663 - }
664 - return ( is_numeric( $e ) && 0 < $e ) ? true : false;
665 - }
666 - );
667 - } else {
668 - $group_ids = '';
669 - }
686 + $select_sites = '';
687 + $select_tags = '';
688 + $where_clients = '';
670 689
671 - $select_sites = '';
672 - $select_tags = '';
673 - $where_clients = '';
690 + $sql = '';
674 691
675 - $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' ) );
676 697
677 - if ( $with_selected_sites ) {
678 - $select_sites .= ',( SELECT GROUP_CONCAT(wp.id SEPARATOR ",") FROM ' . $this->table_name( 'wp' ) . ' wp WHERE wp.client_id = wc.client_id ) as selected_sites ';
679 - }
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 + }
680 701
681 - if ( ! empty( $group_ids ) ) {
702 + if ( ! empty( $group_ids ) ) {
682 703
683 - $join_group = '';
684 - $where_group = '';
704 + $join_group = '';
705 + $where_group = '';
685 706
686 - if ( in_array( 'nogroups', $group_ids ) ) {
687 - $join_group = ' LEFT JOIN ' . $this->table_name( 'wp_group' ) . ' wpgroup ON wp.id = wpgroup.wpid ';
688 - $group_ids = array_filter(
689 - $group_ids,
690 - function ( $e ) {
691 - return 'nogroups' !== $e;
692 - }
693 - );
694 - if ( 0 < count( $group_ids ) ) {
695 - $groups = implode( ',', $group_ids );
696 - $where_group = ' AND ( wpgroup.groupid IS NULL OR wpgroup.groupid IN (' . $groups . ') ) ';
697 - } else {
698 - $where_group = ' AND wpgroup.groupid IS NULL ';
699 - }
700 - } else {
701 - $groups = implode( ',', $group_ids );
702 - $join_group = ' JOIN ' . $this->table_name( 'wp_group' ) . ' wpgroup ON wp.id = wpgroup.wpid ';
703 - $where_group = ' AND wpgroup.groupid IN (' . $groups . ') ';
704 - }
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 + }
705 726
706 - $sql_tags = ' SELECT wp.client_id FROM ' . $this->table_name( 'wp' ) . ' wp ';
707 - $sql_tags .= $join_group;
708 - $sql_tags .= ' WHERE 1 ' . $where_group;
709 - $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.
710 731
711 - if ( empty( $result_tags ) ) {
712 - return array();
713 - } else {
714 - $cli_ids = array();
715 - foreach ( $result_tags as $item ) {
716 - $cli_ids[] = $item->client_id;
717 - }
718 - $cli_ids = array_values( array_unique( $cli_ids ) );
719 - $where_clients = ' AND wc.client_id IN (' . implode( ',', $cli_ids ) . ') ';
720 - }
721 - }
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 + }
722 743
723 - if ( $with_tags ) {
724 - $select_tags .= ", ( SELECT GROUP_CONCAT(gr.name ORDER BY gr.name SEPARATOR ',') FROM " . $this->table_name( 'wp' ) . ' wp ';
725 - $select_tags .= ' LEFT JOIN ' . $this->table_name( 'wp_group' ) . ' wpgr ON wp.id = wpgr.wpid ';
726 - $select_tags .= ' LEFT JOIN ' . $this->table_name( 'group' ) . ' gr ON wpgr.groupid = gr.id ';
727 - $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 ';
728 749
729 - $select_tags .= ", ( SELECT GROUP_CONCAT(gr.id ORDER BY gr.id SEPARATOR ',') FROM " . $this->table_name( 'wp' ) . ' wp ';
730 - $select_tags .= ' LEFT JOIN ' . $this->table_name( 'wp_group' ) . ' wpgr ON wp.id = wpgr.wpid ';
731 - $select_tags .= ' LEFT JOIN ' . $this->table_name( 'group' ) . ' gr ON wpgr.groupid = gr.id ';
732 - $select_tags .= ' WHERE wp.client_id = wc.client_id ) as wpgroupids ';
733 - }
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 + }
734 755
735 - $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 ';
736 757
737 - if ( 'all' === $by ) {
738 - $sql = ' SELECT wc.*, cc.* ' . $select_sites . $select_tags;
739 - $sql .= ' FROM ' . $this->table_name( 'wp_clients' ) . ' wc ';
740 - $sql .= $join_contact;
741 - $sql .= ' WHERE 1 ' . $where_clients;
742 - $sql .= ' ORDER BY wc.name';
743 - }
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 + }
744 766
745 - if ( ! empty( $sql ) ) {
746 - if ( OBJECT === $obj ) {
747 - $result = $this->wpdb->get_results( $sql, OBJECT );
748 - } else {
749 - $result = $this->wpdb->get_results( $sql, ARRAY_A );
750 - }
751 - return $result;
752 - }
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';
753 772
754 - if ( 'client_id' === $by && is_numeric( $value ) ) {
755 - $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 );
756 - } elseif ( 'client_email' === $by && ! empty( $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_email=%s ', $value );
758 - }
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 + }
759 778
760 - $result = null;
761 - if ( ! empty( $sql ) ) {
762 - if ( OBJECT === $obj ) {
763 - $result = $this->wpdb->get_row( $sql, OBJECT );
764 - } else {
765 - $result = $this->wpdb->get_row( $sql, ARRAY_A );
766 - }
767 - }
768 - return $result;
769 - }
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 + }
770 787
771 - /**
772 - * Method get_wp_clients.
773 - *
774 - * Get clients.
775 - *
776 - * @param array $params params.
777 - *
778 - * @return mixed result.
779 - */
780 - 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 + }
781 793
782 - $custom_field = false;
783 - $with_tags = false;
784 - $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 + }
785 804
786 - $where = '';
787 - $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.
788 815
789 - if ( $params && is_array( $params ) ) {
790 - $client = isset( $params['client'] ) ? sanitize_text_field( wp_unslash( $params['client'] ) ) : '';
791 - if ( '' !== $client ) {
792 - $clients = explode( ';', $client );
793 - $clientWhere = '';
794 - foreach ( $clients as $clt ) {
795 - if ( is_numeric( $clt ) ) {
796 - $clientWhere .= intval( $clt ) . ', ';
797 - }
798 - }
799 - $clientWhere = rtrim( $clientWhere, ', ' );
816 + $custom_field = false;
817 + $with_tags = false;
818 + $with_contacts = false;
819 + $count_only = false;
800 820
801 - $where .= ' AND wc.client_id IN (' . $clientWhere . ') ';
802 - }
803 - $custom_field = $params['custom_fields'] && $params['custom_fields'] ? true : false;
821 + $s = '';
822 + $exclude = array();
823 + $include = array();
824 + $limit = '';
804 825
805 - $with_tags = isset( $params['with_tags'] ) && $params['with_tags'] ? true : false;
806 - $with_contacts = isset( $params['with_contacts'] ) && $params['with_contacts'] ? true : false;
807 - }
826 + $where = '';
827 + $select_tags = '';
808 828
809 - if ( $with_tags ) {
810 - $select_tags .= ", ( SELECT GROUP_CONCAT(gr.name ORDER BY gr.name SEPARATOR ',') FROM " . $this->table_name( 'wp' ) . ' wp ';
811 - $select_tags .= ' LEFT JOIN ' . $this->table_name( 'wp_group' ) . ' wpgr ON wp.id = wpgr.wpid ';
812 - $select_tags .= ' LEFT JOIN ' . $this->table_name( 'group' ) . ' gr ON wpgr.groupid = gr.id ';
813 - $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' ) );
814 833
815 - $select_tags .= ", ( SELECT GROUP_CONCAT(gr.id ORDER BY gr.id SEPARATOR ',') FROM " . $this->table_name( 'wp' ) . ' wp ';
816 - $select_tags .= ' LEFT JOIN ' . $this->table_name( 'wp_group' ) . ' wpgr ON wp.id = wpgr.wpid ';
817 - $select_tags .= ' LEFT JOIN ' . $this->table_name( 'group' ) . ' gr ON wpgr.groupid = gr.id ';
818 - $select_tags .= ' WHERE wp.client_id = wc.client_id ) as wpgroupids ';
819 - }
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 ) );
820 839
821 - $sql = ' SELECT wc.* ';
822 - $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;
823 - $sql .= ' FROM ' . $this->table_name( 'wp_clients' ) . ' wc ';
824 - $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, ', ' );
825 847
826 - $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;
827 851
828 - $contact_fields = array(
829 - 'contact_id',
830 - 'contact_client_id',
831 - 'contact_email',
832 - 'contact_name',
833 - 'contact_phone',
834 - 'contact_role',
835 - 'contact_image',
836 - 'facebook',
837 - 'twitter',
838 - 'instagram',
839 - 'linkedin',
840 - );
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;
841 855
842 - $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;
843 862
844 - 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 + }
845 874
846 - if ( $custom_field ) {
847 - $custom_fields = $this->get_client_fields( true, $rst['client_id'] );
848 - if ( $custom_fields ) {
849 - foreach ( $custom_fields as $field ) {
850 - $rst[ $field->field_name ] = $field->field_value;
851 - }
852 - }
853 - }
854 - if ( $with_tags && ! empty( $rst['wpgroupids'] ) && ! empty( $rst['wpgroups'] ) ) {
855 - $wpgroupids = explode( ',', $rst['wpgroupids'] );
856 - $wpgroups = explode( ',', $rst['wpgroups'] );
875 + if ( ! empty( $exclude ) ) {
876 + $where .= ' AND wc.client_id NOT IN (' . implode( ',', $exclude ) . ') ';
877 + }
857 878
858 - $tags = array();
859 - if ( is_array( $wpgroupids ) ) {
860 - foreach ( $wpgroupids as $gidx => $groupid ) {
861 - if ( $groupid && ! isset( $tags[ $groupid ] ) ) {
862 - $tags[ $groupid ] = isset( $wpgroups[ $gidx ] ) ? $wpgroups[ $gidx ] : '';
863 - }
864 - }
865 - }
879 + if ( ! empty( $include ) ) {
880 + $where .= ' AND wc.client_id IN (' . implode( ',', $include ) . ') ';
881 + }
866 882
867 - $rst['tags'] = $tags;
868 - }
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 + }
869 906
870 - if ( $with_contacts ) {
871 - $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 + }
872 911
873 - $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 ';
874 917
875 - if ( is_array( $client_contacts ) ) {
876 - foreach ( $client_contacts as $gidx => $contact ) {
877 - $contacts[ $contact['contact_id'] ] = MainWP_Utility::map_fields( $contact, $contact_fields, false );
878 - }
879 - }
880 - $rst['contacts'] = $contacts;
881 - }
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 + }
882 923
883 - $output[] = $rst;
884 - }
885 - return $output;
886 - }
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 + }
887 935
888 - /**
889 - * Method update_selected_sites_for_client.
890 - *
891 - * Update client.
892 - *
893 - * @param int $client_id client id.
894 - * @param array $site_ids site ids.
895 - *
896 - * @return bool true|false.
897 - */
898 - public function update_selected_sites_for_client( $client_id, $site_ids ) {
899 - if ( empty( $client_id ) ) {
900 - return false;
901 - }
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.
902 937
903 - $site_ids = array_filter(
904 - $site_ids,
905 - function ( $e ) {
906 - return ( is_numeric( $e ) && 0 < $e ) ? true : false;
907 - }
908 - );
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 + );
909 951
910 - if ( is_array( $site_ids ) && count( $site_ids ) > 0 ) {
911 - $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 ) );
912 - $this->wpdb->query( $this->wpdb->prepare( 'UPDATE ' . $this->table_name( 'wp' ) . ' SET client_id=%d WHERE id IN (' . implode( ',', $site_ids ) . ')', $client_id ) );
913 - return true;
914 - } else {
915 - $this->wpdb->query( $this->wpdb->prepare( 'UPDATE ' . $this->table_name( 'wp' ) . ' SET client_id=0 WHERE client_id=%d ', $client_id ) );
916 - return true;
917 - }
918 - return false;
919 - }
952 + $output = array();
920 953
921 - /**
922 - * Method delete_client.
923 - *
924 - * Delete client.
925 - *
926 - * @param int $client_id Client id to delete.
927 - * @return bool Results.
928 - */
929 - public function delete_client( $client_id ) {
954 + foreach ( $result as $rst ) {
930 955
931 - $current = $this->get_wp_client_by( 'client_id', $client_id );
932 - if ( $current && $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $this->table_name( 'wp_clients' ) . ' WHERE client_id=%d ', $client_id ) ) ) {
933 - $this->wpdb->query( $this->wpdb->prepare( 'UPDATE ' . $this->table_name( 'wp' ) . ' SET client_id=0 WHERE client_id=%d ', $client_id ) );
934 - $fields = $this->get_client_fields_by( 'client_id', $client_id );
935 - if ( $fields ) {
936 - foreach ( $fields as $field ) {
937 - $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $this->table_name( 'wp_clients_fields' ) . ' WHERE field_id=%d ', $field->field_id ) );
938 - $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 ) );
939 - }
940 - }
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'] );
941 967
942 - if ( ! empty( $current->image ) ) {
943 - $dirs = MainWP_System_Utility::get_mainwp_dir( 'client-images', true );
944 - $base_dir = $dirs[0];
945 - $old_file = $base_dir . '/' . $current->image;
946 - MainWP_Utility::delete_file( $old_file );
947 - }
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 + }
948 976
949 - $this->delete_client_contacts_by_client_id( $client_id );
977 + $rst['tags'] = $tags;
978 + }
950 979
951 - /**
952 - * Delete client
953 - *
954 - * Fires after delete a client.
955 - *
956 - * @param object $current client deleted.
957 - *
958 - * @since 4.5.1.1
959 - */
960 - 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 );
961 982
962 - return true;
963 - }
964 - return false;
965 - }
983 + $contacts = array();
966 984
967 - /**
968 - * Method get_websites_by_client_ids.
969 - *
970 - * Get websites by client.
971 - *
972 - * @param int $client_ids Client ids.
973 - * @param array $params other params.
974 - *
975 - * @return mixed $result Results.
976 - */
977 - 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 + }
978 992
979 - if ( empty( $client_ids ) ) {
980 - return false;
981 - }
993 + $output[] = $rst;
994 + }
995 + return $output;
996 + }
982 997
983 - if ( ! is_array( $params ) ) {
984 - $params = array();
985 - }
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 + }
986 1012
987 - $client = '';
988 - if ( is_array( $client_ids ) ) {
989 - // valid client ids.
990 - $client_ids = array_filter(
991 - $client_ids,
992 - function ( $e ) {
993 - return is_numeric( $e ) && ! empty( $e ) ? true : false; // to valid client ids.
994 - }
995 - );
996 - $client = implode( ';', $client_ids );
997 - } else {
998 - $client = $client_ids;
999 - }
1013 + $site_ids = array_filter(
1014 + $site_ids,
1015 + function ( $e ) {
1016 + return ( is_numeric( $e ) && 0 < $e ) ? true : false;
1017 + }
1018 + );
1000 1019
1001 - $params['client'] = $client;
1020 + $table_wp = esc_sql( $this->table_name( 'wp' ) );
1002 1021
1003 - return MainWP_DB::instance()->get_websites_for_current_user( $params );
1004 - }
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 + }
1005 1032
1006 - /**
1007 - * Method get_number_sites_of_client.
1008 - *
1009 - * Get client by.
1010 - *
1011 - * @param int $client_id Client id.
1012 - *
1013 - * @return int Number of sites.
1014 - */
1015 - public function get_number_sites_of_client( $client_id ) {
1016 - if ( empty( $client_id ) ) {
1017 - return false;
1018 - }
1019 - 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 ) );
1020 - }
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 ) {
1021 1042
1022 - /**
1023 - * Method count_total_clients.
1024 - *
1025 - * Count total of Clients.
1026 - *
1027 - * @return int Total number.
1028 - */
1029 - public function count_total_clients() {
1030 - return $this->wpdb->get_var( 'SELECT COUNT(client_id) FROM ' . $this->table_name( 'wp_clients' ) );
1031 - }
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' ) );
1032 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 + }
1033 1058
1034 - /**
1035 - * Method add_client_field.
1036 - *
1037 - * Add client field.
1038 - *
1039 - * @param mixed $field Client fields data.
1040 - *
1041 - * @return mixed bool|results.
1042 - */
1043 - public function add_client_field( $field ) {
1044 - if ( ! empty( $field['field_name'] ) && isset( $field['client_id'] ) ) {
1045 - if ( $this->get_client_fields_by( 'field_name', $field['field_name'], $field['client_id'] ) ) { // field name existed for the client can not create.
1046 - return false;
1047 - }
1048 - if ( $this->wpdb->insert( $this->table_name( 'wp_clients_fields' ), $field ) ) {
1049 - return $this->get_client_fields_by( 'field_id', $this->wpdb->insert_id );
1050 - }
1051 - }
1052 - return false;
1053 - }
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 + }
1054 1065
1055 - /**
1056 - * Method update_client_field.
1057 - *
1058 - * Update client field.
1059 - *
1060 - * @param int $field_id field id.
1061 - * @param array $field field data.
1062 - *
1063 - * @return mixed|false field.
1064 - */
1065 - public function update_client_field( $field_id, $field ) {
1066 - if ( $field_id && ! empty( $field['field_name'] ) ) {
1067 - $current = $this->get_client_fields_by( 'field_id', $field_id );
1068 - if ( $current ) {
1069 - if ( $this->wpdb->update( $this->table_name( 'wp_clients_fields' ), $field, array( 'field_id' => $field_id ) ) ) {
1070 - return $this->get_client_fields_by( 'field_id', $current->field_id );
1071 - }
1072 - }
1073 - }
1074 - return false;
1075 - }
1066 + $this->delete_client_contacts_by_client_id( $client_id );
1076 1067
1077 - /**
1078 - * Method update_client_field_value.
1079 - *
1080 - * Update client field value.
1081 - *
1082 - * @param int $field_id field id.
1083 - * @param mixed $value field value.
1084 - * @param int $client_id client id.
1085 - *
1086 - * @return mixed|false field data.
1087 - */
1088 - public function update_client_field_value( $field_id, $value, $client_id ) {
1089 - if ( ! empty( $field_id ) ) {
1090 - $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 ) );
1091 - if ( $row ) {
1092 - if ( $row->field_value != $value ) { //phpcs:ignore -- to valid.
1093 - $this->wpdb->update( $this->table_name( 'wp_clients_field_values' ), array( 'field_value' => $value ), array( 'value_id' => $row->value_id ) );
1094 - }
1095 - return true;
1096 - } else {
1097 - return $this->wpdb->insert(
1098 - $this->table_name( 'wp_clients_field_values' ),
1099 - array(
1100 - 'field_id' => $field_id,
1101 - 'field_value' => $value,
1102 - 'value_client_id' => $client_id,
1103 - )
1104 - );
1105 - }
1106 - }
1107 - return false;
1108 - }
1068 + $snapshot_info = $this->get_clients_snapshot_info();
1109 1069
1110 - /**
1111 - * Method get_client_fields_by.
1112 - *
1113 - * Get client field.
1114 - *
1115 - * @param string $by by.
1116 - * @param mixed $value field value.
1117 - * @param int $client_id client id.
1118 - *
1119 - * @return mixed|null $field field data.
1120 - */
1121 - 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 );
1122 1082
1123 - if ( empty( $by ) || empty( $value ) ) {
1124 - return null;
1125 - }
1083 + return true;
1084 + }
1085 + return false;
1086 + }
1126 1087
1127 - $sql = '';
1128 1088
1129 - if ( 'client_id' === $by ) {
1130 - $sql = $this->wpdb->prepare( 'SELECT * FROM ' . $this->table_name( 'wp_clients_fields' ) . ' WHERE `client_id`=%d ', $value );
1131 - return $this->wpdb->get_results( $sql );
1132 - }
1089 + /**
1090 + * Get clients snapshot info.
1091 + *
1092 + * @return array
1093 + */
1094 + public function get_clients_snapshot_info() {
1133 1095
1134 - if ( 'field_name' === $by ) {
1135 - $value = str_replace( array( '[', ']' ), '', $value );
1136 - }
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;
1137 1111
1138 - if ( 'field_id' === $by ) {
1139 - $sql = $this->wpdb->prepare( 'SELECT * FROM ' . $this->table_name( 'wp_clients_fields' ) . ' WHERE `field_id`=%d', $value );
1140 - } elseif ( 'field_name' === $by ) {
1141 - $sql = $this->wpdb->prepare( 'SELECT * FROM ' . $this->table_name( 'wp_clients_fields' ) . ' WHERE `field_name` = %s AND `client_id`=%d ', $value, $client_id );
1142 - }
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 + }
1143 1118
1144 - $field = null;
1145 1119
1146 - if ( ! empty( $sql ) ) {
1147 - $field = $this->wpdb->get_row( $sql );
1148 - }
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() ) {
1149 1131
1150 - return $field;
1151 - }
1132 + if ( empty( $client_ids ) ) {
1133 + return false;
1134 + }
1152 1135
1153 - /**
1154 - * Method get_client_fields()
1155 - *
1156 - * Get client fields.
1157 - *
1158 - * @param bool $general Get general fields OR not.
1159 - * @param int $client_id Client id.
1160 - * @param bool $field_name_index index result with field name.
1161 - *
1162 - * @return mixed results.
1163 - */
1164 - public function get_client_fields( $general = true, $client_id = 0, $field_name_index = false ) {
1165 - $where = '';
1136 + if ( ! is_array( $params ) ) {
1137 + $params = array();
1138 + }
1166 1139
1167 - if ( $client_id ) {
1168 - if ( true === $general ) {
1169 - $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 ) . ') ) ';
1170 - } else {
1171 - $where = ' f.client_id = ' . intval( $client_id );
1172 - }
1173 - } elseif ( true === $general ) {
1174 - $where = ' f.client_id = 0';
1175 - }
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 + }
1176 1153
1177 - if ( '' === $where ) {
1178 - return false;
1179 - }
1154 + $params['client'] = $client;
1180 1155
1181 - $gene_results = array();
1156 + return MainWP_DB::instance()->get_websites_for_current_user( $params );
1157 + }
1182 1158
1183 - if ( $general ) {
1184 - // to fix: missing general fields for client without client fields values.
1185 - $gene_sql = 'SELECT f.* FROM ' . $this->table_name( 'wp_clients_fields' ) . ' f WHERE f.client_id = 0 ORDER BY f.field_name ';
1186 - $gene_results = $this->wpdb->get_results( $gene_sql );
1187 - }
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 + }
1188 1175
1189 - if ( $client_id ) { // get fields values of client.
1190 - $sql = 'SELECT f.*, v.field_value as field_value FROM ' . $this->table_name( 'wp_clients_fields' ) . ' f LEFT JOIN ' .
1191 - $this->table_name( 'wp_clients_field_values' ) . ' v ON f.field_id = v.field_id WHERE ' . $where . ' ORDER BY f.field_name ';
1192 - } else {
1193 - $sql = 'SELECT f.* FROM ' . $this->table_name( 'wp_clients_fields' ) . ' f WHERE ' . $where . ' ORDER BY f.field_name '; // value_client_id to compatible result.
1194 - }
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 + }
1195 1187
1196 - $results = $this->wpdb->get_results( $sql );
1197 1188
1198 - $fields_list = array();
1199 - if ( $field_name_index ) {
1200 - if ( $results ) {
1201 - foreach ( $results as $item ) {
1202 - $fields_list[ $item->field_name ] = $item;
1203 - }
1204 - }
1205 - if ( $gene_results ) {
1206 - foreach ( $gene_results as $gene_item ) {
1207 - if ( ! isset( $fields_list[ $gene_item->field_name ] ) ) {
1208 - $gene_item->field_value = '';
1209 - $fields_list[ $gene_item->field_name ] = $gene_item;
1210 - }
1211 - }
1212 - }
1213 - } else {
1214 - $check_list = array();
1215 - if ( $results ) {
1216 - foreach ( $results as $item ) {
1217 - $check_list[ $item->field_name ] = true;
1218 - $fields_list[] = $item;
1219 - }
1220 - }
1221 - if ( $gene_results ) {
1222 - foreach ( $gene_results as $gene_item ) {
1223 - if ( ! isset( $check_list[ $gene_item->field_name ] ) ) {
1224 - $check_list[ $gene_item->field_name ] = true;
1225 - $gene_item->field_value = '';
1226 - $fields_list[] = $gene_item;
1227 - }
1228 - }
1229 - }
1230 - }
1231 - return $fields_list;
1232 - }
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 + }
1233 1212
1234 - /**
1235 - * Suspend - Unsuspended websites.
1236 - *
1237 - * @param int $client_id Client id.
1238 - * @param int $suspend_val Suspend value: 0 or 1.
1239 - *
1240 - * @return int|boolean The result.
1241 - */
1242 - public function suspend_unsuspend_websites_by_client_id( $client_id, $suspend_val ) {
1243 - if ( empty( $client_id ) ) {
1244 - return false;
1245 - }
1246 - return $this->wpdb->query( $this->wpdb->prepare( 'UPDATE ' . $this->table_name( 'wp' ) . ' SET suspended=%d WHERE client_id=%d ', $suspend_val, $client_id ) );
1247 - }
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 + }
1248 1234
1249 - /**
1250 - * Method delete_client_field_by.
1251 - *
1252 - * Delete client field by.
1253 - *
1254 - * @param string $by by.
1255 - * @param mixed $value field value.
1256 - * @param int $client_id client id.
1257 - *
1258 - * @return bool Deleted or not.
1259 - */
1260 - 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 + }
1261 1268
1262 - if ( 'field_id' === $by ) {
1263 - 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.
1264 - if ( $client_id > 0 ) { // individual field value.
1265 - $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.
1266 - } else {
1267 - $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).
1268 - }
1269 - return true;
1270 - }
1271 - }
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 ) {
1272 1281
1273 - return false;
1274 - }
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 );
1275 1287
1276 - /**
1277 - * Method pro_reports_get_tokens()
1278 - *
1279 - * Get pro reports get tokens data.
1280 - *
1281 - * @return mixed results.
1282 - */
1283 - public function pro_reports_get_tokens() {
1284 - return $this->wpdb->get_results( 'SELECT * FROM ' . $this->table_name( 'pro_reports_token' ) . ' WHERE 1 = 1 ORDER BY type DESC, token_name ASC' );
1285 - }
1288 + if ( empty( $by ) || $missing ) {
1289 + return null;
1290 + }
1286 1291
1287 - /**
1288 - * Method pro_reports_get_site_token_values()
1289 - *
1290 - * Get pro reports get tokens values data.
1291 - *
1292 - * @return mixed results.
1293 - */
1294 - public function pro_reports_get_site_token_values() {
1295 - return $this->wpdb->get_results( ' SELECT * FROM ' . $this->table_name( 'pro_reports_site_token' ) . ' WHERE 1 ' );
1296 - }
1292 + $sql = '';
1293 + $table_fields = esc_sql( $this->table_name( 'wp_clients_fields' ) );
1297 1294
1298 - /**
1299 - * Method client_reports_get_tokens()
1300 - *
1301 - * Get client reports get tokens data.
1302 - *
1303 - * @return mixed results.
1304 - */
1305 - public function client_reports_get_tokens() {
1306 - return $this->wpdb->get_results( 'SELECT * FROM ' . $this->table_name( 'client_report_token' ) . ' WHERE 1 = 1 ORDER BY token_name ASC' );
1307 - }
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 + }
1308 1299
1309 - /**
1310 - * Method client_reports_get_site_token_values()
1311 - *
1312 - * Get client reports get tokens values data.
1313 - *
1314 - * @return mixed results.
1315 - */
1316 - public function client_reports_get_site_token_values() {
1317 - return $this->wpdb->get_results( ' SELECT * FROM ' . $this->table_name( 'client_report_site_token' ) . ' WHERE 1 ' );
1318 - }
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 + }
1319 1600 }