PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.2.1
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.2.1
6.2.2 6.2.1 6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 All 155 releases
← All changes | pages/page-mainwp-client.php +2461 -1714 5.0 → 6.2.1 View file →
@@ -8,1897 +8,2644 @@
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_client
14 19 *
15 20 * @uses page-mainwp-bulk-add::MainWP_Bulk_Add()
16 21 */
17 -class MainWP_Client {
22 +class MainWP_Client { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
18 23
19 - /**
20 - * Get Class Name
21 - *
22 - * @return string __CLASS__
23 - */
24 - public static function get_class_name() {
25 - return __CLASS__;
26 - }
24 + /**
25 + * Get Class Name
26 + *
27 + * @return string __CLASS__
28 + */
29 + public static function get_class_name() {
30 + return __CLASS__;
31 + }
27 32
28 - /**
29 - * Current page.
30 - *
31 - * @static
32 - * @var string $page Current page.
33 - */
34 - public static $page;
33 + /**
34 + * Current page.
35 + *
36 + * @static
37 + * @var string $page Current page.
38 + */
39 + public static $page;
35 40
36 - /**
37 - * Public static varable to hold Subpages information.
38 - *
39 - * @var array $subPages
40 - */
41 - public static $subPages;
41 + /**
42 + * Public static varable to hold Subpages information.
43 + *
44 + * @var array $subPages
45 + */
46 + public static $subPages;
42 47
43 48
44 - /**
45 - * Magage Sites table
46 - *
47 - * @var $itemsTable Magage Sites table.
48 - */
49 - public static $itemsTable;
49 + /**
50 + * Magage Sites table
51 + *
52 + * @var $itemsTable Magage Sites table.
53 + */
54 + public static $itemsTable;
50 55
51 - /**
52 - * Method init()
53 - *
54 - * Initiate hooks for the clients page.
55 - */
56 - public static function init() {
57 - /**
58 - * This hook allows you to render the client page header via the 'mainwp_pageheader_client' action.
59 - *
60 - * This hook is normally used in the same context of 'mainwp_pageheader_client'
61 - *
62 - * @see \MainWP_client::render_header
63 - */
64 - add_action( 'mainwp_pageheader_client', array( self::get_class_name(), 'render_header' ) );
56 + /**
57 + * Method init()
58 + *
59 + * Initiate hooks for the clients page.
60 + */
61 + public static function init() {
62 + /**
63 + * This hook allows you to render the client page header via the 'mainwp_pageheader_client' action.
64 + *
65 + * This hook is normally used in the same context of 'mainwp_pageheader_client'
66 + *
67 + * @see \MainWP_client::render_header
68 + */
69 + add_action( 'mainwp_pageheader_client', array( static::get_class_name(), 'render_header' ) );
65 70
66 - /**
67 - * This hook allows you to render the client page footer via the 'mainwp_pagefooter_client' action.
68 - *
69 - * This hook is normally used in the same context of 'mainwp_pagefooter_client'
70 - *
71 - * @see \MainWP_client::render_footer
72 - */
73 - add_action( 'mainwp_pagefooter_client', array( self::get_class_name(), 'render_footer' ) );
71 + /**
72 + * This hook allows you to render the client page footer via the 'mainwp_pagefooter_client' action.
73 + *
74 + * This hook is normally used in the same context of 'mainwp_pagefooter_client'
75 + *
76 + * @see \MainWP_client::render_footer
77 + */
78 + add_action( 'mainwp_pagefooter_client', array( static::get_class_name(), 'render_footer' ) );
74 79
75 - add_action( 'mainwp_help_sidebar_content', array( self::get_class_name(), 'mainwp_help_content' ) );
76 - }
80 + MainWP_Post_Handler::instance()->add_action( 'mainwp_add_edit_client_upload_client_icon', array( static::class, 'ajax_upload_client_icon' ) );
81 + MainWP_Post_Handler::instance()->add_action( 'mainwp_add_edit_contact_upload_contact_icon', array( static::class, 'ajax_upload_contact_icon' ) );
82 + }
77 83
78 - /**
79 - * Method init_menu()
80 - *
81 - * Initiate menu.
82 - *
83 - * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
84 - */
85 - public static function init_menu() {
86 - self::$page = add_submenu_page(
87 - 'mainwp_tab',
88 - esc_html__( 'Clients', 'mainwp' ),
89 - '<span id="mainwp-clients">' . esc_html__( 'Clients', 'mainwp' ) . '</span>',
90 - 'read',
91 - 'ManageClients',
92 - array(
93 - self::get_class_name(),
94 - 'render_manage_clients',
95 - )
96 - );
84 + /**
85 + * Method init_menu()
86 + *
87 + * Initiate menu.
88 + *
89 + * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
90 + */
91 + public static function init_menu() {
92 + static::$page = add_submenu_page(
93 + 'mainwp_tab',
94 + esc_html__( 'Clients', 'mainwp' ),
95 + '<span id="mainwp-clients">' . esc_html__( 'Clients', 'mainwp' ) . '</span>',
96 + 'read',
97 + 'ManageClients',
98 + array(
99 + static::get_class_name(),
100 + 'render_manage_clients',
101 + )
102 + );
97 103
98 - add_submenu_page(
99 - 'mainwp_tab',
100 - esc_html__( 'Clients', 'mainwp' ),
101 - '<div class="mainwp-hidden">' . esc_html__( 'Add Client', 'mainwp' ) . '</div>',
102 - 'read',
103 - 'ClientAddNew',
104 - array(
105 - self::get_class_name(),
106 - 'render_add_client',
107 - )
108 - );
104 + add_submenu_page(
105 + 'mainwp_tab',
106 + esc_html__( 'Clients', 'mainwp' ),
107 + '<div class="mainwp-hidden">' . esc_html__( 'Add Client', 'mainwp' ) . '</div>',
108 + 'read',
109 + 'ClientAddNew',
110 + array(
111 + static::get_class_name(),
112 + 'render_add_client',
113 + )
114 + );
109 115
110 - add_submenu_page(
111 - 'mainwp_tab',
112 - esc_html__( 'Clients', 'mainwp' ),
113 - '<div class="mainwp-hidden">' . esc_html__( 'Client Fields', 'mainwp' ) . '</div>',
114 - 'read',
115 - 'ClientAddField',
116 - array(
117 - self::get_class_name(),
118 - 'render_client_fields',
119 - )
120 - );
116 + add_submenu_page(
117 + 'mainwp_tab',
118 + esc_html__( 'Clients', 'mainwp' ),
119 + '<div class="mainwp-hidden">' . esc_html__( 'Import Clients', 'mainwp' ) . '</div>',
120 + 'read',
121 + 'ClientImport',
122 + array(
123 + static::get_class_name(),
124 + 'render_import_clients',
125 + )
126 + );
121 127
122 - /**
123 - * This hook allows you to add extra sub pages to the client page via the 'mainwp-getsubpages-client' filter.
124 - *
125 - * @link http://codex.mainwp.com/#mainwp-getsubpages-client
126 - */
127 - $sub_pages = array();
128 - self::$subPages = apply_filters( 'mainwp_getsubpages_client', $sub_pages );
128 + add_submenu_page(
129 + 'mainwp_tab',
130 + esc_html__( 'Clients', 'mainwp' ),
131 + '<div class="mainwp-hidden">' . esc_html__( 'Client Fields', 'mainwp' ) . '</div>',
132 + 'read',
133 + 'ClientAddField',
134 + array(
135 + static::get_class_name(),
136 + 'render_client_fields',
137 + )
138 + );
129 139
130 - if ( isset( self::$subPages ) && is_array( self::$subPages ) ) {
131 - foreach ( self::$subPages as $subPage ) {
132 - if ( MainWP_Menu::is_disable_menu_item( 3, 'ManageClients' . $subPage['slug'] ) ) {
133 - continue;
134 - }
135 - add_submenu_page( 'mainwp_tab', $subPage['title'], '<div class="mainwp-hidden">' . esc_html( $subPage['title'] ) . '</div>', 'read', 'ManageClients' . $subPage['slug'], $subPage['callback'] );
136 - }
137 - }
140 + /**
141 + * This hook allows you to add extra sub pages to the client page via the 'mainwp-getsubpages-client' filter.
142 + *
143 + * @link http://codex.mainwp.com/#mainwp-getsubpages-client
144 + */
145 + $sub_pages = array();
146 + static::$subPages = apply_filters( 'mainwp_getsubpages_client', $sub_pages );
138 147
139 - self::init_left_menu( self::$subPages );
148 + if ( isset( static::$subPages ) && is_array( static::$subPages ) ) {
149 + foreach ( static::$subPages as $subPage ) {
150 + if ( MainWP_Menu::is_disable_menu_item( 3, 'ManageClients' . $subPage['slug'] ) ) {
151 + continue;
152 + }
153 + add_submenu_page( 'mainwp_tab', $subPage['title'], '<div class="mainwp-hidden">' . esc_html( $subPage['title'] ) . '</div>', 'read', 'ManageClients' . $subPage['slug'], $subPage['callback'] );
154 + }
155 + }
140 156
141 - add_action( 'load-' . self::$page, array( self::get_class_name(), 'on_load_page' ) );
142 - }
157 + static::init_left_menu( static::$subPages );
143 158
144 - /**
145 - * Method on_load_page()
146 - *
147 - * Run on page load.
148 - */
149 - public static function on_load_page() {
159 + add_action( 'load-' . static::$page, array( static::get_class_name(), 'on_load_page' ) );
160 + }
150 161
151 - if ( isset( $_GET['client_id'] ) && ! empty( $_GET['client_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
152 - MainWP_Client_Overview::instance()->on_load_page( self::$page );
153 - return;
154 - }
162 + /**
163 + * Method on_load_page()
164 + *
165 + * Run on page load.
166 + */
167 + public static function on_load_page() {
155 168
156 - add_filter( 'mainwp_header_actions_right', array( self::get_class_name(), 'screen_options' ), 10, 2 );
169 + if ( isset( $_GET['client_id'] ) && ! empty( $_GET['client_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
170 + MainWP_Client_Overview::instance()->on_load_page( static::$page );
171 + return;
172 + }
157 173
158 - self::$itemsTable = new MainWP_Client_List_Table();
159 - }
174 + add_filter( 'mainwp_header_actions_right', array( static::get_class_name(), 'screen_options' ), 10, 2 );
160 175
161 - /**
162 - * Method screen_options()
163 - *
164 - * Create Page Settings button.
165 - *
166 - * @param mixed $input Page Settings button HTML.
167 - *
168 - * @return mixed Screen sptions button.
169 - */
170 - public static function screen_options( $input ) {
171 - return $input .
172 - '<a class="ui button basic icon" onclick="mainwp_manage_clients_screen_options(); return false;" data-inverted="" data-position="bottom right" href="#" target="_blank" data-tooltip="' . esc_html__( 'Page Settings', 'mainwp' ) . '">
173 - <i class="cog icon"></i>
174 - </a>';
175 - }
176 + static::$itemsTable = new MainWP_Client_List_Table();
177 + }
176 178
177 - /**
178 - * Initiates sub pages menu.
179 - *
180 - * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
181 - */
182 - public static function init_subpages_menu() {
183 - ?>
184 - <div id="menu-mainwp-Clients" class="mainwp-submenu-wrapper">
185 - <div class="wp-submenu sub-open" style="">
186 - <div class="mainwp_boxout">
187 - <div class="mainwp_boxoutin"></div>
188 - <?php if ( mainwp_current_user_have_right( 'dashboard', 'manage_clients' ) ) { ?>
189 - <a href="<?php echo esc_url( admin_url( 'admin.php?page=ManageClients' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'Clients', 'mainwp' ); ?></a>
190 - <?php } ?>
191 - <?php if ( ! MainWP_Menu::is_disable_menu_item( 3, 'ClientAddNew' ) ) { ?>
192 - <a href="<?php echo esc_url( admin_url( 'admin.php?page=ClientAddNew' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'Add Client', 'mainwp' ); ?></a>
193 - <?php } ?>
194 - <?php if ( ! MainWP_Menu::is_disable_menu_item( 3, 'ClientAddField' ) ) { ?>
195 - <a href="<?php echo esc_url( admin_url( 'admin.php?page=ClientAddField' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'Client Properties', 'mainwp' ); ?></a>
196 - <?php } ?>
197 - <?php
198 - if ( isset( self::$subPages ) && is_array( self::$subPages ) ) {
199 - foreach ( self::$subPages as $subPage ) {
200 - if ( MainWP_Menu::is_disable_menu_item( 3, 'ManageClients' . $subPage['slug'] ) ) {
201 - continue;
202 - }
203 - ?>
204 - <a href="<?php echo esc_url( admin_url( 'admin.php?page=ManageClients' . $subPage['slug'] ) ); ?>" class="mainwp-submenu"><?php echo esc_html( $subPage['title'] ); ?></a>
205 - <?php
206 - }
207 - }
208 - ?>
209 - </div>
210 - </div>
211 - </div>
212 - <?php
213 - }
179 + /**
180 + * Method screen_options()
181 + *
182 + * Create Page Settings button.
183 + *
184 + * @param mixed $input Page Settings button HTML.
185 + *
186 + * @return mixed Screen sptions button.
187 + */
188 + public static function screen_options( $input ) {
189 + return $input .
190 + '<a class="ui button basic icon" onclick="mainwp_manage_clients_screen_options(); return false;" data-inverted="" data-position="bottom right" href="#" target="_blank" data-tooltip="' . esc_html__( 'Page Settings', 'mainwp' ) . '" aria-label="' . esc_html__( 'Page Settings', 'mainwp' ) . '">
191 + <i class="cog icon"></i>
192 + </a>';
193 + }
214 194
215 - /**
216 - * Initiates Clients menu.
217 - *
218 - * @param array $subPages Sub pages array.
219 - *
220 - * @uses \MainWP\Dashboard\MainWP_Menu::add_left_menu()
221 - * @uses \MainWP\Dashboard\MainWP_Menu::init_subpages_left_menu()
222 - * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
223 - */
224 - public static function init_left_menu( $subPages = array() ) {
225 - MainWP_Menu::add_left_menu(
226 - array(
227 - 'title' => esc_html__( 'Clients', 'mainwp' ),
228 - 'parent_key' => 'mainwp_tab',
229 - 'slug' => 'ManageClients',
230 - 'href' => 'admin.php?page=ManageClients',
231 - 'icon' => '<i class="users icon"></i>',
232 - 'desc' => 'Manage clients on your child sites',
233 - ),
234 - 0
235 - );
195 + /**
196 + * Initiates sub pages menu.
197 + *
198 + * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
199 + */
200 + public static function init_subpages_menu() {
201 + ?>
202 + <div id="menu-mainwp-Clients" class="mainwp-submenu-wrapper">
203 + <div class="wp-submenu sub-open" style="">
204 + <div class="mainwp_boxout">
205 + <div class="mainwp_boxoutin"></div>
206 + <?php if ( \mainwp_current_user_can( 'dashboard', 'manage_clients' ) ) { ?>
207 + <a href="<?php echo esc_url( admin_url( 'admin.php?page=ManageClients' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'Clients', 'mainwp' ); ?></a>
208 + <?php } ?>
209 + <?php if ( ! MainWP_Menu::is_disable_menu_item( 3, 'ClientAddNew' ) ) { ?>
210 + <a href="<?php echo esc_url( admin_url( 'admin.php?page=ClientAddNew' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'Add Client', 'mainwp' ); ?></a>
211 + <?php } ?>
212 + <?php if ( ! MainWP_Menu::is_disable_menu_item( 3, 'ClientImport' ) ) { ?>
213 + <a href="<?php echo esc_url( admin_url( 'admin.php?page=ClientImport' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'Import Clients', 'mainwp' ); ?></a>
214 + <?php } ?>
215 + <?php if ( ! MainWP_Menu::is_disable_menu_item( 3, 'ClientAddField' ) ) { ?>
216 + <a href="<?php echo esc_url( admin_url( 'admin.php?page=ClientAddField' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'Client Properties', 'mainwp' ); ?></a>
217 + <?php } ?>
218 + <?php
219 + if ( isset( static::$subPages ) && is_array( static::$subPages ) ) {
220 + foreach ( static::$subPages as $subPage ) {
221 + if ( MainWP_Menu::is_disable_menu_item( 3, 'ManageClients' . $subPage['slug'] ) ) {
222 + continue;
223 + }
224 + ?>
225 + <a href="<?php echo esc_url( admin_url( 'admin.php?page=ManageClients' . $subPage['slug'] ) ); ?>" class="mainwp-submenu"><?php echo esc_html( $subPage['title'] ); ?></a>
226 + <?php
227 + }
228 + }
229 + ?>
230 + </div>
231 + </div>
232 + </div>
233 + <?php
234 + }
236 235
237 - $init_sub_subleftmenu = array(
238 - array(
239 - 'title' => esc_html__( 'Clients', 'mainwp' ),
240 - 'parent_key' => 'ManageClients',
241 - 'href' => 'admin.php?page=ManageClients',
242 - 'slug' => 'ManageClients',
243 - 'right' => 'manage_clients',
244 - 'leftsub_order_level2' => 1,
245 - ),
246 - array(
247 - 'title' => esc_html__( 'Add Client', 'mainwp' ),
248 - 'parent_key' => 'ManageClients',
249 - 'href' => 'admin.php?page=ClientAddNew',
250 - 'slug' => 'ClientAddNew',
251 - 'right' => '',
252 - 'leftsub_order_level2' => 2,
253 - ),
254 - array(
255 - 'title' => esc_html__( 'Client Fields', 'mainwp' ),
256 - 'parent_key' => 'ManageClients',
257 - 'href' => 'admin.php?page=ClientAddField',
258 - 'slug' => 'ClientAddField',
259 - 'right' => '',
260 - 'leftsub_order_level2' => 3,
261 - ),
262 - );
236 + /**
237 + * Initiates Clients menu.
238 + *
239 + * @param array $subPages Sub pages array.
240 + *
241 + * @uses \MainWP\Dashboard\MainWP_Menu::add_left_menu()
242 + * @uses \MainWP\Dashboard\MainWP_Menu::init_subpages_left_menu()
243 + * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
244 + */
245 + public static function init_left_menu( $subPages = array() ) {
246 + MainWP_Menu::add_left_menu(
247 + array(
248 + 'title' => esc_html__( 'Clients', 'mainwp' ),
249 + 'parent_key' => 'mainwp_tab',
250 + 'slug' => 'ManageClients',
251 + 'href' => 'admin.php?page=ManageClients',
252 + 'icon' => '<i class="users icon"></i>',
253 + 'desc' => 'Manage clients on your child sites',
254 + ),
255 + 0
256 + );
263 257
264 - MainWP_Menu::init_subpages_left_menu( $subPages, $init_sub_subleftmenu, 'ManageClients', 'ManageClients' );
258 + $init_sub_subleftmenu = array(
259 + array(
260 + 'title' => esc_html__( 'Clients', 'mainwp' ),
261 + 'parent_key' => 'ManageClients',
262 + 'href' => 'admin.php?page=ManageClients',
263 + 'slug' => 'ManageClients',
264 + 'right' => 'manage_clients',
265 + 'leftsub_order_level2' => 1,
266 + ),
267 + array(
268 + 'title' => esc_html__( 'Add Client', 'mainwp' ),
269 + 'parent_key' => 'ManageClients',
270 + 'href' => 'admin.php?page=ClientAddNew',
271 + 'slug' => 'ClientAddNew',
272 + 'right' => '',
273 + 'leftsub_order_level2' => 2,
274 + ),
275 + array(
276 + 'title' => esc_html__( 'Import Clients', 'mainwp' ),
277 + 'parent_key' => 'ManageClients',
278 + 'href' => 'admin.php?page=ClientImport',
279 + 'slug' => 'ClientImport',
280 + 'right' => '',
281 + 'leftsub_order_level2' => 3,
282 + ),
283 + array(
284 + 'title' => esc_html__( 'Client Fields', 'mainwp' ),
285 + 'parent_key' => 'ManageClients',
286 + 'href' => 'admin.php?page=ClientAddField',
287 + 'slug' => 'ClientAddField',
288 + 'right' => '',
289 + 'leftsub_order_level2' => 4,
290 + ),
291 + );
265 292
266 - foreach ( $init_sub_subleftmenu as $item ) {
267 - if ( MainWP_Menu::is_disable_menu_item( 3, $item['slug'] ) ) {
268 - continue;
269 - }
270 - MainWP_Menu::add_left_menu( $item, 2 );
271 - }
272 - }
293 + MainWP_Menu::init_subpages_left_menu( $subPages, $init_sub_subleftmenu, 'ManageClients', 'ManageClients' );
273 294
274 - /**
275 - * Method render_header()
276 - *
277 - * Render Clients page header.
278 - *
279 - * @param string $shownPage The page slug shown at this moment.
280 - *
281 - * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
282 - * @uses \MainWP\Dashboard\MainWP_UI::render_top_header()
283 - * @uses \MainWP\Dashboard\MainWP_UI::render_page_navigation()
284 - */
285 - public static function render_header( $shownPage = '' ) { // phpcs:ignore -- Current complexity is the only way to achieve desired results, pull request solutions appreciated.
286 - // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
287 - $client_id = isset( $_GET['client_id'] ) ? intval( $_GET['client_id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
295 + foreach ( $init_sub_subleftmenu as $item ) {
296 + if ( MainWP_Menu::is_disable_menu_item( 3, $item['slug'] ) ) {
297 + continue;
298 + }
299 + MainWP_Menu::add_left_menu( $item, 2 );
300 + }
301 + }
288 302
289 - $params = array(
290 - 'title' => esc_html__( 'Clients', 'mainwp' ),
291 - 'which' => 'overview' === $shownPage ? 'page_clients_overview' : '',
292 - );
303 + /**
304 + * Method ajax_upload_client_icon()
305 + */
306 + public static function ajax_upload_client_icon() { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR - complexity.
307 + MainWP_Post_Handler::instance()->secure_request( 'mainwp_add_edit_client_upload_client_icon' );
293 308
294 - $client = false;
295 - if ( $client_id ) {
296 - $client = MainWP_DB_Client::instance()->get_wp_client_by( 'client_id', $client_id );
297 - if ( $client ) {
298 - $client_pic = isset( $client->image ) ? MainWP_Client_Handler::get_client_image_url( $client->image ) : '';
299 - if ( '' !== $client_pic ) {
300 - $client_pic = '<img src="' . esc_attr( $client_pic ) . '" class="ui circurlar avatar image" />';
301 - } else {
302 - $client_pic = '<i class="user circle icon"></i>'; // phpcs:ignore -- Prevent modify WP icon.
303 - }
304 - $params['title'] = $client_pic . '<div class="content">' . $client->name . '<div class="sub header"><a href="mailto:' . $client->client_email . '" target="_blank" style="color:#666!important;font-weight:normal!important;">' . $client->client_email . '</a> </div></div>';
305 - }
306 - }
309 + // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
310 + $iconfile_slug = isset( $_POST['iconFileSlug'] ) ? sanitize_text_field( wp_unslash( $_POST['iconFileSlug'] ) ) : '';
311 + $delete = isset( $_POST['delete'] ) ? intval( $_POST['delete'] ) : 0;
312 + $client_id = isset( $_POST['iconItemId'] ) ? intval( $_POST['iconItemId'] ) : 0;
313 + $delnonce = isset( $_POST['delnonce'] ) ? sanitize_key( $_POST['delnonce'] ) : '';
307 314
308 - MainWP_UI::render_top_header( $params );
315 + if ( $delete ) {
316 + if ( ! MainWP_System_Utility::is_valid_custom_nonce( 'client', $iconfile_slug, $delnonce ) ) {
317 + die( 'Invalid nonce!' );
318 + }
319 + if ( $client_id ) {
320 + $client = MainWP_DB_Client::instance()->get_wp_client_by( 'client_id', $client_id );
321 + if ( $client && ! empty( $client->image ) ) {
322 + $update = array(
323 + 'image' => '',
324 + 'client_id' => $client_id,
325 + );
326 + MainWP_DB_Client::instance()->update_client( $update );
327 + MainWP_Utility::instance()->delete_uploaded_icon_file( 'client-images', $client->image );
328 + }
329 + } elseif ( ! empty( $iconfile_slug ) ) {
330 + MainWP_Utility::instance()->delete_uploaded_icon_file( 'client-images', $iconfile_slug );
331 + }
332 + wp_die( wp_json_encode( array( 'result' => 'success' ) ) );
333 + }
309 334
310 - $renderItems = array();
335 + $output = isset( $_FILES['mainwp_upload_icon_uploader'] ) ? MainWP_System_Utility::handle_upload_image( 'client-images', $_FILES['mainwp_upload_icon_uploader'] ) : null;
336 + // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
311 337
312 - if ( mainwp_current_user_have_right( 'dashboard', 'manage_clients' ) ) {
313 - $renderItems[] = array(
314 - 'title' => esc_html__( 'Clients', 'mainwp' ),
315 - 'href' => 'admin.php?page=ManageClients',
316 - 'active' => ( '' === $shownPage ) ? true : false,
317 - );
318 - }
338 + $uploaded_icon = 'NOTCHANGE';
339 + if ( is_array( $output ) && isset( $output['filename'] ) && ! empty( $output['filename'] ) ) {
340 + $uploaded_icon = $output['filename'];
341 + }
319 342
320 - if ( $client_id ) {
321 - $renderItems[] = array(
322 - 'title' => $client ? $client->name : esc_html__( 'Overview', 'mainwp' ),
323 - 'href' => 'admin.php?page=ManageClients&client_id=' . $client_id,
324 - 'active' => ( 'overview' === $shownPage ),
325 - );
326 - $renderItems[] = array(
327 - 'title' => $client ? esc_html__( 'Edit', 'mainwp' ) . ' ' . $client->name : esc_html__( 'Edit Client', 'mainwp' ),
328 - 'href' => 'admin.php?page=ClientAddNew&client_id=' . $client_id,
329 - 'active' => ( 'Edit' === $shownPage ) ? true : false,
330 - );
331 - }
343 + if ( 'NOTCHANGE' !== $uploaded_icon ) {
344 + $dirs = MainWP_System_Utility::get_mainwp_dir( 'client-images', true );
345 + $icon_url = $dirs[1] . $uploaded_icon;
346 + wp_die(
347 + wp_json_encode(
348 + array(
349 + 'result' => 'success',
350 + 'iconfile' => esc_html( $uploaded_icon ),
351 + 'iconsrc' => esc_html( $icon_url ),
352 + 'iconimg' => '<img class="ui circular image" src="' . esc_attr( $icon_url ) . '" style="width:28px;height:auto;display:inline-block;" alt="Client custom icon">',
353 + 'iconnonce' => MainWP_System_Utility::get_custom_nonce( 'client', esc_html( $uploaded_icon ) ),
354 + )
355 + )
356 + );
357 + } else {
358 + $result = array(
359 + 'result' => 'failed',
360 + );
361 + $error = MainWP_Post_Handler::get_upload_icon_error( $output );
362 + if ( ! empty( $error ) ) {
363 + $result['error'] = esc_html( $error );
364 + }
365 + wp_die( wp_json_encode( $result ) );
366 + }
367 + }
332 368
333 - if ( ! MainWP_Menu::is_disable_menu_item( 3, 'ClientAddNew' ) ) {
334 - $renderItems[] = array(
335 - 'title' => esc_html__( 'Add Client', 'mainwp' ),
336 - 'href' => 'admin.php?page=ClientAddNew',
337 - 'active' => ( 'Add' === $shownPage ) ? true : false,
338 - );
339 - }
340 369
341 - if ( ! MainWP_Menu::is_disable_menu_item( 3, 'ClientAddField' ) ) {
342 - $renderItems[] = array(
343 - 'title' => esc_html__( 'Client Fields', 'mainwp' ),
344 - 'href' => 'admin.php?page=ClientAddField',
345 - 'active' => ( 'AddField' === $shownPage ) ? true : false,
346 - );
347 - }
370 + /**
371 + * Method ajax_upload_contact_icon()
372 + */
373 + public static function ajax_upload_contact_icon() { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR - complexity.
374 + MainWP_Post_Handler::instance()->secure_request( 'mainwp_add_edit_contact_upload_contact_icon' );
375 + // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
376 + $iconfile_slug = isset( $_POST['iconFileSlug'] ) ? sanitize_text_field( wp_unslash( $_POST['iconFileSlug'] ) ) : '';
377 + $delete = isset( $_POST['delete'] ) ? intval( $_POST['delete'] ) : 0;
378 + $contact_id = isset( $_POST['iconItemId'] ) ? intval( $_POST['iconItemId'] ) : 0;
379 + $delnonce = isset( $_POST['delnonce'] ) ? sanitize_key( $_POST['delnonce'] ) : '';
348 380
349 - if ( isset( self::$subPages ) && is_array( self::$subPages ) ) {
350 - foreach ( self::$subPages as $subPage ) {
351 - if ( MainWP_Menu::is_disable_menu_item( 3, 'ManageClients' . $subPage['slug'] ) ) {
352 - continue;
353 - }
381 + if ( $delete ) {
382 + if ( ! MainWP_System_Utility::is_valid_custom_nonce( 'contact', $iconfile_slug, $delnonce ) ) {
383 + die( 'Invalid nonce!' );
384 + }
385 + if ( $contact_id ) {
386 + $contact_data = MainWP_DB_Client::instance()->get_wp_client_contact_by( 'contact_id', $contact_id );
387 + if ( $contact_data && ! empty( $contact_data->contact_image ) ) {
388 + $update = array(
389 + 'contact_image' => '',
390 + 'contact_id' => $contact_id,
391 + );
392 + MainWP_DB_Client::instance()->update_client_contact( $update );
393 + MainWP_Utility::instance()->delete_uploaded_icon_file( 'client-images', $contact_data->contact_image );
394 + }
395 + } elseif ( ! empty( $iconfile_slug ) ) {
396 + MainWP_Utility::instance()->delete_uploaded_icon_file( 'client-images', $iconfile_slug );
397 + }
398 + wp_die( wp_json_encode( array( 'result' => 'success' ) ) );
399 + }
354 400
355 - if ( ! empty( $subPage['individual_settings'] ) && empty( $client_id ) ) {
356 - continue;
357 - }
401 + $output = isset( $_FILES['mainwp_upload_icon_uploader'] ) ? MainWP_System_Utility::handle_upload_image( 'client-images', $_FILES['mainwp_upload_icon_uploader'] ) : null;
402 + // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
358 403
359 - $client_param = $client_id ? '&client_id=' . $client_id : '';
360 - $item = array();
361 - $item['title'] = $subPage['title'];
362 - $item['href'] = 'admin.php?page=ManageClients' . $subPage['slug'] . $client_param;
363 - $item['active'] = ( $subPage['slug'] === $shownPage ) ? true : false;
364 - $renderItems[] = $item;
365 - }
366 - }
367 - // phpcs:enable
368 - MainWP_UI::render_page_navigation( $renderItems );
369 - }
404 + $uploaded_icon = 'NOTCHANGE';
405 + if ( is_array( $output ) && isset( $output['filename'] ) && ! empty( $output['filename'] ) ) {
406 + $uploaded_icon = $output['filename'];
407 + }
370 408
371 - /**
372 - * Method render_footer()
373 - *
374 - * Render Clients page footer. Closes the page container.
375 - */
376 - public static function render_footer() {
377 - echo '</div>';
378 - }
409 + if ( 'NOTCHANGE' !== $uploaded_icon ) {
410 + $dirs = MainWP_System_Utility::get_mainwp_dir( 'client-images', true );
411 + $icon_url = $dirs[1] . $uploaded_icon;
412 + wp_die(
413 + wp_json_encode(
414 + array(
415 + 'result' => 'success',
416 + 'iconfile' => esc_html( $uploaded_icon ),
417 + 'iconsrc' => esc_html( $icon_url ),
418 + 'iconimg' => '<img class="ui circular image" src="' . esc_attr( $icon_url ) . '" style="width:32px;height:auto;display:inline-block;" alt="Client custom icon">',
419 + 'iconnonce' => MainWP_System_Utility::get_custom_nonce( 'contact', esc_html( $uploaded_icon ) ),
420 + )
421 + )
422 + );
423 + } else {
424 + $result = array(
425 + 'result' => 'failed',
426 + );
427 + $error = MainWP_Post_Handler::get_upload_icon_error( $output );
428 + if ( ! empty( $error ) ) {
429 + $result['error'] = esc_html( $error );
430 + }
431 + wp_die( wp_json_encode( $result ) );
432 + }
433 + }
379 434
380 - /**
381 - * Renders manage clients dashboard.
382 - *
383 - * @return void
384 - */
385 - public static function render_manage_clients() {
386 435
387 - if ( isset( $_GET['client_id'] ) && ! empty( $_GET['client_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
388 - MainWP_Client_Overview::instance()->on_show_page( intval( $_GET['client_id'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
389 - return;
390 - }
436 + /**
437 + * Method render_header()
438 + *
439 + * Render Clients page header.
440 + *
441 + * @param string $shownPage The page slug shown at this moment.
442 + *
443 + * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
444 + * @uses \MainWP\Dashboard\MainWP_UI::render_top_header()
445 + * @uses \MainWP\Dashboard\MainWP_UI::render_page_navigation()
446 + */
447 + public static function render_header( $shownPage = '' ) { // phpcs:ignore -- NOSONAR -Current complexity is the only way to achieve desired results, pull request solutions appreciated.
448 + // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
449 + $client_id = isset( $_GET['client_id'] ) ? intval( $_GET['client_id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
391 450
392 - if ( ! mainwp_current_user_have_right( 'dashboard', 'manage_clients' ) ) {
393 - mainwp_do_not_have_permissions( esc_html__( 'manage clients', 'mainwp' ) );
394 - return;
395 - }
451 + $params = array(
452 + 'title' => esc_html__( 'Clients', 'mainwp' ),
453 + 'which' => 'overview' === $shownPage ? 'page_clients_overview' : '',
454 + );
396 455
397 - self::$itemsTable->prepare_items();
456 + $client = false;
457 + if ( $client_id ) {
458 + $client = MainWP_DB_Client::instance()->get_wp_client_by( 'client_id', $client_id );
459 + if ( $client ) {
460 + $arr_client = MainWP_Utility::map_fields( $client, array( 'image', 'selected_icon_info' ), false ); // array map.
461 + $client_pic = MainWP_Client_Handler::get_client_contact_image( $arr_client );
462 + $params['title'] = $client_pic . '<div class="content">' . $client->name . '<div class="sub header"><a href="mailto:' . esc_attr( $client->client_email ) . '" target="_blank" style="font-weight:normal!important;">' . $client->client_email . '</a> </div></div>';
463 + }
464 + }
398 465
399 - self::render_header( '' );
400 - self::render_second_top_header();
466 + MainWP_UI::render_top_header( $params );
401 467
402 - ?>
403 - <div id="mainwp-manage-sites-content" class="ui segment">
404 - <div id="mainwp-message-zone" style="display:none;" class="ui message"></div>
405 - <form method="post" class="mainwp-table-container">
406 - <?php
407 - wp_nonce_field( 'mainwp-admin-nonce' );
408 - self::$itemsTable->display();
409 - self::$itemsTable->clear_items();
410 - ?>
411 - </form>
412 - </div>
413 - <?php
414 - self::render_footer( '' );
415 - self::render_screen_options();
416 - }
468 + $renderItems = array();
417 469
418 - /**
419 - * Method render_second_top_header()
420 - *
421 - * Render second top header.
422 - *
423 - * @return void Render second top header html.
424 - */
425 - public static function render_second_top_header() {
426 - ?>
427 - <div class="mainwp-sub-header ui mini form">
428 - <?php
429 - do_action( 'mainwp_manageclients_tabletop' );
430 - ?>
431 - </div>
432 - <?php
433 - }
470 + if ( \mainwp_current_user_can( 'dashboard', 'manage_clients' ) ) {
471 + $renderItems[] = array(
472 + 'title' => esc_html__( 'Clients', 'mainwp' ),
473 + 'href' => 'admin.php?page=ManageClients',
474 + 'active' => ( '' === $shownPage ) ? true : false,
475 + );
476 + }
434 477
478 + if ( $client_id ) {
479 + $renderItems[] = array(
480 + 'title' => $client ? $client->name : esc_html__( 'Operations', 'mainwp' ),
481 + 'href' => 'admin.php?page=ManageClients&client_id=' . $client_id,
482 + 'active' => ( 'overview' === $shownPage ),
483 + );
484 + $renderItems[] = array(
485 + 'title' => $client ? esc_html__( 'Edit', 'mainwp' ) . ' ' . $client->name : esc_html__( 'Edit Client', 'mainwp' ),
486 + 'href' => 'admin.php?page=ClientAddNew&client_id=' . $client_id,
487 + 'active' => ( 'Edit' === $shownPage ) ? true : false,
488 + );
489 + }
435 490
436 - /**
437 - * Renders Edit Clients Modal window.
438 - */
439 - public static function render_update_clients() {
491 + if ( ! MainWP_Menu::is_disable_menu_item( 3, 'ClientAddNew' ) ) {
492 + $renderItems[] = array(
493 + 'title' => esc_html__( 'Add Client', 'mainwp' ),
494 + 'href' => 'admin.php?page=ClientAddNew',
495 + 'active' => ( 'Add' === $shownPage ) ? true : false,
496 + );
497 + }
440 498
441 - ?>
442 - <div id="mainwp-edit-clients-modal" class="ui modal">
443 - <i class="close icon"></i>
444 - <div class="header"><?php esc_html_e( 'Edit client', 'mainwp' ); ?></div>
445 - <div class="ui message"><?php esc_html_e( 'Empty fields will not be passed to child sites.', 'mainwp' ); ?></div>
446 - <form id="update_client_profile">
447 - <?php wp_nonce_field( 'mainwp-admin-nonce' ); ?>
448 - <div class="ui segment">
449 - <div class="ui form">
450 - <h3><?php esc_html_e( 'Name', 'mainwp' ); ?></h3>
451 - <div class="ui grid field">
452 - <label class="six wide column middle aligned"><?php esc_html_e( 'First Name', 'mainwp' ); ?></label>
453 - <div class="ui six wide column">
454 - <div class="ui left labeled input">
455 - <input type="text" name="first_name" id="first_name" value="" class="regular-text" />
456 - </div>
457 - </div>
458 - </div>
499 + if ( ! MainWP_Menu::is_disable_menu_item( 3, 'ClientImport' ) ) {
500 + $renderItems[] = array(
501 + 'title' => esc_html__( 'Import Clients', 'mainwp' ),
502 + 'href' => 'admin.php?page=ClientImport',
503 + 'active' => ( 'Add' === $shownPage ) ? true : false,
504 + );
505 + }
459 506
460 - <div class="ui grid field">
461 - <label class="six wide column middle aligned"><?php esc_html_e( 'Last Name', 'mainwp' ); ?></label>
462 - <div class="ui six wide column">
463 - <div class="ui left labeled input">
464 - <input type="text" name="last_name" id="last_name" value="" class="regular-text" />
465 - </div>
466 - </div>
467 - </div>
507 + if ( ! MainWP_Menu::is_disable_menu_item( 3, 'ClientAddField' ) ) {
508 + $renderItems[] = array(
509 + 'title' => esc_html__( 'Client Fields', 'mainwp' ),
510 + 'href' => 'admin.php?page=ClientAddField',
511 + 'active' => ( 'AddField' === $shownPage ) ? true : false,
512 + );
513 + }
468 514
469 - <div class="ui grid field">
470 - <label class="six wide column middle aligned"><?php esc_html_e( 'Nickname', 'mainwp' ); ?></label>
471 - <div class="ui six wide column">
472 - <div class="ui left labeled input">
473 - <input type="text" name="nickname" id="nickname" value="" class="regular-text" />
474 - </div>
475 - </div>
476 - </div>
515 + if ( isset( static::$subPages ) && is_array( static::$subPages ) ) {
516 + foreach ( static::$subPages as $subPage ) {
517 + if ( MainWP_Menu::is_disable_menu_item( 3, 'ManageClients' . $subPage['slug'] ) ) {
518 + continue;
519 + }
477 520
478 - <div class="ui grid field">
479 - <label class="six wide column middle aligned"><?php esc_html_e( 'Display name publicly as', 'mainwp' ); ?></label>
480 - <div class="ui six wide column">
481 - <div class="ui left labeled input">
482 - <select name="display_name" id="display_name"></select>
483 - </div>
484 - </div>
485 - </div>
521 + if ( ! empty( $subPage['individual_settings'] ) && empty( $client_id ) ) {
522 + continue;
523 + }
486 524
487 - <h3><?php esc_html_e( 'Contact Info', 'mainwp' ); ?></h3>
525 + $client_param = $client_id ? '&client_id=' . $client_id : '';
526 + $item = array();
527 + $item['title'] = $subPage['title'];
528 + $item['href'] = 'admin.php?page=ManageClients' . $subPage['slug'] . $client_param;
529 + $item['active'] = ( $subPage['slug'] === $shownPage ) ? true : false;
530 + $renderItems[] = $item;
531 + }
532 + }
533 + // phpcs:enable
534 + MainWP_UI::render_page_navigation( $renderItems );
535 + }
488 536
489 - <div class="ui grid field">
490 - <label class="six wide column middle aligned"><?php esc_html_e( 'Email', 'mainwp' ); ?></label>
491 - <div class="ui six wide column">
492 - <div class="ui left labeled input">
493 - <input type="email" name="email" id="email" value="" class="regular-text ltr" />
494 - </div>
495 - </div>
496 - </div>
537 + /**
538 + * Method render_footer()
539 + *
540 + * Render Clients page footer. Closes the page container.
541 + */
542 + public static function render_footer() {
543 + echo '</div>';
544 + }
497 545
498 - <div class="ui grid field">
499 - <label class="six wide column middle aligned"><?php esc_html_e( 'Website', 'mainwp' ); ?></label>
500 - <div class="ui six wide column">
501 - <div class="ui left labeled input">
502 - <input type="url" name="url" id="url" value="" class="regular-text code" />
503 - </div>
504 - </div>
505 - </div>
546 + /**
547 + * Renders manage clients dashboard.
548 + *
549 + * @return void
550 + */
551 + public static function render_manage_clients() {
506 552
507 - <h3><?php esc_html_e( 'About the client', 'mainwp' ); ?></h3>
553 + if ( isset( $_GET['client_id'] ) && ! empty( $_GET['client_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
554 + MainWP_Client_Overview::instance()->on_show_page( intval( $_GET['client_id'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
555 + return;
556 + }
508 557
509 - <div class="ui grid field">
510 - <label class="six wide column middle aligned"><?php esc_html_e( 'Biographical Info', 'mainwp' ); ?></label>
511 - <div class="ui six wide column">
512 - <div class="ui left labeled input">
513 - <textarea name="description" id="description" rows="5" cols="30"></textarea>
514 - <p class="description"><?php esc_html_e( 'Share a little biographical information to fill out your profile. This may be shown publicly.', 'mainwp' ); ?></p>
515 - </div>
516 - </div>
517 - </div>
558 + if ( ! \mainwp_current_user_can( 'dashboard', 'manage_clients' ) ) {
559 + \mainwp_do_not_have_permissions( esc_html__( 'manage clients', 'mainwp' ) );
560 + return;
561 + }
518 562
519 - <h3><?php esc_html_e( 'Account Management', 'mainwp' ); ?></h3>
563 + static::$itemsTable->prepare_items();
520 564
521 - <div class="ui grid field">
522 - <label class="six wide column middle aligned"><?php esc_html_e( 'Password', 'mainwp' ); ?></label>
523 - <div class="ui six wide column">
524 - <div class="ui left labeled action input">
525 - <input class="hidden" value=" "/>
526 - <input type="text" id="password" name="password" autocomplete="off" value="">
527 - </div>
528 - </div>
529 - </div>
530 - </div>
531 - </div>
532 - </form>
533 - <div class="actions">
534 - <div id="mainwp_update_password_error" style="display: none"></div>
535 - <span id="mainwp_clients_updating"><i class="ui active inline loader tiny"></i></span>
536 - <input type="button" class="ui green button" id="mainwp_btn_update_client" value="<?php esc_attr_e( 'Update', 'mainwp' ); ?>">
537 - </div>
538 - </div>
539 - <?php
540 - }
565 + $has_no_clients = ( 0 === static::$itemsTable->total_items );
541 566
567 + static::render_header( '' );
542 568
543 - /**
544 - * Method render_screen_options()
545 - *
546 - * Render Page Settings Modal.
547 - */
548 - public static function render_screen_options() { // phpcs:ignore -- Current complexity is the only way to achieve desired results, pull request solutions appreciated.
569 + if ( ! $has_no_clients ) {
570 + static::render_second_top_header();
571 + }
549 572
550 - $columns = self::$itemsTable->get_columns();
573 + ?>
574 + <div id="mainwp-manage-clients-content" class="ui padded segment">
575 + <?php if ( $has_no_clients && MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-clients-welcome-message' ) ) : ?>
576 + <div class="ui icon message mainwp-welcome-message">
577 + <em data-emoji=":wave:" class="big"></em>
578 + <div class="content">
579 + <div class="ui massive header"><?php esc_html_e( 'Welcome to MainWP Clients', 'mainwp' ); ?></div>
580 + <p><?php esc_html_e( 'Organize and manage your customers with client profiles, contact information, and site associations.', 'mainwp' ); ?>
581 + </p>
582 + <p>
583 + <?php
584 + // translators: 1: Opening anchor tag for Add Client. 2: Closing anchor tag. 3: Opening anchor tag for Import Clients. 4: Closing anchor tag.
585 + printf( esc_html__( 'Start by %1$sadding your first client%2$s or %3$simporting existing clients%4$s from a CSV file.', 'mainwp' ), '<a href="admin.php?page=ClientAddNew">', '</a>', '<a href="admin.php?page=ClientImport">', '</a>' );
586 + ?>
587 + </p>
588 + </div>
589 + <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-clients-welcome-message"></i>
590 + </div>
591 + <?php else : ?>
592 + <div id="mainwp-message-zone" style="display:none;" class="ui message"></div>
593 + <?php if ( static::$itemsTable->total_items > 0 && static::$itemsTable->total_items <= 5 && MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-clients-add-more-clients-tip' ) ) : ?>
594 + <div class="ui message">
595 + <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-clients-add-more-clients-tip"></i>
596 + <?php
597 + // translators: 1: Bulb emoji element. 2: Opening anchor tag. 3: Closing anchor tag.
598 + printf( esc_html__( '%1$s Tip: Add more Clients. Use %2$sAdd Client%3$s to continue organizing your network.', 'mainwp' ), '<em data-emoji=":bulb:" class="small"></em>', '<a href="admin.php?page=ClientAddNew">', '</a>' );
599 + ?>
600 + </div>
601 + <?php endif; ?>
602 + <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-clients-columns-order-tip' ) ) : ?>
603 + <div class="ui message">
604 + <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-clients-columns-order-tip"></i>
605 + <?php
606 + // translators: 1: Bulb emoji element. 2: Cog icon element.
607 + printf( esc_html__( '%1$s Tip: Drag columns to reorder or use (%2$s) Page Settings to show/hide columns. Your column layout is saved automatically.', 'mainwp' ), '<em data-emoji=":bulb:" class="small"></em>', '<i class="cog fitted icon"></i>' );
608 + ?>
609 + </div>
610 + <?php endif; ?>
611 + <form method="post" class="mainwp-table-container">
612 + <?php
613 + MainWP_UI::generate_wp_nonce( 'mainwp-admin-nonce' );
614 + static::$itemsTable->display();
615 + static::$itemsTable->clear_items();
616 + ?>
617 + </form>
618 + <?php endif; ?>
619 + </div>
620 + <?php
621 + static::render_footer( '' );
551 622
552 - if ( isset( $columns['cb'] ) ) {
553 - unset( $columns['cb'] );
554 - }
623 + if ( ! $has_no_clients ) {
624 + static::render_screen_options();
625 + }
626 + }
555 627
556 - $sites_per_page = get_option( 'mainwp_default_manage_clients_per_page', 25 );
628 + /**
629 + * Method render_second_top_header()
630 + *
631 + * Render second top header.
632 + *
633 + * @return void Render second top header html.
634 + */
635 + public static function render_second_top_header() {
636 + ?>
637 + <div class="mainwp-sub-header ui mini form">
638 + <?php
639 + do_action( 'mainwp_manageclients_tabletop' );
640 + ?>
641 + </div>
642 + <?php
643 + }
557 644
558 - if ( isset( $columns['site_actions'] ) && empty( $columns['site_actions'] ) ) {
559 - $columns['site_actions'] = esc_html__( 'Actions', 'mainwp' );
560 - }
561 645
562 - $show_cols = get_user_option( 'mainwp_settings_show_manage_clients_columns' );
646 + /**
647 + * Renders Edit Clients Modal window.
648 + */
649 + public static function render_update_clients() {
563 650
564 - if ( false === $show_cols ) { // to backwards.
565 - $default_cols = array(
566 - 'name' => 1,
567 - 'email' => 1,
568 - 'phone' => 1,
569 - 'websites' => 1,
570 - );
651 + ?>
652 + <div id="mainwp-edit-clients-modal" class="ui modal">
653 + <i class="close icon"></i>
654 + <div class="header"><?php esc_html_e( 'Edit client', 'mainwp' ); ?></div>
655 + <div class="scrolling content">
656 + <div class="ui info message"><?php esc_html_e( 'Blank fields will not be changed.', 'mainwp' ); ?></div>
657 + <form id="update_client_profile" class="ui form">
658 + <?php MainWP_UI::generate_wp_nonce( 'mainwp-admin-nonce' ); ?>
659 + <h3 class="ui header"><?php esc_html_e( 'Name', 'mainwp' ); ?></h3>
660 + <div class="ui grid field">
661 + <label class="six wide column middle aligned"><?php esc_html_e( 'First Name', 'mainwp' ); ?></label>
662 + <div class="ui six wide column">
663 + <div class="ui input">
664 + <input type="text" name="first_name" id="first_name" value="" class="regular-text" />
665 + </div>
666 + </div>
667 + </div>
571 668
572 - $show_cols = array();
573 - foreach ( $columns as $name => $title ) {
574 - if ( isset( $default_cols[ $name ] ) ) {
575 - $show_cols[ $name ] = 1;
576 - } {
577 - $show_cols[ $name ] = 1; // show other columns.
578 - }
579 - }
580 - $user = wp_get_current_user();
581 - if ( $user ) {
582 - update_user_option( $user->ID, 'mainwp_settings_show_manage_clients_columns', $show_cols, true );
583 - }
584 - }
669 + <div class="ui grid field">
670 + <label class="six wide column middle aligned"><?php esc_html_e( 'Last Name', 'mainwp' ); ?></label>
671 + <div class="ui six wide column">
672 + <div class="ui input">
673 + <input type="text" name="last_name" id="last_name" value="" class="regular-text" />
674 + </div>
675 + </div>
676 + </div>
585 677
586 - if ( ! is_array( $show_cols ) ) {
587 - $show_cols = array();
588 - }
678 + <div class="ui grid field">
679 + <label class="six wide column middle aligned"><?php esc_html_e( 'Nickname', 'mainwp' ); ?></label>
680 + <div class="ui six wide column">
681 + <div class="ui input">
682 + <input type="text" name="nickname" id="nickname" value="" class="regular-text" />
683 + </div>
684 + </div>
685 + </div>
589 686
590 - ?>
591 - <div class="ui modal" id="mainwp-manage-sites-screen-options-modal">
592 - <i class="close icon"></i>
593 - <div class="header"><?php esc_html_e( 'Page Settings', 'mainwp' ); ?></div>
594 - <div class="scrolling content ui form">
595 - <form method="POST" action="" id="manage-sites-screen-options-form" name="manage_sites_screen_options_form">
596 - <?php wp_nonce_field( 'mainwp-admin-nonce' ); ?>
597 - <input type="hidden" name="wp_nonce" value="<?php echo esc_attr( wp_create_nonce( 'ManageClientsScrOptions' ) ); ?>" />
598 - <div class="ui grid field">
599 - <label class="six wide column"><?php esc_html_e( 'Default items per page value', 'mainwp' ); ?></label>
600 - <div class="ten wide column">
601 - <div class="ui info message">
602 - <ul>
603 - <li><?php esc_html_e( 'Based on your Dashboard server default large numbers can severely impact page load times.', 'mainwp' ); ?></li>
604 - <li><?php esc_html_e( 'Do not add commas for thousands (ex 1000).', 'mainwp' ); ?></li>
605 - <li><?php esc_html_e( '-1 to default to All of your Child Sites.', 'mainwp' ); ?></li>
606 - </ul>
607 - </div>
608 - <input type="text" name="mainwp_default_manage_clients_per_page" id="mainwp_default_manage_clients_per_page" saved-value="<?php echo intval( $sites_per_page ); ?>" value="<?php echo intval( $sites_per_page ); ?>"/>
609 - </div>
610 - </div>
611 - <div class="ui grid field">
612 - <label class="six wide column"><?php esc_html_e( 'Show columns', 'mainwp' ); ?></label>
613 - <div class="ten wide column">
614 - <ul class="mainwp_hide_wpmenu_checkboxes">
615 - <?php
616 - foreach ( $columns as $name => $title ) {
617 - if ( empty( $title ) ) {
618 - continue;
619 - }
620 - ?>
621 - <li>
622 - <div class="ui checkbox <?php echo ( 'site_preview' === $name ) ? 'site_preview not-auto-init' : ''; ?>">
623 - <input type="checkbox"
624 - <?php
625 - $show_col = ! isset( $show_cols[ $name ] ) || ( 1 === (int) $show_cols[ $name ] );
626 - if ( $show_col ) {
627 - echo 'checked="checked"';
628 - }
629 - ?>
630 - id="mainwp_show_column_<?php echo esc_attr( $name ); ?>" name="mainwp_show_column_<?php echo esc_attr( $name ); ?>" value="<?php echo esc_attr( $name ); ?>">
631 - <label for="mainwp_show_column_<?php echo esc_attr( $name ); ?>" ><?php echo $title; // phpcs:ignore WordPress.Security.EscapeOutput ?></label>
632 - <input type="hidden" value="<?php echo esc_attr( $name ); ?>" name="show_columns_name[]" />
633 - </div>
634 - </li>
635 - <?php
636 - }
637 - ?>
638 - </ul>
639 - </div>
640 - </div>
641 - </div>
642 - <div class="actions">
643 - <div class="ui two columns grid">
644 - <div class="left aligned column">
645 - <span data-tooltip="<?php esc_attr_e( 'Resets the page to its original layout and reinstates relocated columns.', 'mainwp' ); ?>" data-inverted="" data-position="top center"><input type="button" class="ui button" name="reset" id="reset-manageclients-settings" value="<?php esc_attr_e( 'Reset Page', 'mainwp' ); ?>" /></span>
646 - </div>
647 - <div class="ui right aligned column">
648 - <input type="submit" class="ui green button" name="btnSubmit" id="submit-manageclients-settings" value="<?php esc_attr_e( 'Save Settings', 'mainwp' ); ?>" />
649 - </div>
650 - </div>
651 - </div>
652 - <input type="hidden" name="reset_manageclients_columns_order" value="0">
653 - </form>
654 - </div>
655 - <div class="ui small modal" id="mainwp-monitoring-sites-site-preview-screen-options-modal">
656 - <div class="header"><?php esc_html_e( 'Page Settings', 'mainwp' ); ?></div>
657 - <div class="scrolling content ui form">
658 - <span><?php esc_html_e( 'Would you like to turn on home screen previews? This function queries WordPress.com servers to capture a screenshot of your site the same way comments shows you preview of URLs.', 'mainwp' ); ?>
659 - </div>
660 - <div class="actions">
661 - <div class="ui ok button"><?php esc_html_e( 'Yes', 'mainwp' ); ?></div>
662 - <div class="ui cancel button"><?php esc_html_e( 'No', 'mainwp' ); ?></div>
663 - </div>
664 - </div>
665 - <script type="text/javascript">
666 - jQuery( document ).ready( function () {
667 - jQuery( '.ui.checkbox.not-auto-init.site_preview' ).checkbox( {
668 - onChecked : function() {
669 - var $chk = jQuery( this );
670 - jQuery( '#mainwp-monitoring-sites-site-preview-screen-options-modal' ).modal( {
671 - allowMultiple: true, // multiple modals.
672 - width: 100,
673 - onDeny: function () {
674 - $chk.prop('checked', false);
675 - }
676 - } ).modal( 'show' );
677 - }
678 - } );
679 - jQuery('#reset-manageclients-settings').on( 'click', function () {
680 - mainwp_confirm(__( 'Are you sure.' ), function(){
681 - jQuery('input[name=mainwp_default_manage_clients_per_page]').val(25);
682 - jQuery('.mainwp_hide_wpmenu_checkboxes input[id^="mainwp_show_column_"]').prop( 'checked', false );
683 - //default columns.
684 - var cols = ['name','email','phone','websites'];
685 - jQuery.each( cols, function ( index, value ) {
686 - jQuery('.mainwp_hide_wpmenu_checkboxes input[id="mainwp_show_column_' + value + '"]').prop( 'checked', true );
687 - } );
688 - jQuery('input[name=reset_manageclients_columns_order]').attr('value',1);
689 - jQuery('#submit-manageclients-settings').click();
690 - }, false, false, true );
691 - return false;
692 - });
693 - } );
694 - </script>
695 - <?php
696 - }
687 + <div class="ui grid field">
688 + <label class="six wide column middle aligned"><?php esc_html_e( 'Display name publicly as', 'mainwp' ); ?></label>
689 + <div class="ui six wide column">
690 + <div class="ui input">
691 + <select name="display_name" id="display_name" class="ui selection dropdown"></select>
692 + </div>
693 + </div>
694 + </div>
697 695
698 - /**
699 - * Renders Clients Table.
700 - *
701 - * @param string $role Current client role.
702 - * @param string $groups Current client groups.
703 - * @param string $sites Current Child Sites the client is on.
704 - * @param null $search Search field.
705 - */
706 - public static function render_table( $role = '', $groups = '', $sites = '', $search = null ) {
696 + <h3 class="ui header"><?php esc_html_e( 'Contact Info', 'mainwp' ); ?></h3>
707 697
708 - /**
709 - * Action: mainwp_before_clients_table
710 - *
711 - * Fires before the client table.
712 - *
713 - * @since 4.1
714 - */
715 - do_action( 'mainwp_before_clients_table' );
716 - ?>
717 - <table id="mainwp-clients-table" class="ui unstackable single line table" style="width:100%">
718 - <thead>
719 - <tr>
720 - <th class="no-sort collapsing check-column"><span class="ui checkbox"><input id="cb-select-all-top" type="checkbox" /></span></th>
721 - <?php do_action( 'mainwp_clients_table_header' ); ?>
722 - <th><?php esc_html_e( 'Client name', 'mainwp' ); ?></th>
723 - <th><?php esc_html_e( 'Company', 'mainwp' ); ?></th>
724 - <th><?php esc_html_e( 'Email', 'mainwp' ); ?></th>
725 - <th><?php esc_html_e( 'Phone', 'mainwp' ); ?></th>
726 - <th><?php esc_html_e( 'Websites', 'mainwp' ); ?></th>
727 - <th id="mainwp-clients-actions" class="no-sort collapsing"></th>
728 - </tr>
729 - </thead>
730 - <tbody id="mainwp-clients-list">
731 - <?php
732 - self::render_table_body( $role, $groups, $sites, $search );
733 - ?>
734 - </tbody>
735 - <tfoot>
736 - <tr>
737 - <th class="no-sort collapsing check-column"><span class="ui checkbox"><input id="cb-select-all-top" type="checkbox" /></span></th>
738 - <?php do_action( 'mainwp_clients_table_header' ); ?>
739 - <th><?php esc_html_e( 'Client name', 'mainwp' ); ?></th>
740 - <th><?php esc_html_e( 'Company', 'mainwp' ); ?></th>
741 - <th><?php esc_html_e( 'Email', 'mainwp' ); ?></th>
742 - <th><?php esc_html_e( 'Phone', 'mainwp' ); ?></th>
743 - <th><?php esc_html_e( 'Websites', 'mainwp' ); ?></th>
744 - <th id="mainwp-clients-actions" class="no-sort collapsing"></th>
745 - </tr>
746 - </tfoot>
747 - </table>
748 - <?php
749 - /**
750 - * Action: mainwp_after_clients_table
751 - *
752 - * Fires after the client table.
753 - *
754 - * @since 4.1
755 - */
756 - do_action( 'mainwp_after_clients_table' );
698 + <div class="ui grid field">
699 + <label class="six wide column middle aligned"><?php esc_html_e( 'Email', 'mainwp' ); ?></label>
700 + <div class="ui six wide column">
701 + <div class="ui input">
702 + <input type="email" name="email" id="email" value="" class="regular-text ltr" />
703 + </div>
704 + </div>
705 + </div>
757 706
758 - /**
759 - * Filter: mainwp_clients_table_fatures
760 - *
761 - * Filters the Manage Clients table features.
762 - *
763 - * @since 4.1
764 - */
765 - $table_features = array(
766 - 'searching' => 'true',
767 - 'paging' => 'true',
768 - 'info' => 'true',
769 - 'stateSave' => 'true',
770 - 'scrollX' => 'true',
771 - 'responsive' => 'true',
772 - 'colReorder' => '{ fixedColumnsLeft: 1, fixedColumnsRight: 1 }',
773 - 'order' => '[]',
774 - );
775 - $table_features = apply_filters( 'mainwp_clients_table_fatures', $table_features );
776 - ?>
777 - <script type="text/javascript">
778 - var responsive = <?php echo esc_html( $table_features['responsive'] ); ?>;
779 - if( jQuery( window ).width() > 1140 ) {
780 - responsive = false;
781 - }
782 - jQuery( document ).ready( function () {
783 - try {
784 - jQuery( "#mainwp-clients-table" ).DataTable().destroy(); // to fix re-init database issue.
785 - jQuery( "#mainwp-clients-table" ).DataTable( {
786 - "responsive" : responsive,
787 - "searching" : <?php echo esc_html( $table_features['searching'] ); ?>,
788 - "colReorder" : <?php echo esc_html( $table_features['colReorder'] ); ?>,
789 - "stateSave": <?php echo esc_html( $table_features['stateSave'] ); ?>,
790 - "paging": <?php echo esc_html( $table_features['paging'] ); ?>,
791 - "info": <?php echo esc_html( $table_features['info'] ); ?>,
792 - "order": <?php echo esc_html( $table_features['order'] ); ?>,
793 - "scrollX" : <?php echo esc_html( $table_features['scrollX'] ); ?>,
794 - "lengthMenu": [ [10, 25, 50, 100, -1], [10, 25, 50, 100, "All"] ],
795 - "columnDefs": [ {
796 - "targets": 'no-sort',
797 - "orderable": false
798 - } ],
799 - "preDrawCallback": function() {
800 - jQuery('#mainwp-clients-table .ui.dropdown').dropdown();
801 - jQuery('#mainwp-clients-table .ui.checkbox').checkbox();
802 - mainwp_datatable_fix_menu_overflow();
803 - mainwp_table_check_columns_init(); // ajax: to fix checkbox all.
804 - }
805 - } );
806 - } catch ( err ) {
807 - // to fix js error.
808 - }
809 - } );
810 - </script>
811 - <?php
812 - }
707 + <div class="ui grid field">
708 + <label class="six wide column middle aligned"><?php esc_html_e( 'Website', 'mainwp' ); ?></label>
709 + <div class="ui six wide column">
710 + <div class="ui input">
711 + <input type="url" name="url" id="url" value="" class="regular-text code" />
712 + </div>
713 + </div>
714 + </div>
813 715
814 - /**
815 - * Renders the table body.
816 - *
817 - * @param string $role client Role.
818 - * @param string $groups Usr Group.
819 - * @param string $sites Clients Sites.
820 - * @param string $search Search field.
821 - */
822 - public static function render_table_body( $role = '', $groups = '', $sites = '', $search = '' ) { // phpcs:ignore -- current complexity required to achieve desired results. Pull request solutions appreciated.
716 + <h3 class="ui header"><?php esc_html_e( 'About the user', 'mainwp' ); ?></h3>
823 717
824 - if ( empty( $output->clients ) ) {
825 - self::render_not_found();
826 - return;
827 - } else {
828 - self::clients_search_handler_renderer( $clients, $website );
829 - }
830 - }
718 + <div class="ui grid field">
719 + <label class="six wide column middle aligned"><?php esc_html_e( 'Biographical Info', 'mainwp' ); ?></label>
720 + <div class="ui six wide column">
721 + <div class="ui input">
722 + <textarea name="description" id="description" rows="5" cols="30" style="width:100%"></textarea>
723 + <br/><span class="ui small text"><?php esc_html_e( 'Share a little biographical information to fill out your profile. This may be shown publicly.', 'mainwp' ); ?></span>
724 + </div>
725 + </div>
726 + </div>
831 727
832 - /**
833 - * Renders when cache is not found.
834 - */
835 - public static function render_not_found() {
836 - ob_start();
837 - ?>
838 - <tr><td colspan="999"><?php esc_html_e( 'Please use the search options to find wanted clients.', 'mainwp' ); ?></td></tr>
839 - <?php
840 - $newOutput = ob_get_clean();
841 - echo $newOutput; // phpcs:ignore WordPress.Security.EscapeOutput
842 - }
728 + <h3 class="ui header"><?php esc_html_e( 'Account Management', 'mainwp' ); ?></h3>
843 729
844 - /**
845 - * Renders Search results.
846 - *
847 - * @param array $clients Clients array.
848 - * @param object $website Object containing the child site info.
849 - *
850 - * @return mixed Search results table.
851 - */
852 - protected static function clients_search_handler_renderer( $clients, $website ) {
853 - $return = 0;
730 + <div class="ui grid field">
731 + <label class="six wide column middle aligned"><?php esc_html_e( 'Password', 'mainwp' ); ?></label>
732 + <div class="ui six wide column">
733 + <div class="ui action input">
734 + <input class="hidden" value=" "/>
735 + <input type="text" id="password" name="password" autocomplete="off" value="">
736 + </div>
737 + </div>
738 + </div>
854 739
855 - foreach ( $clients as $client ) {
856 - if ( ! is_array( $client ) ) {
857 - continue;
858 - }
859 - ob_start();
860 - ?>
861 - <tr>
862 - <td class="check-column"><span class="ui checkbox"><input type="checkbox" name="client[]" value="1"></span></td>
863 - <?php do_action( 'mainwp_clients_table_column', $client, $website ); ?>
864 - <td class="name column-name">
865 - <?php echo ! empty( $client['display_name'] ) ? esc_html( $client['display_name'] ) : '&nbsp;'; ?>
866 - <div class="row-actions-working">
867 - <i class="ui active inline loader tiny"></i> <?php esc_html_e( 'Please wait', 'mainwp' ); ?>
868 - </div>
869 - </td>
870 - <td class="clientname column-clientname"><strong><abbr title="<?php echo esc_attr( $client['login'] ); ?>"><?php echo esc_html( $client['login'] ); ?></abbr></strong></td>
871 - <td class="email column-email"><a href="mailto:<?php echo esc_attr( $client['email'] ); ?>"><?php echo esc_html( $client['email'] ); ?></a></td>
872 - <td class="posts column-posts"><a href="<?php echo esc_url( admin_url( 'admin.php?page=PostBulkManage&siteid=' . intval( $website->id ) ) . '&clientid=' . $client['id'] ); ?>"><?php echo esc_html( $client['post_count'] ); ?></a></td>
873 - <td class="website column-website"><a href="<?php echo esc_url( $website->url ); ?>" target="_blank"><?php echo esc_html( $website->url ); ?></a></td>
874 - <td class="right aligned">
875 - <input class="clientId" type="hidden" name="id" value="<?php echo esc_attr( $client['id'] ); ?>" />
876 - <input class="clientName" type="hidden" name="name" value="<?php echo esc_attr( $client['login'] ); ?>" />
877 - <input class="websiteId" type="hidden" name="id" value="<?php echo intval( $website->id ); ?>" />
878 - <div class="ui left pointing dropdown icon mini basic green button" style="z-index: 999">
879 - <a href="javascript:void(0)"><i class="ellipsis horizontal icon"></i></a>
880 - <div class="menu">
881 - <a class="item client_getedit" href="#"><?php esc_html_e( 'Edit', 'mainwp' ); ?></a>
882 - <?php if ( ( 1 !== (int) $client['id'] ) && ( $client['login'] !== $website->adminname ) ) { ?>
883 - <a class="item client_submitdelete" href="#"><?php esc_html_e( 'Delete', 'mainwp' ); ?></a>
884 - <?php } elseif ( ( 1 === (int) $client['id'] ) || ( $client['login'] === $website->adminname ) ) { ?>
885 - <a href="javascript:void(0)" class="item" data-tooltip="This client is used for our secure link, it can not be deleted." data-inverted="" data-position="left center"><?php esc_html_e( 'Delete', 'mainwp' ); ?></a>
886 - <?php } ?>
887 - <a class="item" href="<?php echo 'admin.php?page=SiteOpen&newWindow=yes&websiteid=' . intval( $website->id ); ?>&_opennonce=<?php echo esc_html( wp_create_nonce( 'mainwp-admin-nonce' ) ); ?>" data-tooltip="<?php esc_attr_e( 'Jump to the site WP Admin', 'mainwp' ); ?>" data-position="bottom right" data-inverted="" class="open_newwindow_wpadmin ui green basic icon button" target="_blank"><?php esc_html_e( 'Go to WP Admin', 'mainwp' ); ?></a>
888 - <?php
889 - /**
890 - * Action: mainwp_clients_table_action
891 - *
892 - * Adds a new item in the Actions menu in Manage Clients table.
893 - *
894 - * Suggested HTML markup:
895 - * <a class="item" href="Your custom URL">Your custom label</a>
896 - *
897 - * @param array $client Array containing the client data.
898 - * @param array $website Object containing the website data.
899 - *
900 - * @since 4.1
901 - */
902 - do_action( 'mainwp_clients_table_action', $client, $website );
903 - ?>
904 - </div>
905 - </div>
906 - </td>
907 - </tr>
908 - <?php
909 - $newOutput = ob_get_clean();
910 - echo $newOutput; // phpcs:ignore WordPress.Security.EscapeOutput
911 - ++$return;
912 - }
740 + </form>
741 + </div>
742 + <div class="actions">
743 + <div id="mainwp_update_password_error" style="display: none"></div>
744 + <span id="mainwp_clients_updating"><i class="ui active inline loader tiny"></i></span>
745 + <input type="button" class="ui green button" id="mainwp_btn_update_client" value="<?php esc_attr_e( 'Update', 'mainwp' ); ?>">
746 + </div>
747 + </div>
748 + <?php
749 + }
913 750
914 - return $return;
915 - }
916 751
917 - /**
918 - * Renders the Add New Client form.
919 - */
920 - public static function render_add_client() {
921 - $show = 'Add';
922 - $client_id = 0;
923 - $selected_sites = array();
924 - $edit_client = false;
752 + /**
753 + * Method render_screen_options()
754 + *
755 + * Render Page Settings Modal.
756 + */
757 + public static function render_screen_options() { // phpcs:ignore -- NOSONAR -Current complexity is the only way to achieve desired results, pull request solutions appreciated.
925 758
926 - if ( isset( $_GET['client_id'] ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Recommended
927 - $show = 'Edit';
928 - $client_id = intval( $_GET['client_id'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Recommended
929 - $edit_client = $client_id ? MainWP_DB_Client::instance()->get_wp_client_by( 'client_id', $client_id ) : false;
930 - $client_sites = MainWP_DB_Client::instance()->get_websites_by_client_ids( $client_id );
759 + $columns = static::$itemsTable->get_columns();
931 760
932 - if ( $client_sites ) {
933 - foreach ( $client_sites as $site ) {
934 - $selected_sites[] = $site->id;
935 - }
936 - }
937 - }
761 + if ( isset( $columns['cb'] ) ) {
762 + unset( $columns['cb'] );
763 + }
938 764
939 - self::render_header( $show );
940 - ?>
941 - <div class="ui alt segment" id="mainwp-add-clients">
942 - <form action="" method="post" enctype="multipart/form-data" name="createclient_form" id="createclient_form" class="add:clients: validate">
943 - <?php wp_nonce_field( 'mainwp-admin-nonce' ); ?>
944 - <div class="mainwp-main-content">
945 - <div class="ui segment">
946 - <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-add-client-info-message' ) ) : ?>
947 - <div class="ui info message">
948 - <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-add-client-info-message"></i>
949 - <?php printf( esc_html__( 'use the provided form to create a new client on your child site(). for additional help, please check this %1$shelp documentation %2$s.', 'mainwp' ), '<a href="https://kb.mainwp.com/docs/create-a-new-client/" target="_blank">', '</a> <i class="external alternate icon"></i>' ); ?>
950 - </div>
951 - <?php endif; ?>
952 - <div class="ui message" id="mainwp-message-zone-client" style="display:none;"></div>
953 - <div id="mainwp-add-new-client-form" >
954 - <?php
955 - self::render_add_client_content( $edit_client );
956 - ?>
957 - </div>
958 - </div>
959 - </div>
960 - <div class="mainwp-side-content mainwp-no-padding">
765 + $sites_per_page = get_option( 'mainwp_default_manage_clients_per_page', 25 );
961 766
962 - <?php if ( $client_id ) : ?>
963 - <div class="mainwp-select-sites ui accordion mainwp-sidebar-accordion">
964 - <div class="title active"><i class="dropdown icon"></i> <?php esc_html_e( 'Tokens Info', 'mainwp' ); ?></div>
965 - <div class="content active">
966 - <div class="ui info message">
967 - <?php esc_html_e( 'Client info is available as tokens for reports and boilerplate content. Toggle the switch to see available tokens.', 'mainwp' ); ?>
968 - </div>
969 - <div class="ui toggle checkbox">
970 - <input type="checkbox" name="mainwp_toggle_tokens_info" id="mainwp_toggle_tokens_info">
971 - <label><?php esc_html_e( 'Toggle available tokens', 'mainwp' ); ?></label>
972 - </div>
973 - </div>
974 - </div>
975 - <script type="text/javascript">
976 - jQuery( document ).ready( function() {
977 - jQuery( '#mainwp_toggle_tokens_info' ).on( 'change', function() {
978 - jQuery( '.hidden.token.column' ).toggle();
979 - } );
980 - } );
981 - </script>
982 - <div class="ui fitted divider"></div>
983 - <?php endif; ?>
767 + if ( isset( $columns['site_actions'] ) && empty( $columns['site_actions'] ) ) {
768 + $columns['site_actions'] = esc_html__( 'Actions', 'mainwp' );
769 + }
984 770
985 - <div class="mainwp-select-sites ui accordion mainwp-sidebar-accordion">
986 - <div class="title active"><i class="dropdown icon"></i> <?php esc_html_e( 'Select Sites', 'mainwp' ); ?></div>
987 - <div class="content active">
988 - <?php
989 - $sel_params = array(
990 - 'selected_sites' => $selected_sites,
991 - 'show_group' => false,
992 - 'add_edit_client_id' => $client_id,
993 - 'enable_offline_sites' => $client_id ? true : false,
994 - );
771 + $show_cols = get_user_option( 'mainwp_settings_show_manage_clients_columns' );
995 772
996 - MainWP_UI_Select_Sites::select_sites_box( $sel_params );
997 - ?>
998 - </div>
999 - </div>
1000 - <div class="ui fitted divider"></div>
1001 - <div class="mainwp-search-submit">
1002 - <input type="button" name="createclient" current-page="add-new" id="bulk_add_createclient" class="ui big green fluid button" value="<?php echo $client_id ? esc_attr__( 'Update Client', 'mainwp' ) : esc_attr__( 'Add Client', 'mainwp' ); ?> "/>
1003 - </div>
1004 - </div>
1005 - <div style="clear:both"></div>
1006 - </form>
773 + if ( false === $show_cols ) { // to backwards.
774 + $show_cols = array();
775 + foreach ( $columns as $name => $title ) {
776 + if ( in_array( $name, array( 'image', 'client', 'suspended', 'contact_name', 'websites', 'created' ) ) ) {
777 + $show_cols[ $name ] = 1;
778 + } else {
779 + $show_cols[ $name ] = 0;
780 + }
781 + }
782 + $user = wp_get_current_user();
783 + if ( $user ) {
784 + update_user_option( $user->ID, 'mainwp_settings_show_manage_clients_columns', $show_cols, true );
785 + }
786 + }
1007 787
788 + if ( ! is_array( $show_cols ) ) {
789 + $show_cols = array();
790 + }
1008 791
1009 - </div>
1010 - <?php
1011 - self::render_footer( $show );
1012 - self::render_add_field_modal( $client_id );
1013 - }
792 + ?>
793 + <div class="ui modal" id="mainwp-manage-sites-screen-options-modal">
794 + <i class="close icon"></i>
795 + <div class="header"><?php esc_html_e( 'Page Settings', 'mainwp' ); ?></div>
796 + <div class="scrolling content ui form">
797 + <form method="POST" action="" id="manage-sites-screen-options-form" name="manage_sites_screen_options_form">
798 + <?php MainWP_UI::generate_wp_nonce( 'mainwp-admin-nonce' ); ?>
799 + <input type="hidden" name="wp_nonce" value="<?php echo esc_attr( wp_create_nonce( 'ManageClientsScrOptions' ) ); ?>" />
800 + <div class="ui grid field">
801 + <label class="six wide column"><?php esc_html_e( 'Default items per page value', 'mainwp' ); ?></label>
802 + <div class="ten wide column">
803 + <div class="ui info message">
804 + <ul>
805 + <li><?php esc_html_e( 'Based on your Dashboard server default large numbers can severely impact page load times.', 'mainwp' ); ?></li>
806 + <li><?php esc_html_e( 'Do not add commas for thousands (ex 1000).', 'mainwp' ); ?></li>
807 + <li><?php esc_html_e( '-1 to default to All of your Child Sites.', 'mainwp' ); ?></li>
808 + </ul>
809 + </div>
810 + <input type="text" name="mainwp_default_manage_clients_per_page" id="mainwp_default_manage_clients_per_page" saved-value="<?php echo intval( $sites_per_page ); ?>" value="<?php echo intval( $sites_per_page ); ?>"/>
811 + </div>
812 + </div>
813 + <div class="ui grid field">
814 + <label class="six wide column"><?php esc_html_e( 'Show columns', 'mainwp' ); ?></label>
815 + <div class="ten wide column">
816 + <ul class="mainwp_hide_wpmenu_checkboxes">
817 + <?php
818 + foreach ( $columns as $name => $title ) {
819 + if ( empty( $title ) ) {
820 + continue;
821 + }
822 + ?>
823 + <li>
824 + <div class="ui checkbox <?php echo ( 'site_preview' === $name ) ? 'site_preview not-auto-init' : ''; ?>">
825 + <input type="checkbox"
826 + <?php
827 + $show_col = ! isset( $show_cols[ $name ] ) || ( 1 === (int) $show_cols[ $name ] );
828 + if ( $show_col ) {
829 + echo 'checked="checked"';
830 + }
831 + ?>
832 + id="mainwp_show_column_<?php echo esc_attr( $name ); ?>" name="mainwp_show_column_<?php echo esc_attr( $name ); ?>" value="<?php echo esc_attr( $name ); ?>">
833 + <label for="mainwp_show_column_<?php echo esc_attr( $name ); ?>" ><?php echo $title; // phpcs:ignore WordPress.Security.EscapeOutput ?></label>
834 + <input type="hidden" value="<?php echo esc_attr( $name ); ?>" name="show_columns_name[]" />
835 + </div>
836 + </li>
837 + <?php
838 + }
839 + ?>
840 + </ul>
841 + </div>
842 + </div>
843 + </div>
844 + <div class="actions">
845 + <div class="ui two columns grid">
846 + <div class="left aligned column">
847 + <span data-tooltip="<?php esc_attr_e( 'Resets the page to its original layout and reinstates relocated columns.', 'mainwp' ); ?>" data-inverted="" data-position="top center"><input type="button" class="ui button" name="reset" id="reset-manageclients-settings" value="<?php esc_attr_e( 'Reset Page', 'mainwp' ); ?>" /></span>
848 + </div>
849 + <div class="ui right aligned column">
850 + <input type="submit" class="ui green button" name="btnSubmit" id="submit-manageclients-settings" value="<?php esc_attr_e( 'Save Settings', 'mainwp' ); ?>" />
851 + </div>
852 + </div>
853 + </div>
854 + <input type="hidden" name="reset_manageclients_columns_order" value="0">
855 + </form>
856 + </div>
857 + <div class="ui small modal" id="mainwp-monitoring-sites-site-preview-screen-options-modal">
858 + <div class="header"><?php esc_html_e( 'Page Settings', 'mainwp' ); ?></div>
859 + <div class="scrolling content ui form">
860 + <span><?php esc_html_e( 'Would you like to turn on home screen previews? This function queries WordPress.com servers to capture a screenshot of your site the same way comments shows you preview of URLs.', 'mainwp' ); ?>
861 + </div>
862 + <div class="actions">
863 + <div class="ui ok button"><?php esc_html_e( 'Yes', 'mainwp' ); ?></div>
864 + <div class="ui cancel button"><?php esc_html_e( 'No', 'mainwp' ); ?></div>
865 + </div>
866 + </div>
867 + <script type="text/javascript">
868 + jQuery( document ).ready( function () {
869 + jQuery( '.ui.checkbox.not-auto-init.site_preview' ).checkbox( {
870 + onChecked : function() {
871 + let $chk = jQuery( this );
872 + jQuery( '#mainwp-monitoring-sites-site-preview-screen-options-modal' ).modal( {
873 + allowMultiple: true, // multiple modals.
874 + width: 100,
875 + onDeny: function () {
876 + $chk.prop('checked', false);
877 + }
878 + } ).modal( 'show' );
879 + }
880 + } );
881 + jQuery('#reset-manageclients-settings').on( 'click', function () {
882 + mainwp_confirm(__( 'Are you sure?' ), function(){
883 + jQuery('input[name=mainwp_default_manage_clients_per_page]').val(25);
884 + jQuery('.mainwp_hide_wpmenu_checkboxes input[id^="mainwp_show_column_"]').prop( 'checked', false );
885 + //default columns.
886 + let cols = [ 'suspended','image','client','websites','contact_name','created'];
887 + jQuery.each( cols, function ( index, value ) {
888 + jQuery('.mainwp_hide_wpmenu_checkboxes input[id="mainwp_show_column_' + value + '"]').prop( 'checked', true );
889 + } );
890 + jQuery('input[name=reset_manageclients_columns_order]').attr('value',1);
891 + jQuery('#submit-manageclients-settings').click();
892 + }, false, false, true );
893 + return false;
894 + });
895 + } );
896 + </script>
897 + <?php
898 + }
1014 899
900 + /**
901 + * Renders the Add New Client form.
902 + */
903 + public static function render_add_client() {
904 + $show = 'Add';
905 + $client_id = 0;
906 + $selected_sites = array();
907 + $edit_client = false;
1015 908
1016 - /**
1017 - * Renders the Add New Client Fields form.
1018 - */
1019 - public static function render_client_fields() {
909 + if ( isset( $_GET['client_id'] ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Recommended
910 + $show = 'Edit';
911 + $client_id = intval( $_GET['client_id'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Recommended
912 + $edit_client = $client_id ? MainWP_DB_Client::instance()->get_wp_client_by( 'client_id', $client_id ) : false;
913 + $client_sites = MainWP_DB_Client::instance()->get_websites_by_client_ids( $client_id );
1020 914
1021 - self::render_header( 'AddField' );
1022 - ?>
1023 - <div class="ui segment" id="mainwp-add-client-fields">
1024 - <?php
1025 - $fields = MainWP_DB_Client::instance()->get_client_fields();
1026 - ?>
1027 - <div class="ui info message" <?php echo ! MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-clients-manage-fields' ) ? 'style="display: none"' : ''; ?>>
1028 - <?php esc_html_e( 'Create and manage custom Client fields.', 'mainwp' ); ?>
1029 - <i class="ui close icon mainwp-notice-dismiss" notice-id="mainwp-clients-manage-fields"></i>
1030 - </div>
1031 - <div class="ui message" id="mainwp-message-zone-client" style="display:none;"></div>
1032 - <table id="mainwp-clients-custom-fields-table" class="ui selectable compact table" style="width:100%">
1033 - <thead>
1034 - <tr>
1035 - <th><?php esc_html_e( 'Field Name', 'mainwp' ); ?></th>
1036 - <th><?php esc_html_e( 'Field Description', 'mainwp' ); ?></th>
1037 - <th class="no-sort collapsing"><?php esc_html_e( '', 'mainwp' ); ?></th>
1038 - </tr>
1039 - </thead>
1040 - <tbody>
1041 - <?php if ( is_array( $fields ) && count( $fields ) > 0 ) : ?>
1042 - <?php foreach ( $fields as $field ) : ?>
1043 - <?php
1044 - if ( ! $field ) {
1045 - continue;}
1046 - ?>
1047 - <tr class="mainwp-field" field-id="<?php echo intval( $field->field_id ); ?>">
1048 - <td class="field-name">[<?php echo esc_html( stripslashes( $field->field_name ) ); ?>]</td>
1049 - <td class="field-description"><?php echo esc_html( stripslashes( $field->field_desc ) ); ?></td>
1050 - <td>
1051 - <div class="ui left pointing dropdown icon mini basic green button">
1052 - <i class="ellipsis horizontal icon"></i>
1053 - <div class="menu">
1054 - <a class="item" id="mainwp-clients-edit-custom-field" href="#"><?php esc_html_e( 'Edit', 'mainwp' ); ?></a>
1055 - <a class="item" id="mainwp-clients-delete-general-field" href="#"><?php esc_html_e( 'Delete', 'mainwp' ); ?></a>
1056 - </div>
1057 - </div>
1058 - </td>
1059 - </tr>
1060 - <?php endforeach; ?>
1061 - <?php endif; ?>
1062 - </tbody>
1063 - <tfoot>
1064 - <tr>
1065 - <th><a class="ui mini green button" href="javascript:void(0);" id="mainwp-clients-new-custom-field-button"><?php esc_html_e( 'New Field', 'mainwp' ); ?></a></th>
1066 - <th><?php esc_html_e( '', 'mainwp' ); ?></th>
1067 - <th><?php esc_html_e( '', 'mainwp' ); ?></th>
1068 - </tr>
1069 - </tfoot>
1070 - </table>
915 + if ( $client_sites ) {
916 + foreach ( $client_sites as $site ) {
917 + $selected_sites[] = $site->id;
918 + }
919 + }
920 + }
1071 921
1072 - <script type="text/javascript">
1073 - // Init datatables
1074 - jQuery( '#mainwp-clients-custom-fields-table' ).DataTable( {
1075 - "stateSave": true,
1076 - "stateDuration": 0,
1077 - "lengthMenu": [ [10, 25, 50, 100, -1], [10, 25, 50, 100, "All"] ],
1078 - "columnDefs": [ { "orderable": false, "targets": "no-sort" } ],
1079 - "order": [ [ 0, "asc" ] ],
1080 - "language": { "emptyTable": "No fields found." },
1081 - "drawCallback" : function( settings ) {
1082 - jQuery( '#mainwp-clients-custom-fields-table .ui.dropdown').dropdown();
1083 - },
1084 - } );
1085 - </script>
1086 - </div>
922 + static::render_header( $show );
923 + ?>
924 + <div class="ui alt segment" id="mainwp-add-clients">
925 + <form action="" method="post" enctype="multipart/form-data" name="createclient_form" id="createclient_form" class="add:clients: validate">
926 + <?php MainWP_UI::generate_wp_nonce( 'mainwp-admin-nonce' ); ?>
927 + <div class="mainwp-main-content">
928 + <div class="ui padded segment">
929 + <div class="ui message" id="mainwp-message-zone-client" style="display:none;"></div>
930 + <div id="mainwp-add-new-client-form" >
931 + <?php static::render_add_client_content( $edit_client ); ?>
932 + </div>
933 + </div>
934 + </div>
935 + <div class="mainwp-side-content mainwp-no-padding">
936 + <?php if ( $client_id ) : ?>
937 + <div class="mainwp-select-sites ui accordion mainwp-sidebar-accordion">
938 + <div class="title active"><i class="dropdown icon"></i> <?php esc_html_e( 'Tokens Info', 'mainwp' ); ?></div>
939 + <div class="content active">
940 + <div class="ui info message">
941 + <?php esc_html_e( 'Client info is available as tokens for reports and boilerplate content. Toggle the switch to see available tokens.', 'mainwp' ); ?>
942 + </div>
943 + <div class="ui toggle checkbox">
944 + <input type="checkbox" name="mainwp_toggle_tokens_info" id="mainwp_toggle_tokens_info">
945 + <label><?php esc_html_e( 'Toggle available tokens', 'mainwp' ); ?></label>
946 + </div>
947 + </div>
948 + </div>
949 + <script type="text/javascript">
950 + jQuery( document ).ready( function() {
951 + jQuery( '#mainwp_toggle_tokens_info' ).on( 'change', function() {
952 + jQuery( '.hidden.token.column' ).toggle();
953 + } );
954 + } );
955 + </script>
956 + <div class="ui fitted divider"></div>
957 + <?php endif; ?>
1087 958
1088 - <?php
1089 - self::render_add_field_modal();
1090 - self::render_footer( 'AddField' );
1091 - }
959 + <div class="mainwp-select-sites ui accordion mainwp-sidebar-accordion">
960 + <div class="title active"><i class="dropdown icon"></i>
961 + <?php esc_html_e( 'Select Sites', 'mainwp' ); ?></div>
962 + <div class="content active">
963 + <?php
964 + $sel_params = array(
965 + 'selected_sites' => $selected_sites,
966 + 'show_group' => false,
967 + 'add_edit_client_id' => $client_id,
968 + 'enable_offline_sites' => $client_id ? true : false,
969 + );
1092 970
1093 - /**
1094 - * Method render_add_field_modal()
1095 - *
1096 - * Render add custom field modal.
1097 - *
1098 - * @param int $client_id The client id.
1099 - */
1100 - public static function render_add_field_modal( $client_id = 0 ) {
1101 - ?>
1102 - <div class="ui modal" id="mainwp-clients-custom-field-modal">
1103 - <i class="close icon"></i>
1104 - <div class="header"><?php esc_html_e( 'Custom Field', 'mainwp' ); ?></div>
1105 - <div class="content ui mini form">
1106 - <div class="ui yellow message" style="display:none"></div>
1107 - <div class="field">
1108 - <label><?php esc_html_e( 'Field Name', 'mainwp' ); ?></label>
1109 - <input type="text" value="" class="field-name" name="field-name" placeholder="<?php esc_attr_e( 'Enter field name (without of square brackets)', 'mainwp' ); ?>">
1110 - </div>
1111 - <div class="field">
1112 - <label><?php esc_html_e( 'Field Description', 'mainwp' ); ?></label>
1113 - <input type="text" value="" class="field-description" name="field-description" placeholder="<?php esc_attr_e( 'Enter field description', 'mainwp' ); ?>">
1114 - </div>
1115 - </div>
1116 - <div class="actions">
1117 - <input type="button" class="ui green button" client-id="<?php echo intval( $client_id ); ?>" id="mainwp-clients-save-new-custom-field" value="<?php esc_attr_e( 'Save Field', 'mainwp' ); ?>">
1118 - </div>
1119 - <input type="hidden" value="0" name="field-id">
1120 - </div>
1121 - <?php
1122 - }
971 + MainWP_UI_Select_Sites::select_sites_box( $sel_params );
972 + ?>
973 + </div>
974 + </div>
975 + <div class="ui fitted divider"></div>
976 + <div class="mainwp-search-submit">
977 + <input type="button" name="createclient" current-page="add-new" id="bulk_add_createclient" class="ui big green fluid button" value="<?php echo $client_id ? esc_attr__( 'Update Client', 'mainwp' ) : esc_attr__( 'Add Client', 'mainwp' ); ?> "/>
978 + </div>
979 + </div>
980 + <div style="clear:both"></div>
981 + </form>
982 + </div>
983 + <?php
984 + static::render_footer( $show );
985 + static::render_add_field_modal( $client_id );
986 + MainWP_UI::render_modal_upload_icon();
987 + }
1123 988
1124 - /**
1125 - * Method add_client()
1126 - *
1127 - * Bulk client addition $_POST Handler.
1128 - */
1129 - public static function add_client() { // phpcs:ignore -- Current complexity is required to achieve desired results. Pull request solutions appreciated.
989 + /**
990 + * Renders the Import Client form.
991 + */
992 + public static function render_import_clients() { // phpcs:ignore -- NOSONAR - Current complexity is the only way to achieve desired results, pull request solutions appreciated.
993 + static::render_header( 'ImportClients' );
994 + $title_page = esc_html__( 'Import Clients', 'mainwp' );
995 + // phpcs:disable WordPress.Security.NonceVerification.Missing
1130 996
1131 - $selected_sites = ( isset( $_POST['selected_sites'] ) && is_array( $_POST['selected_sites'] ) ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['selected_sites'] ) ) : array(); //phpcs:ignore WordPress.Security.NonceVerification.Missing
1132 - $client_fields = isset( $_POST['client_fields'] ) ? wp_unslash( $_POST['client_fields'] ) : array(); //phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
997 + $has_import_data = ! empty( $_POST['mainwp_client_import_add'] );
998 + // phpcs:enable WordPress.Security.NonceVerification.Missing
999 + if ( $has_import_data && check_admin_referer( 'mainwp-admin-nonce' ) ) {
1000 + $result = static::render_import_client_modal();
1001 + }
1002 + ?>
1003 + <div class="ui padded segment" id="mainwp-import-clients">
1004 + <form method="POST" action="" enctype="multipart/form-data" id="mainwp_client_import_form" class="ui form">
1005 + <div>
1006 + <?php
1007 + if ( ! empty( $result ) && is_wp_error( $result ) ) {
1008 + ?>
1009 + <div class="ui message yellow"><i class="close icon"></i> <?php echo esc_html( $result->get_error_message() ); ?></div>
1010 + <?php
1011 + }
1012 + $el_id_mes_zn_1 = 'mainwp-message-zone';
1013 + ?>
1014 + <div id="<?php echo esc_attr( $el_id_mes_zn_1 ); ?>" class="ui message" style="display:none"></div>
1015 + <h3 class="ui dividing header">
1016 + <?php echo esc_html( $title_page ); ?>
1017 + <div class="sub header"><?php esc_html_e( 'Import multiple clients to your MainWP Dashboard.', 'mainwp' ); ?></div>
1018 + </h3>
1019 + <?php MainWP_UI::generate_wp_nonce( 'mainwp-admin-nonce' ); ?>
1020 + <div class="ui grid field">
1021 + <label class="three wide column middle aligned" for="mainwp_client_import_file_bulkupload"><?php esc_html_e( 'Upload CSV', 'mainwp' ); ?> (<a href="<?php echo esc_url( MAINWP_PLUGIN_URL . 'assets/csv/sample_clients.csv' ); ?>" target="_blank"><?php esc_html_e( 'Download Sample', 'mainwp' ); ?></a>)</label>
1022 + <div class="nine wide column">
1023 + <div class="ui file input">
1024 + <input type="file" name="mainwp_client_import_file_bulkupload" id="mainwp_client_import_file_bulkupload" accept="text/comma-separated-values"/>
1025 + </div>
1026 + </div>
1027 + <div class="ui toggle checkbox four wide column middle aligned">
1028 + <input type="checkbox" name="mainwp_client_import_chk_header_first" checked="checked" id="mainwp_client_import_chk_header_first" value="1"/>
1029 + <label for="mainwp_client_import_chk_header_first"><?php esc_html_e( 'CSV file contains a header', 'mainwp' ); ?></label>
1030 + </div>
1031 + </div>
1032 + </div>
1033 + <div class="ui segment">
1034 + <div class="ui divider"></div>
1035 + <input type="submit" name="mainwp_client_import_add" id="mainwp_client_import_bulkadd" class="ui big green button" value="<?php echo esc_attr( $title_page ); ?>"/>
1036 + </div>
1037 + </form>
1038 + </div>
1039 + <script type="text/javascript">
1040 + jQuery('#mainwp-import-client-tabular-menu .item').tab();
1041 + </script>
1042 + <?php
1043 + static::render_footer( 'ImportClients' );
1044 + }
1045 + /**
1046 + * Method render_import_client_modal()
1047 + *
1048 + * Render HTML import client modal.
1049 + *
1050 + * @return mixed Result.
1051 + */
1052 + public static function render_import_client_modal() {
1053 + $import_client_data = false;
1054 + $has_file_upload = isset( $_FILES['mainwp_client_import_file_bulkupload'] ) && isset( $_FILES['mainwp_client_import_file_bulkupload']['error'] ) && UPLOAD_ERR_OK === $_FILES['mainwp_client_import_file_bulkupload']['error']; // phpcs:ignore -- NOSONAR
1055 + if ( $has_file_upload ) {
1056 + $import_client_data = static::handle_client_import_files();
1057 + }
1058 + if ( ! is_array( $import_client_data ) || empty( $import_client_data['data'] ) || ! is_array( $import_client_data['data'] ) ) {
1059 + return new \WP_Error(
1060 + 'client_import_failed',
1061 + __( 'Failed to import client data. Please try again.', 'mainwp' )
1062 + );
1063 + }
1064 + ?>
1065 + <div class="ui large modal mainwp-qsw-import-client-modal" id="mainwp-import-client-modal" >
1066 + <i class="close icon"></i>
1067 + <div class="header"><?php esc_html_e( 'Import Clients', 'mainwp' ); ?></div>
1068 + <div class="scrolling content">
1069 + <?php static::render_import_client_row_modal( $import_client_data ); ?>
1070 + </div>
1071 + <div class="actions">
1072 + <div class="ui two column grid">
1073 + <div class="left aligned middle aligned column">
1074 + <input type="button" name="mainwp_manageclients_btn_import" id="mainwp_manageclients_btn_import" class="ui basic button" value="<?php esc_attr_e( 'Pause', 'mainwp' ); ?>"/>
1075 + </div>
1076 + </div>
1077 + </div>
1078 + </div>
1079 + <script type="text/javascript">
1080 + jQuery( document ).ready( function () {
1081 + jQuery('#mainwp-import-client-tabular-menu .item').tab();
1082 + jQuery( "#mainwp-import-client-modal" ).modal( {
1083 + closable: false,
1084 + onHide: function() {
1085 + location.reload();
1086 + }
1087 + } ).modal( 'show' );
1088 + } );
1089 + </script>
1090 + <?php
1133 1091
1134 - if ( ! is_array( $client_fields ) ) {
1135 - $client_fields = array();
1136 - }
1092 + return true;
1093 + }
1137 1094
1138 - if ( ! isset( $client_fields['default_field']['client.name'] ) || empty( $client_fields['default_field']['client.name'] ) ) {
1139 - echo wp_json_encode( array( 'error' => esc_html__( 'Client name are empty. Please try again.', 'mainwp' ) ) );
1140 - return;
1141 - }
1095 + /**
1096 + * Method render_import_client_row_modal()
1097 + *
1098 + * Render row HTML import client.
1099 + *
1100 + * @return mixed Result or WP_Error.
1101 + */
1102 + public static function render_import_client_row_modal( $client_data = array() ) { // phpcs:ignore -- NOSONAR -complex.
1142 1103
1143 - $add_new = true;
1104 + if ( is_array( $client_data ) && ! empty( $client_data['data'] ) && is_array( $client_data['data'] ) ) {
1105 + ?>
1106 + <div id="mainwp-importing-clients" class="ui active dimmer">
1107 + <div class="ui double text loader"><?php esc_html_e( 'Importing...', 'mainwp' ); ?></div>
1108 + </div>
1109 + <div class="ui message" id="mainwp-import-clients-status-message">
1110 + <i class="notched circle loading icon"></i> <?php echo esc_html__( 'Importing...', 'mainwp' ); ?>
1111 + </div>
1112 + <?php
1113 + $row = 0;
1114 + $header_line = trim( $client_data['header_line'] );
1115 + foreach ( $client_data['data'] as $val_client_data ) {
1116 + $encoded = wp_json_encode( $val_client_data );
1117 + $original = implode(
1118 + ', ',
1119 + array_map(
1120 + function ( $item ) {
1121 + return is_array( $item ) ? implode( ';', $item ) : $item;
1122 + },
1123 + $val_client_data
1124 + )
1125 + );
1126 + ?>
1127 + <input type="hidden" id="mainwp_manageclients_import_csv_line_<?php echo esc_attr( $row + 1 ); ?>" value="" encoded-data="<?php echo esc_attr( $encoded ); ?>" original="<?php echo esc_attr( $original ); ?>"/>
1128 + <?php
1129 + ++$row;
1130 + }
1131 + ?>
1132 + <input type="hidden" id="mainwp_manageclients_do_import" value="1"/>
1133 + <input type="hidden" id="mainwp_manageclients_total_import" value="<?php echo esc_attr( $row ); ?>"/>
1134 + <div class="mainwp_manageclients_import_listing" id="mainwp_manageclients_import_logging">
1135 + <span class="log ui medium text"><?php echo esc_html( $header_line ) . '<br/>'; ?></span>
1136 + </div>
1137 + <div class="mainwp_manageclients_import_listing" id="mainwp_manageclients_import_fail_logging" style="display: none;"><?php echo esc_html( $header_line ); ?> </div>
1138 + <?php
1139 + }
1140 + }
1144 1141
1145 - $dirs = MainWP_System_Utility::get_mainwp_dir( 'client-images', true );
1146 - $base_dir = $dirs[0];
1142 + /**
1143 + * Method handle_client_import_files()
1144 + *
1145 + * Handle client import files.
1146 + *
1147 + * @uses MainWP_System_Utility::get_wp_file_system()
1148 + * @uses MainWP_DB::instance()->get_websites_by_url()
1149 + *
1150 + * @return array Import data.
1151 + */
1152 + public static function handle_client_import_files() { // phpcs:ignore -- NOSONAR
1147 1153
1148 - $default_client_fields = MainWP_Client_Handler::get_default_client_fields();
1149 - $client_to_add = array();
1150 - foreach ( $default_client_fields as $field_name => $item ) {
1151 - if ( ! empty( $item['db_field'] ) ) {
1152 - if ( isset( $client_fields['default_field'][ $field_name ] ) ) {
1153 - $client_to_add[ $item['db_field'] ] = sanitize_text_field( wp_unslash( $client_fields['default_field'][ $field_name ] ) );
1154 - }
1155 - }
1156 - }
1154 + if ( isset( $_FILES['mainwp_client_import_file_bulkupload']['error'] ) && UPLOAD_ERR_OK !== $_FILES['mainwp_client_import_file_bulkupload']['error'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- NOSONAR
1155 + return false;
1156 + }
1157 1157
1158 - $client_to_add['primary_contact_id'] = isset( $client_fields['default_field']['primary_contact_id'] ) ? intval( $client_fields['default_field']['primary_contact_id'] ) : 0;
1158 + $tmp_path = isset( $_FILES['mainwp_client_import_file_bulkupload']['tmp_name'] ) ? $_FILES['mainwp_client_import_file_bulkupload']['tmp_name'] : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- NOSONAR
1159 1159
1160 - $client_id = isset( $client_fields['client_id'] ) ? intval( $client_fields['client_id'] ) : 0;
1160 + if ( ! is_uploaded_file( $tmp_path ) ) {
1161 + return false;
1162 + }
1161 1163
1162 - $new_suspended = $client_to_add['suspended'];
1163 - $old_suspended = $new_suspended;
1164 + $hasWPFileSystem = MainWP_System_Utility::get_wp_file_system();
1165 + //phpcs:enable
1166 + /**
1167 + * WordPress files system object.
1168 + *
1169 + * @global object
1170 + */
1171 + global $wp_filesystem;
1164 1172
1165 - if ( $client_id ) {
1166 - $current_client = MainWP_DB_Client::instance()->get_wp_client_by( 'client_id', $client_id );
1167 - $old_suspended = $current_client->suspended;
1173 + $lines = array();
1174 + $header_line = '';
1168 1175
1169 - $client_to_add['client_id'] = $client_id; // update client.
1170 - if ( isset( $client_to_add['created'] ) && ! empty( $client_to_add['created'] ) ) {
1171 - $client_to_add['created'] = strtotime( $client_to_add['created'] );
1172 - }
1173 - $add_new = false;
1174 - } else {
1175 - $client_to_add['created'] = time();
1176 - }
1176 + if ( $hasWPFileSystem && ! empty( $wp_filesystem ) ) {
1177 + $content = $wp_filesystem->get_contents( $tmp_path );
1178 + if ( ! empty( $content ) ) {
1179 + // to compatible with EOL on OSs.
1180 + $content = str_replace( "\r\n", "\r", $content );
1181 + $content = str_replace( "\n", "\r", $content );
1182 + $lines = explode( "\r", $content );
1183 + }
1184 + } else {
1185 + return false;
1186 + }
1177 1187
1178 - try {
1179 - $inserted = MainWP_DB_Client::instance()->update_client( $client_to_add, true );
1180 - } catch ( \Exception $e ) {
1181 - echo wp_json_encode( array( 'error' => $e->getMessage() ) );
1182 - return;
1183 - }
1188 + $import_data = array();
1189 + $default_values = array(
1190 + 'client.name' => '',
1191 + 'client.email' => '',
1192 + 'client.contact.address.1' => '',
1193 + 'client.contact.address.2' => '',
1194 + 'client.city' => '',
1195 + 'client.state' => '',
1196 + 'client.zip' => '',
1197 + 'client.country' => '',
1198 + 'client.suspended' => 0,
1199 + 'client.url' => '',
1200 + );
1201 + if ( is_array( $lines ) && ( ! empty( $lines ) ) ) {
1202 + $header_line = null;
1203 + foreach ( $lines as $original_line ) {
1204 + $line = trim( $original_line );
1205 + if ( MainWP_Utility::starts_with( $line, '#' ) ) {
1206 + continue;
1207 + }
1184 1208
1185 - if ( $client_id ) {
1186 - MainWP_DB_Client::instance()->update_selected_sites_for_client( $client_id, $selected_sites );
1187 - } elseif ( is_object( $inserted ) ) {
1188 - MainWP_DB_Client::instance()->update_selected_sites_for_client( $inserted->client_id, $selected_sites );
1189 - $client_id = $inserted->client_id;
1190 - }
1209 + $items = str_getcsv( $line, ',' );
1191 1210
1192 - if ( is_object( $inserted ) ) {
1193 - /**
1194 - * Add client
1195 - *
1196 - * Fires after add a client.
1197 - *
1198 - * @param object $inserted client data.
1199 - * @param bool $add_new true add new, false updated.
1200 - *
1201 - * @since 4.5.1.1
1202 - */
1203 - do_action( 'mainwp_client_updated', $inserted, $add_new );
1211 + if ( ( null === $header_line ) && ! empty( $_POST['mainwp_client_import_chk_header_first'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- NOSONAR
1212 + $header_line = sanitize_text_field( $line ) . "\r";
1213 + continue;
1214 + }
1215 + if ( 3 > count( $items ) ) {
1216 + continue;
1217 + }
1204 1218
1205 - if ( ! $add_new && $new_suspended != $old_suspended ) { //phpcs:ignore -- to valid.
1206 - /**
1207 - * Fires immediately after update client suspend/unsuspend.
1208 - *
1209 - * @since 4.5.1.1
1210 - *
1211 - * @param object $client client data.
1212 - * @param bool $new_suspended true|false.
1213 - */
1214 - do_action( 'mainwp_client_suspend', $inserted, $new_suspended );
1215 - }
1216 - }
1219 + $x = 0;
1220 + $import_fields = array();
1221 + // Take data from the CSV file into the array.
1222 + foreach ( $default_values as $field => $val ) {
1223 + $value = isset( $items[ $x ] ) ? $items[ $x ] : $val;
1224 + $import_fields[ $field ] = sanitize_text_field( $value );
1225 + ++$x;
1226 + }
1227 + $import_data[] = $import_fields;
1228 + }
1229 + }
1217 1230
1218 - if ( $client_id && isset( $client_fields['custom_fields'] ) && is_array( $client_fields['custom_fields'] ) ) {
1219 - foreach ( $client_fields['custom_fields'] as $input_name => $field_val ) {
1220 - $field_id = array_key_first( $field_val );
1221 - // update custom field value for client.
1222 - if ( $field_id ) {
1223 - $val = $field_val[ $field_id ];
1224 - MainWP_DB_Client::instance()->update_client_field_value( $field_id, $val, $client_id );
1225 - }
1226 - }
1227 - }
1231 + if ( ! empty( $import_data ) ) {
1232 + foreach ( $import_data as $k_import => $val_import ) {
1233 + if ( ! empty( $val_import['client.url'] ) ) {
1234 + $import_data[ $k_import ]['client.url'] = explode( ';', sanitize_text_field( $val_import['client.url'] ) );
1235 + }
1236 + }
1237 + }
1238 + return array(
1239 + 'header_line' => esc_js( $header_line ),
1240 + 'data' => $import_data,
1241 + );
1242 + }
1228 1243
1229 - $client_image = 'NOTCHANGE';
1230 - if ( isset( $_POST['mainwp_client_delete_image']['client_field'] ) && $client_id === (int) $_POST['mainwp_client_delete_image']['client_field'] ) { // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1231 - $client_image = '';
1232 - }
1244 + /**
1245 + * Renders the Add New Client Fields form.
1246 + */
1247 + public static function render_client_fields() { // phpcs:ignore -- NOSONAR - Current complexity is the only way to achieve desired results, pull request solutions appreciated.
1233 1248
1234 - if ( isset( $_FILES['mainwp_client_image_uploader']['error']['client_field'] ) && UPLOAD_ERR_OK === $_FILES['mainwp_client_image_uploader']['error']['client_field'] ) { // phpcs:ignore WordPress.Security.NonceVerification
1235 - $output = MainWP_System_Utility::handle_upload_image( 'client-images', $_FILES['mainwp_client_image_uploader'], 'client_field' ); // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1236 - if ( is_array( $output ) && isset( $output['filename'] ) && ! empty( $output['filename'] ) ) {
1237 - $client_image = $output['filename'];
1238 - }
1239 - }
1249 + $fields = MainWP_DB_Client::instance()->get_client_fields();
1250 + $has_no_fields = empty( $fields );
1240 1251
1241 - if ( 'NOTCHANGE' !== $client_image && $client_id ) {
1242 - $client_data = MainWP_DB_Client::instance()->get_wp_client_by( 'client_id', $client_id );
1252 + static::render_header( 'AddField' );
1243 1253
1244 - $old_file = $client_data->image;
1245 - if ( $old_file !== $client_image && ! empty( $old_file ) ) {
1246 - $delete_old_file = $base_dir . '/' . $old_file;
1247 - if ( file_exists( $delete_old_file ) ) {
1248 - wp_delete_file( $delete_old_file );
1249 - }
1250 - }
1251 - $update = array(
1252 - 'client_id' => $client_id,
1253 - 'image' => $client_image,
1254 - );
1255 - MainWP_DB_Client::instance()->update_client( $update );
1256 - }
1254 + if ( ! $has_no_fields ) {
1255 + ?>
1256 + <div class="mainwp-sub-header">
1257 + <div class="ui grid">
1258 + <div class="equal width row ui mini form">
1259 + <div class="middle aligned column">
1260 + <div id="mainwp-client-fields-bulk-actions-menu" class="ui selection dropdown disabled">
1261 + <div class="default text"><?php esc_html_e( 'Bulk actions', 'mainwp' ); ?></div>
1262 + <i class="dropdown icon"></i>
1263 + <div class="menu">
1264 + <div class="item" data-value="delete"><?php esc_html_e( 'Delete', 'mainwp' ); ?></div>
1265 + </div>
1266 + </div>
1267 + <button class="ui mini basic button" id="mainwp-do-client-fields-bulk-actions" disabled="disabled"><?php esc_html_e( 'Apply', 'mainwp' ); ?></button>
1268 + </div>
1269 + <div class="right aligned middle aligned column">
1270 + <a class="ui mini green basic button" href="javascript:void(0);" id="mainwp-clients-new-custom-field-button"><i class="plus icon"></i><?php esc_html_e( 'Add Client Field', 'mainwp' ); ?></a>
1271 + </div>
1272 + </div>
1273 + </div>
1274 + </div>
1275 + <?php
1276 + }
1277 + ?>
1278 + <div class="ui padded segment" id="mainwp-add-client-fields">
1279 + <?php if ( $has_no_fields ) : ?>
1280 + <?php MainWP_UI::render_empty_page_placeholder( esc_html__( 'No custom fields created yet.', 'mainwp' ), esc_html__( 'Create custom fields to capture additional information about your clients. Click the New Field button to get started.', 'mainwp' ), '<em data-emoji=":compass:" class="big"></em>' ); ?>
1281 + <div style="text-align: center; margin-top: 20px;">
1282 + <a class="ui green button" href="javascript:void(0);" id="mainwp-clients-new-custom-field-button"><?php esc_html_e( 'Add Client Field', 'mainwp' ); ?></a>
1283 + </div>
1284 + <?php else : ?>
1285 + <div class="ui message" id="mainwp-message-zone-client" style="display:none;"></div>
1286 + <?php if ( count( $fields ) < 5 && MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-client-fields-tip' ) ) : ?>
1287 + <div class="ui message">
1288 + <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-client-fields-tip"></i>
1289 + <?php
1290 + // translators: 1: Bulb emoji element. 2: Opening anchor tag. 3: Closing anchor tag.
1291 + printf( esc_html__( '%1$s Tip: Custom Client Fields let you store extra details unique to your workflow, such as billing info, project type, or renewal dates. Once added, these fields will appear when adding or editing a client. %2$sLearn more%3$s about how custom fields work.', 'mainwp' ), '<em data-emoji=":bulb:" class="small"></em>', '<a href="https://docs.mainwp.com/clients/manage-clients#client-fields" target="_blank">', '</a>' );
1292 + ?>
1293 + </div>
1294 + <?php endif; ?>
1295 + <table id="mainwp-clients-custom-fields-table" class="ui table" style="width:100%">
1296 + <thead>
1297 + <tr>
1298 + <th scope="col" class="no-sort collapsing check-column">
1299 + <div class="ui checkbox">
1300 + <input type="checkbox" id="mainwp-client-fields-select-all">
1301 + <label></label>
1302 + </div>
1303 + </th>
1304 + <th scope="col"><?php esc_html_e( 'Field Name', 'mainwp' ); ?></th>
1305 + <th scope="col"><?php esc_html_e( 'Field Description', 'mainwp' ); ?></th>
1306 + <th scope="col" class="no-sort collapsing"></th>
1307 + </tr>
1308 + </thead>
1309 + <tbody>
1310 + <?php if ( is_array( $fields ) && ! empty( $fields ) ) : ?>
1311 + <?php foreach ( $fields as $field ) : ?>
1312 + <?php
1313 + if ( ! $field ) {
1314 + continue;
1315 + }
1316 + ?>
1317 + <tr class="mainwp-field none-selected-color" field-id="<?php echo intval( $field->field_id ); ?>">
1318 + <td class="check-column">
1319 + <div class="ui checkbox">
1320 + <input type="checkbox" class="mainwp-client-field-checkbox" value="<?php echo intval( $field->field_id ); ?>">
1321 + <label></label>
1322 + </div>
1323 + </td>
1324 + <td class="field-name">[<?php echo esc_html( stripslashes( $field->field_name ) ); ?>]</td>
1325 + <td class="field-description"><?php echo esc_html( stripslashes( $field->field_desc ) ); ?></td>
1326 + <td>
1327 + <div class="ui right pointing dropdown">
1328 + <i class="ellipsis vertical icon"></i>
1329 + <div class="menu">
1330 + <a class="item" id="mainwp-clients-edit-custom-field" href="#"><?php esc_html_e( 'Edit', 'mainwp' ); ?></a>
1331 + <a class="item" id="mainwp-clients-delete-general-field" href="#"><?php esc_html_e( 'Delete', 'mainwp' ); ?></a>
1332 + </div>
1333 + </div>
1334 + </td>
1335 + </tr>
1336 + <?php endforeach; ?>
1337 + <?php endif; ?>
1338 + </tbody>
1339 + </table>
1257 1340
1258 - $is_first_contact = true;
1259 - $auto_assign_contact_id = 0;
1341 + <script type="text/javascript">
1342 + // Init datatables
1343 + jQuery( '#mainwp-clients-custom-fields-table' ).DataTable( {
1344 + "stateSave": true,
1345 + "stateDuration": 0,
1346 + "lengthMenu": [ [10, 25, 50, 100, -1], [10, 25, 50, 100, "All"] ],
1347 + "columnDefs": [ { "orderable": false, "targets": "no-sort" } ],
1348 + "order": [ [ 0, "asc" ] ],
1349 + "language": { "emptyTable": "No fields found." },
1350 + "drawCallback" : function( settings ) {
1351 + jQuery( '#mainwp-clients-custom-fields-table .ui.dropdown').dropdown();
1352 + jQuery( '#mainwp-clients-custom-fields-table .ui.checkbox').checkbox();
1353 + },
1354 + stateSaveParams: function (settings, data) {
1355 + data._mwpv = mainwpParams.mainwpVersion || 'dev';
1356 + },
1357 + stateLoadParams: function (settings, data) {
1358 + if ((mainwpParams.mainwpVersion || 'dev') !== data._mwpv) return false;
1359 + },
1360 + search: { regex: false, smart: false },
1361 + orderMulti: false,
1362 + searchDelay: 350
1363 + } );
1260 1364
1261 - if ( $client_id && isset( $client_fields['contacts_field'] ) ) {
1365 + // Initialize header checkbox
1366 + jQuery( '#mainwp-clients-custom-fields-table thead .ui.checkbox' ).checkbox();
1367 + </script>
1368 + <?php endif; ?>
1369 + </div>
1262 1370
1263 - foreach ( $client_fields['contacts_field']['client.contact.name'] as $indx => $contact_name ) {
1264 - $contact_to_add = array();
1265 - if ( empty( $contact_name ) ) {
1266 - continue;
1267 - }
1268 - $contact_to_add['contact_name'] = $contact_name;
1371 + <?php
1372 + static::render_add_field_modal();
1373 + static::render_footer( 'AddField' );
1374 + }
1269 1375
1270 - $contact_email = $client_fields['contacts_field']['contact.email'][ $indx ];
1271 - if ( empty( $contact_email ) ) {
1272 - continue;
1273 - }
1376 + /**
1377 + * Method render_add_field_modal()
1378 + *
1379 + * Render add custom field modal.
1380 + *
1381 + * @param int $client_id The client id.
1382 + */
1383 + public static function render_add_field_modal( $client_id = 0 ) {
1384 + ?>
1385 + <div class="ui small modal" id="mainwp-clients-custom-field-modal">
1386 + <i class="close icon"></i>
1387 + <div class="header"><?php esc_html_e( 'Custom Field', 'mainwp' ); ?></div>
1388 + <div class="content ui mini form">
1389 + <div class="ui yellow message" style="display:none"></div>
1390 + <div class="field">
1391 + <label><?php esc_html_e( 'Field Name', 'mainwp' ); ?> <span class="ui small red text"><?php esc_html_e( '(Required)', 'mainwp' ); ?></span></label>
1392 + <input type="text" value="" class="field-name" name="field-name" placeholder="<?php esc_attr_e( 'Enter field name (without of square brackets)', 'mainwp' ); ?>">
1393 + </div>
1394 + <div class="field">
1395 + <label><?php esc_html_e( 'Field Description', 'mainwp' ); ?> <span class="ui small red text"><?php esc_html_e( '(Required)', 'mainwp' ); ?></span></label>
1396 + <input type="text" value="" class="field-description" name="field-description" placeholder="<?php esc_attr_e( 'Enter field description', 'mainwp' ); ?>">
1397 + </div>
1398 + </div>
1399 + <div class="actions">
1400 + <input type="button" class="ui green mini button disabled" client-id="<?php echo intval( $client_id ); ?>" id="mainwp-clients-save-new-custom-field" value="<?php esc_attr_e( 'Save Field', 'mainwp' ); ?>" disabled>
1401 + </div>
1402 + <input type="hidden" value="0" name="field-id">
1403 + </div>
1404 + <?php
1405 + }
1274 1406
1275 - $contact_id = isset( $client_fields['contacts_field']['contact_id'][ $indx ] ) ? intval( $client_fields['contacts_field']['contact_id'][ $indx ] ) : 0;
1407 + /**
1408 + * Method add_client()
1409 + *
1410 + * Bulk client addition $_POST Handler.
1411 + */
1412 + public static function add_client() { // phpcs:ignore -- NOSONAR -Current complexity is required to achieve desired results. Pull request solutions appreciated.
1276 1413
1277 - if ( empty( $contact_id ) ) {
1278 - continue;
1279 - }
1414 + $selected_sites = ( isset( $_POST['selected_sites'] ) && is_array( $_POST['selected_sites'] ) ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['selected_sites'] ) ) : array(); //phpcs:ignore WordPress.Security.NonceVerification.Missing
1415 + $client_fields = isset( $_POST['client_fields'] ) ? wp_unslash( $_POST['client_fields'] ) : array(); //phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1280 1416
1281 - $contact_to_add['contact_email'] = $contact_email;
1417 + if ( ! is_array( $client_fields ) ) {
1418 + $client_fields = array();
1419 + }
1282 1420
1283 - $contact_to_add['contact_phone'] = $client_fields['contacts_field']['contact.phone'][ $indx ];
1284 - $contact_to_add['contact_role'] = $client_fields['contacts_field']['contact.role'][ $indx ];
1285 - $contact_to_add['facebook'] = $client_fields['contacts_field']['contact.facebook'][ $indx ];
1286 - $contact_to_add['twitter'] = $client_fields['contacts_field']['contact.twitter'][ $indx ];
1287 - $contact_to_add['instagram'] = $client_fields['contacts_field']['contact.instagram'][ $indx ];
1288 - $contact_to_add['linkedin'] = $client_fields['contacts_field']['contact.linkedin'][ $indx ];
1421 + $editing_client_id = isset( $client_fields['client_id'] ) ? intval( $client_fields['client_id'] ) : 0;
1289 1422
1290 - $contact_to_add['contact_client_id'] = $client_id;
1291 - $contact_to_add['contact_id'] = $contact_id;
1423 + if ( ! empty( $editing_client_id ) && ! wp_verify_nonce( $_POST['nonce_client_id'], 'editing-client-' . $editing_client_id ) ) { //phpcs:ignore -- NOSONAR - ok.
1424 + die( 'Invalid nonce!' );
1425 + }
1292 1426
1293 - $updated = MainWP_DB_Client::instance()->update_client_contact( $contact_to_add );
1427 + if ( ! isset( $client_fields['default_field']['client.name'] ) || empty( $client_fields['default_field']['client.name'] ) ) {
1428 + echo wp_json_encode( array( 'error' => esc_html__( 'Client name are empty. Please try again.', 'mainwp' ) ) );
1429 + return;
1430 + }
1294 1431
1295 - $is_first_contact = false;
1432 + $add_new = true;
1296 1433
1297 - if ( $updated ) {
1298 - $contact_image = 'NOTCHANGE';
1299 - if ( isset( $_POST['mainwp_client_delete_image']['contacts_field'][ $contact_id ] ) && $contact_id === (int) $_POST['mainwp_client_delete_image']['contacts_field'][ $contact_id ] ) { // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1300 - $contact_image = '';
1301 - }
1434 + $default_client_fields = MainWP_Client_Handler::get_default_client_fields();
1435 + $client_to_add = array();
1436 + foreach ( $default_client_fields as $field_name => $item ) {
1437 + if ( ! empty( $item['db_field'] ) && isset( $client_fields['default_field'][ $field_name ] ) ) {
1438 + $client_to_add[ $item['db_field'] ] = sanitize_text_field( wp_unslash( $client_fields['default_field'][ $field_name ] ) );
1439 + }
1440 + }
1302 1441
1303 - if ( isset( $_FILES['mainwp_client_image_uploader']['error']['contacts_field'][ $indx ] ) && UPLOAD_ERR_OK === $_FILES['mainwp_client_image_uploader']['error']['contacts_field'][ $indx ] ) { // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1304 - $output = MainWP_System_Utility::handle_upload_image( 'client-images', $_FILES['mainwp_client_image_uploader'], 'contacts_field', $indx ); // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1305 - if ( is_array( $output ) && isset( $output['filename'] ) && ! empty( $output['filename'] ) ) {
1306 - $contact_image = $output['filename'];
1307 - }
1308 - }
1442 + $client_to_add['primary_contact_id'] = isset( $client_fields['default_field']['primary_contact_id'] ) ? intval( $client_fields['default_field']['primary_contact_id'] ) : 0;
1309 1443
1310 - if ( 'NOTCHANGE' !== $contact_image && $client_id ) {
1311 - $contact_data = MainWP_DB_Client::instance()->get_wp_client_contact_by( 'contact_id', $contact_id );
1444 + $client_id = isset( $client_fields['client_id'] ) ? intval( $client_fields['client_id'] ) : 0;
1312 1445
1313 - $old_file = $contact_data->contact_image;
1314 - if ( $old_file !== $contact_image && ! empty( $old_file ) ) {
1315 - $delete_old_file = $base_dir . '/' . $old_file;
1316 - if ( file_exists( $delete_old_file ) ) {
1317 - wp_delete_file( $delete_old_file );
1318 - }
1319 - }
1320 - $update = array(
1321 - 'contact_id' => $contact_id,
1322 - 'contact_image' => $contact_image,
1323 - );
1324 - MainWP_DB_Client::instance()->update_client_contact( $update );
1325 - }
1326 - }
1327 - }
1328 - }
1446 + $new_suspended = isset( $client_to_add['suspended'] ) ? (int) $client_to_add['suspended'] : 0;
1447 + $old_suspended = $new_suspended;
1329 1448
1330 - if ( $client_id && isset( $client_fields['new_contacts_field'] ) ) {
1449 + if ( $client_id ) {
1450 + $current_client = MainWP_DB_Client::instance()->get_wp_client_by( 'client_id', $client_id );
1451 + $old_suspended = $current_client->suspended;
1331 1452
1332 - $first_contact_id = 0;
1333 - foreach ( $client_fields['new_contacts_field']['client.contact.name'] as $indx => $contact_name ) {
1334 - $contact_to_add = array();
1335 - if ( empty( $contact_name ) ) {
1336 - continue;
1337 - }
1338 - $contact_to_add['contact_name'] = $contact_name;
1453 + $client_to_add['client_id'] = $client_id; // update client.
1454 + if ( isset( $client_to_add['created'] ) && ! empty( $client_to_add['created'] ) ) {
1455 + $client_to_add['created'] = strtotime( $client_to_add['created'] );
1456 + }
1457 + $add_new = false;
1339 1458
1340 - $contact_email = $client_fields['new_contacts_field']['contact.email'][ $indx ];
1341 - if ( empty( $contact_email ) ) {
1342 - continue;
1343 - }
1344 - $contact_to_add['contact_email'] = $contact_email;
1459 + $current_sites_ids = array();
1460 + $current_sites = MainWP_DB_Client::instance()->get_websites_by_client_ids( $client_id, array( 'no_perm_check' => true ) );
1345 1461
1346 - $contact_to_add['contact_phone'] = $client_fields['new_contacts_field']['contact.phone'][ $indx ];
1347 - $contact_to_add['contact_role'] = $client_fields['new_contacts_field']['contact.role'][ $indx ];
1348 - $contact_to_add['facebook'] = $client_fields['new_contacts_field']['contact.facebook'][ $indx ];
1349 - $contact_to_add['twitter'] = $client_fields['new_contacts_field']['contact.twitter'][ $indx ];
1350 - $contact_to_add['instagram'] = $client_fields['new_contacts_field']['contact.instagram'][ $indx ];
1351 - $contact_to_add['linkedin'] = $client_fields['new_contacts_field']['contact.linkedin'][ $indx ];
1462 + if ( ! empty( $current_sites ) ) {
1463 + $current_sites_ids = array_values(
1464 + array_map(
1465 + function ( $item ) {
1466 + return $item->id;
1467 + },
1468 + $current_sites
1469 + )
1470 + );
1471 + }
1352 1472
1353 - $contact_to_add['contact_client_id'] = $client_id;
1473 + $selected_sites = MainWP_System::get_selected_sites_with_allowed_sites( $selected_sites, $current_sites_ids );
1474 + } else {
1475 + $client_to_add['created'] = time();
1476 + }
1354 1477
1355 - $inserted = MainWP_DB_Client::instance()->update_client_contact( $contact_to_add );
1478 + try {
1479 + $inserted = MainWP_DB_Client::instance()->update_client( $client_to_add, true );
1480 + } catch ( \Exception $e ) {
1481 + echo wp_json_encode( array( 'error' => $e->getMessage() ) );
1482 + return;
1483 + }
1356 1484
1357 - if ( $inserted ) {
1485 + if ( $client_id ) {
1486 + MainWP_DB_Client::instance()->update_selected_sites_for_client( $client_id, $selected_sites );
1487 + } elseif ( is_object( $inserted ) ) {
1488 + MainWP_DB_Client::instance()->update_selected_sites_for_client( $inserted->client_id, $selected_sites );
1489 + $client_id = $inserted->client_id;
1490 + }
1358 1491
1359 - $contact_id = $inserted->contact_id;
1360 - $contact_image = '';
1492 + if ( is_object( $inserted ) ) {
1361 1493
1362 - if ( isset( $_FILES['mainwp_client_image_uploader']['error']['new_contacts_field'][ $indx ] ) && UPLOAD_ERR_OK === $_FILES['mainwp_client_image_uploader']['error']['new_contacts_field'][ $indx ] ) { // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1363 - $output = MainWP_System_Utility::handle_upload_image( 'client-images', $_FILES['mainwp_client_image_uploader'], 'new_contacts_field', $indx ); // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1364 - if ( is_array( $output ) && isset( $output['filename'] ) && ! empty( $output['filename'] ) ) {
1365 - $contact_image = $output['filename'];
1366 - }
1367 - }
1494 + static::invalidate_warm_cache();
1368 1495
1369 - if ( '' !== $contact_image && $contact_id ) {
1370 - $update = array(
1371 - 'contact_id' => $contact_id,
1372 - 'contact_image' => $contact_image,
1373 - );
1374 - MainWP_DB_Client::instance()->update_client_contact( $update );
1375 - }
1496 + /**
1497 + * Add client
1498 + *
1499 + * Fires after add a client.
1500 + *
1501 + * @param object $inserted client data.
1502 + * @param bool $add_new true add new, false updated.
1503 + *
1504 + * @since 4.5.1.1
1505 + */
1506 + do_action( 'mainwp_client_updated', $inserted, $add_new );
1376 1507
1377 - if ( $is_first_contact && empty( $auto_assign_contact_id ) ) {
1378 - $auto_assign_contact_id = $contact_id;
1379 - }
1380 - }
1381 - }
1382 - }
1508 + if ( ! $add_new && $new_suspended != $old_suspended ) { //phpcs:ignore -- to valid.
1509 + /**
1510 + * Fires immediately after update client suspend/unsuspend.
1511 + *
1512 + * @since 4.5.1.1
1513 + *
1514 + * @param object $client client data.
1515 + * @param bool $new_suspended true|false.
1516 + */
1517 + do_action( 'mainwp_client_suspend', $inserted, $new_suspended );
1518 + }
1519 + }
1383 1520
1384 - if ( $client_id && isset( $client_fields['delele_contacts'] ) && is_array( $client_fields['delele_contacts'] ) ) {
1385 - foreach ( $client_fields['delele_contacts'] as $delete_id ) {
1386 - MainWP_DB_Client::instance()->delete_client_contact( $client_id, $delete_id );
1387 - $is_first_contact = false;
1388 - }
1389 - }
1521 + if ( $client_id && isset( $client_fields['custom_fields'] ) && is_array( $client_fields['custom_fields'] ) ) {
1522 + foreach ( $client_fields['custom_fields'] as $field_val ) {
1523 + $field_id = array_key_first( $field_val );
1524 + // update custom field value for client.
1525 + if ( $field_id ) {
1526 + $val = $field_val[ $field_id ];
1527 + MainWP_DB_Client::instance()->update_client_field_value( $field_id, $val, $client_id );
1528 + }
1529 + }
1530 + }
1390 1531
1391 - if ( $is_first_contact && $auto_assign_contact_id && $client_id ) {
1392 - // auto assign.
1393 - $update = array(
1394 - 'client_id' => $client_id,
1395 - 'primary_contact_id' => $auto_assign_contact_id,
1396 - );
1397 - MainWP_DB_Client::instance()->update_client( $update );
1398 - }
1532 + $client_image = '';
1533 + if ( isset( $_POST['mainwp_add_edit_client_uploaded_icon_hidden'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
1534 + $client_image = sanitize_text_field( wp_unslash( $_POST['mainwp_add_edit_client_uploaded_icon_hidden'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
1535 + }
1399 1536
1400 - // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1401 - if ( isset( $_POST['is_first_client'] ) && ! empty( $_POST['is_first_client'] ) ) {
1402 - delete_transient( 'mainwp_transient_just_connected_site_id' );
1403 - }
1404 - //phpcs:enable
1537 + // compatible with quick setup.
1538 + if ( isset( $_FILES['mainwp_client_image_uploader']['error']['client_field'] ) && UPLOAD_ERR_OK === $_FILES['mainwp_client_image_uploader']['error']['client_field'] ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1539 + $output = MainWP_System_Utility::handle_upload_image( 'client-images', $_FILES['mainwp_client_image_uploader'], 'client_field' ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1540 + if ( is_array( $output ) && isset( $output['filename'] ) && ! empty( $output['filename'] ) ) {
1541 + $client_image = $output['filename'];
1542 + }
1543 + }
1405 1544
1406 - echo wp_json_encode(
1407 - array(
1408 - 'success' => 'yes',
1409 - 'client_id' => $client_id,
1410 - )
1411 - );
1412 - }
1545 + $client_data = MainWP_DB_Client::instance()->get_wp_client_by( 'client_id', $client_id );
1546 + if ( $client_data && $client_data->image !== $client_image && $client_id ) {
1547 + $old_file = $client_data->image;
1548 + if ( $old_file !== $client_image && ! empty( $old_file ) ) {
1549 + MainWP_Utility::instance()->delete_uploaded_icon_file( 'client-images', $old_file );
1550 + }
1551 + $update = array(
1552 + 'client_id' => $client_id,
1553 + 'image' => $client_image,
1554 + );
1555 + MainWP_DB_Client::instance()->update_client( $update );
1556 + }
1413 1557
1414 - /**
1415 - * Method render_add_client_modal().
1416 - *
1417 - * Renders add client Modal window.
1418 - */
1419 - public static function render_add_client_modal() {
1420 - ?>
1421 - <div id="mainwp-creating-new-client-modal" class="ui modal">
1422 - <i class="close icon"></i>
1423 - <div class="header"><?php esc_html_e( 'New client', 'mainwp' ); ?></div>
1424 - <div class="ui message" id="mainwp-message-zone-client" style="display:none;"></div>
1425 - <div class="scrolling content mainwp-modal-content">
1426 - <form action="" method="post" enctype="multipart/form-data" name="createclient_form" id="createclient_form" class="add:clients: validate">
1427 - <?php
1428 - self::render_add_client_content();
1429 - ?>
1430 - </form>
1431 - </div>
1432 - <div class="actions">
1433 - <div class="ui button green" current-page="modal-add" id="bulk_add_createclient"><?php esc_html_e( 'Add Client', 'mainwp' ); ?></div>
1434 - </div>
1435 - </div>
1558 + if ( $client_id && isset( $client_fields['default_field']['selected_icon'] ) ) {
1559 + $cust_icon = sanitize_text_field( wp_unslash( $client_fields['default_field']['selected_icon'] ) );
1560 + $cust_color = sanitize_hex_color( wp_unslash( $client_fields['default_field']['selected_color'] ) );
1561 + $update = array(
1562 + 'client_id' => $client_id,
1563 + 'selected_icon_info' => 'selected:' . $cust_icon . ';color:' . $cust_color,
1564 + );
1565 + MainWP_DB_Client::instance()->update_client( $update );
1566 + }
1436 1567
1437 - <script type="text/javascript">
1438 - jQuery(document).on('click', '.edit-site-new-client-button', function () {
1439 - jQuery('#mainwp-creating-new-client-modal').modal({
1440 - allowMultiple: false,
1441 - }).modal('show');
1442 - return false;
1443 - });
1444 - </script>
1445 - <?php
1446 - }
1568 + $is_first_contact = true;
1569 + $auto_assign_contact_id = 0;
1447 1570
1448 - /**
1449 - * Method render_add_client_content().
1450 - *
1451 - * Renders add client content window.
1452 - *
1453 - * @param mixed $edit_client The client data.
1454 - */
1455 - public static function render_add_client_content( $edit_client = false ) { // phpcs:ignore -- Current complexity is required to achieve desired results. Pull request solutions appreciated.
1456 - $client_id = $edit_client ? $edit_client->client_id : 0;
1457 - $default_client_fields = MainWP_Client_Handler::get_default_client_fields();
1458 - $custom_fields = MainWP_DB_Client::instance()->get_client_fields( true, $client_id, true );
1459 - $client_image = $edit_client ? $edit_client->image : '';
1571 + if ( $client_id && isset( $client_fields['contacts_field'] ) ) {
1460 1572
1461 - ?>
1462 - <h3 class="ui dividing header">
1463 - <?php if ( $client_id ) : ?>
1464 - <?php echo esc_html__( 'Edit Client', 'mainwp' ); ?>
1465 - <div class="sub header"><?php esc_html_e( 'Edit client information.', 'mainwp' ); ?></div>
1466 - <?php else : ?>
1467 - <?php esc_html_e( 'Add New Client', 'mainwp' ); ?>
1468 - <div class="sub header"><?php esc_html_e( 'Enter the client information.', 'mainwp' ); ?></div>
1469 - <?php endif; ?>
1470 - </h3>
1471 - <div class="ui form">
1472 - <?php
1573 + foreach ( $client_fields['contacts_field']['client.contact.name'] as $indx => $contact_name ) {
1574 + $contact_to_add = array();
1575 + if ( empty( $contact_name ) ) {
1576 + continue;
1577 + }
1578 + $contact_to_add['contact_name'] = sanitize_text_field( wp_unslash( $contact_name ) );
1473 1579
1474 - foreach ( $default_client_fields as $field_name => $field ) {
1475 - $db_field = isset( $field['db_field'] ) ? $field['db_field'] : '';
1476 - $val = $edit_client && '' !== $db_field && property_exists( $edit_client, $db_field ) ? $edit_client->{$db_field} : '';
1477 - $tip = isset( $field['tooltip'] ) ? $field['tooltip'] : '';
1478 - ?>
1479 - <div class="ui grid field">
1480 - <label class="six wide column middle aligned" <?php echo ! empty( $tip ) ? 'data-tooltip="' . esc_attr( $tip ) . '" data-inverted="" data-position="top left"' : ''; // phpcs:ignore WordPress.Security.EscapeOutput ?>><?php echo esc_html( $field['title'] ); ?></label>
1481 - <div class="ui six wide column">
1482 - <div class="ui left labeled input">
1483 - <?php
1484 - if ( 'client.note' === $field_name ) {
1485 - ?>
1486 - <div class="editor">
1487 - <textarea class="code" cols="80" rows="10" name="client_fields[default_field][<?php echo esc_attr( $field_name ); ?>]"><?php echo esc_html( $val ); ?></textarea>
1488 - </div>
1489 - <?php
1490 - } elseif ( 'client.suspended' === $field_name ) {
1491 - ?>
1492 - <select name="client_fields[default_field][<?php echo esc_attr( $field_name ); ?>]" id="client_fields[default_field][<?php echo esc_attr( $field_name ); ?>]" class="ui dropdown">
1493 - <option value="0" <?php echo ( '0' === $val ? 'selected' : '' ); ?>><?php esc_html_e( 'Active', 'mainwp' ); ?></option>
1494 - <option value="1" <?php echo ( '1' === $val ? 'selected' : '' ); ?>><?php esc_html_e( 'Suspended', 'mainwp' ); ?></option>
1495 - <option value="2" <?php echo ( '2' === $val ? 'selected' : '' ); ?>><?php esc_html_e( 'Lead', 'mainwp' ); ?></option>
1496 - <option value="3" <?php echo ( '3' === $val ? 'selected' : '' ); ?>><?php esc_html_e( 'Lost', 'mainwp' ); ?></option>
1497 - </select>
1498 - <?php
1499 - } elseif ( $client_id && 'client.created' === $field_name ) {
1500 - $created = empty( $val ) ? time() : $val;
1501 - ?>
1502 - <div class="ui calendar mainwp_datepicker" >
1503 - <div class="ui input left icon">
1504 - <i class="calendar icon"></i>
1505 - <input type="text" autocomplete="off" name="client_fields[default_field][<?php echo esc_attr( $field_name ); ?>]" placeholder="<?php esc_attr_e( 'Added date', 'mainwp' ); ?>" id="client_fields[default_field][<?php echo esc_attr( $field_name ); ?>]" value="<?php echo esc_attr( date( 'Y-m-d', $created ) ); // phpcs:ignore -- local time. ?>"/>
1506 - </div>
1507 - </div>
1508 - <?php
1509 - } else {
1510 - ?>
1511 - <input type="text" value="<?php echo esc_html( $val ); ?>" class="regular-text" name="client_fields[default_field][<?php echo esc_attr( $field_name ); ?>]"/>
1512 - <?php
1513 - }
1514 - ?>
1515 - </div>
1516 - </div>
1517 - <?php if ( $client_id ) : ?>
1518 - <div class="ui four wide middle aligned hidden token column" style="display:none">
1519 - <?php if ( 'client.suspended' !== $field_name ) { ?>
1520 - [<?php echo esc_html( $field_name ); ?>]
1521 - <?php } ?>
1522 - </div>
1523 - <?php endif; ?>
1524 - </div>
1525 - <?php
1580 + $contact_email = sanitize_text_field( wp_unslash( $client_fields['contacts_field']['contact.email'][ $indx ] ) );
1581 + if ( empty( $contact_email ) ) {
1582 + continue;
1583 + }
1526 1584
1527 - if ( 'client.name' === $field_name ) {
1528 - ?>
1529 - <div class="ui grid field">
1530 - <label class="six wide column middle aligned"><?php esc_html_e( 'Client photo', 'mainwp' ); ?></label>
1531 - <div class="six wide column" data-tooltip="<?php esc_attr_e( 'Upload a client photo.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1532 - <div class="ui file fluid input">
1533 - <input type="file" name="mainwp_client_image_uploader[client_field]" accept="image/*" data-inverted="" data-tooltip="<?php esc_attr_e( "Image must be 500KB maximum. It will be cropped to 310px wide and 70px tall. For best results us an image of this site. Allowed formats: jpeg, gif and png. Note that animated gifs aren't going to be preserved.", 'mainwp' ); ?>" />
1534 - </div>
1535 - </div>
1536 - </div>
1537 - <?php if ( ! empty( $client_image ) ) : ?>
1538 - <div class="ui grid field">
1539 - <label class="six wide column middle aligned"></label>
1540 - <div class="six wide column">
1541 - <img class="ui tiny circular image" src="<?php echo esc_url( MainWP_Client_Handler::get_client_image_url( $client_image ) ); ?>" /><br/>
1542 - <div class="ui toggle checkbox" data-tooltip="<?php esc_attr_e( 'If enabled, delete client image.', 'mainwp' ); ?>" data-inverted="" data-position="bottom left">
1543 - <input type="checkbox" value="<?php echo intval( $client_id ); ?>" id="mainwp_client_delete_image[client_field]" name="mainwp_client_delete_image[client_field]" />
1544 - <label for="mainwp_client_delete_image[client_field][]"><?php esc_html_e( 'Delete photo', 'mainwp' ); ?></label>
1545 - </div>
1546 - </div>
1547 - </div>
1548 - <?php endif; ?>
1549 - <?php
1550 - }
1551 - }
1585 + $contact_id = isset( $client_fields['contacts_field']['contact_id'][ $indx ] ) ? intval( $client_fields['contacts_field']['contact_id'][ $indx ] ) : 0;
1552 1586
1553 - $client_contacts = array();
1554 - if ( $client_id ) {
1555 - $client_contacts = MainWP_DB_Client::instance()->get_wp_client_contact_by( 'client_id', $client_id );
1556 - ?>
1557 - <div class="ui grid field">
1558 - <label class="six wide column middle aligned"><?php echo esc_html_e( 'Client primary contact', 'mainwp' ); ?></label>
1559 - <div class="ui six wide column">
1560 - <div class="ui left labeled">
1561 - <div class="ui search selection dropdown" init-value="" id="client_fields[default_field][primary_contact_id]">
1562 - <input type="hidden" name="client_fields[default_field][primary_contact_id]" value="<?php echo $edit_client ? intval( $edit_client->primary_contact_id ) : 0; ?>">
1563 - <i class="dropdown icon"></i>
1564 - <div class="default text"><?php esc_attr_e( 'Select primary contact', 'mainwp' ); ?></div>
1565 - <div class="menu">
1566 - <div class="item" data-value="0"><?php esc_attr_e( 'Select primary contact', 'mainwp' ); ?></div>
1567 - <?php if ( $client_contacts ) : ?>
1568 - <?php foreach ( $client_contacts as $contact ) { ?>
1569 - <div class="item" data-value="<?php echo intval( $contact->contact_id ); ?>"><?php echo esc_html( stripslashes( $contact->contact_name ) ); ?></div>
1570 - <?php } ?>
1571 - <?php endif; ?>
1572 - </div>
1573 - </div>
1574 - </div>
1575 - </div>
1576 - <div class="ui four wide column">
1577 - </div>
1578 - </div>
1579 - <div class="ui section hidden divider"></div>
1580 - <?php
1581 - }
1587 + if ( empty( $contact_id ) ) {
1588 + continue;
1589 + }
1582 1590
1583 - $primary_contact_id = 0;
1591 + $editing_contact_nonce_id = sanitize_key( $client_fields['contacts_field']['nonce_contact_id'][ $indx ] );
1584 1592
1585 - if ( $edit_client && $edit_client->primary_contact_id ) {
1586 - $primary_contact_id = $edit_client->primary_contact_id;
1587 - }
1593 + if ( ! wp_verify_nonce( $editing_contact_nonce_id, 'editing-' . $client_id . '-contact-' . $contact_id ) ) {
1594 + continue;
1595 + }
1588 1596
1589 - if ( is_array( $custom_fields ) && count( $custom_fields ) > 0 ) {
1590 - $compatible_tokens = MainWP_Client_Handler::get_compatible_tokens();
1591 - foreach ( $custom_fields as $field ) {
1592 - if ( isset( $default_client_fields[ $field->field_name ] ) ) {
1593 - continue;
1594 - }
1595 - // do not show these tokens.
1596 - if ( isset( $compatible_tokens[ $field->field_name ] ) ) {
1597 - continue;
1598 - }
1599 - ?>
1600 - <div class="ui grid field mainwp-field" field-id="<?php echo intval( $field->field_id ); ?>">
1601 - <label class="six wide column middle aligned field-description"><?php echo esc_html( $field->field_desc ); ?></label>
1602 - <div class="ui six wide column">
1603 - <div class="ui left labeled input">
1604 - <input type="text" value="<?php echo ( property_exists( $field, 'field_value' ) && '' !== $field->field_value ) ? esc_html( $field->field_value ) : ''; ?>" class="regular-text" name="client_fields[custom_fields][<?php echo esc_html( $field->field_name ); ?>][<?php echo esc_html( $field->field_id ); ?>]"/>
1605 - </div>
1606 - </div>
1607 - <div class="ui four wide column">
1608 - <?php if ( $client_id > 0 && $field->client_id > 0 ) { // edit client and it is individual field, then show to edit/delete field buttons. ?>
1609 - <div class="ui left pointing dropdown icon mini basic green button">
1610 - <i class="ellipsis horizontal icon"></i>
1611 - <div class="menu">
1612 - <a class="item" id="mainwp-clients-edit-custom-field" href="#"><?php esc_html_e( 'Edit', 'mainwp' ); ?></a>
1613 - <a class="item" client-id="<?php echo intval( $client_id ); ?>" id="mainwp-clients-delete-individual-field" href="#"><?php esc_html_e( 'Delete', 'mainwp' ); ?></a>
1614 - </div>
1615 - </div>
1616 - <?php } ?>
1617 - <span class="field-name">[<?php echo esc_html( $field->field_name ); ?>]</span>
1618 - </div>
1619 - </div>
1620 - <?php
1621 - }
1622 - }
1597 + $contact_to_add['contact_email'] = $contact_email;
1623 1598
1624 - $temp = self::get_add_contact_temp( false, false );
1599 + $contact_to_add['contact_phone'] = sanitize_text_field( wp_unslash( $client_fields['contacts_field']['contact.phone'][ $indx ] ) );
1600 + $contact_to_add['contact_role'] = sanitize_text_field( wp_unslash( $client_fields['contacts_field']['contact.role'][ $indx ] ) );
1601 + $contact_to_add['facebook'] = sanitize_text_field( wp_unslash( $client_fields['contacts_field']['contact.facebook'][ $indx ] ) );
1602 + $contact_to_add['twitter'] = sanitize_text_field( wp_unslash( $client_fields['contacts_field']['contact.twitter'][ $indx ] ) );
1603 + $contact_to_add['instagram'] = sanitize_text_field( wp_unslash( $client_fields['contacts_field']['contact.instagram'][ $indx ] ) );
1604 + $contact_to_add['linkedin'] = sanitize_text_field( wp_unslash( $client_fields['contacts_field']['contact.linkedin'][ $indx ] ) );
1625 1605
1626 - if ( $client_id ) {
1627 - if ( $client_contacts ) {
1628 - foreach ( $client_contacts as $client_contact ) {
1629 - self::get_add_contact_temp( $client_contact, true );
1630 - }
1631 - }
1632 - }
1633 - ?>
1634 - <div class="ui grid field">
1635 - <label class="six wide column middle aligned"><?php esc_html_e( 'Create a new contact for this client', 'mainwp' ); ?></label>
1636 - <div class="ui six wide column">
1637 - <div class="ui left labeled input">
1638 - <a href="javascript:void(0);" class="ui green button mainwp-client-add-contact" add-contact-temp="<?php echo esc_attr( $temp ); ?>"><?php esc_html_e( 'Add Additional Contact', 'mainwp' ); ?></a>
1639 - </div>
1640 - </div>
1641 - </div>
1642 - <div class="ui section hidden divider after-add-contact-field"></div>
1643 - </div>
1644 - <input type="hidden" name="client_fields[client_id]" value="<?php echo intval( $client_id ); ?>">
1645 - <script type="text/javascript">
1646 - jQuery( document ).ready( function () {
1647 - // to fix issue not loaded calendar js library
1648 - if (jQuery('.ui.calendar').length > 0) {
1649 - if (mainwpParams.use_wp_datepicker == 1) {
1650 - jQuery('#mainwp-add-new-client-form .ui.calendar input[type=text]').datepicker({ dateFormat: "yy-mm-dd" });
1651 - } else {
1652 - jQuery('#mainwp-add-new-client-form .ui.calendar').calendar({
1653 - type: 'date',
1654 - monthFirst: false,
1655 - today: true,
1656 - touchReadonly: false,
1657 - formatter: {
1658 - date: function (date) {
1659 - if (!date) return '';
1660 - var day = date.getDate();
1661 - var month = date.getMonth() + 1;
1662 - var year = date.getFullYear();
1606 + $cust_icon = sanitize_text_field( wp_unslash( $client_fields['contacts_field']['selected_icon'][ $indx ] ) );
1607 + $cust_color = sanitize_hex_color( wp_unslash( $client_fields['contacts_field']['selected_color'][ $indx ] ) );
1663 1608
1664 - if (month < 10) {
1665 - month = '0' + month;
1666 - }
1667 - if (day < 10) {
1668 - day = '0' + day;
1669 - }
1670 - return year + '-' + month + '-' + day;
1671 - }
1672 - }
1673 - });
1674 - }
1675 - }
1676 - } );
1677 - </script>
1678 - <?php
1679 - }
1609 + $contact_to_add['contact_icon_info'] = 'selected:' . $cust_icon . ';color:' . $cust_color;
1680 1610
1681 - /**
1682 - * Method get_add_contact_temp().
1683 - *
1684 - * Get add contact template.
1685 - *
1686 - * @param mixed $edit_contact The contact data to edit.
1687 - * @param bool $echo_out Echo template or not.
1688 - */
1689 - public static function get_add_contact_temp( $edit_contact = false, $echo_out = false ) {
1611 + $contact_to_add['contact_client_id'] = $client_id;
1612 + $contact_to_add['contact_id'] = $contact_id;
1690 1613
1691 - $input_name = 'new_contacts_field';
1692 - $contact_id = 0;
1693 - $contact_image = '';
1694 - if ( $edit_contact ) {
1695 - $input_name = 'contacts_field';
1696 - $contact_id = $edit_contact->contact_id;
1697 - $contact_image = $edit_contact->contact_image;
1698 - }
1614 + $updated = MainWP_DB_Client::instance()->update_client_contact( $contact_to_add );
1699 1615
1700 - ob_start();
1701 - ?>
1702 - <h3 class="ui dividing header top-contact-fields"> <?php // must have class: top-contact-fields. ?>
1703 - <?php if ( $edit_contact ) : ?>
1704 - <?php echo esc_html__( 'Edit Contact', 'mainwp' ); ?>
1705 - <div class="sub header"><?php esc_html_e( 'Edit contact person information.', 'mainwp' ); ?></div>
1706 - <?php else : ?>
1707 - <?php esc_html_e( 'Add Contact', 'mainwp' ); ?>
1708 - <div class="sub header"><?php esc_html_e( 'Enter contact person information.', 'mainwp' ); ?></div>
1709 - <?php endif; ?>
1710 - </h3>
1711 - <?php
1712 - $contact_fields = MainWP_Client_Handler::get_default_contact_fields();
1713 - foreach ( $contact_fields as $field_name => $field ) {
1714 - $db_field = isset( $field['db_field'] ) ? $field['db_field'] : '';
1715 - $val = $edit_contact && '' !== $db_field && property_exists( $edit_contact, $db_field ) ? $edit_contact->{$db_field} : '';
1716 - $contact_id = $edit_contact && property_exists( $edit_contact, 'contact_id' ) ? $edit_contact->contact_id : '';
1717 - ?>
1718 - <div class="ui grid field">
1719 - <label class="six wide column middle aligned"><?php echo esc_html( $field['title'] ); ?></label>
1720 - <div class="ui six wide column">
1721 - <div class="ui left labeled input">
1722 - <input type="text" value="<?php echo esc_html( $val ); ?>" class="regular-text" name="client_fields[<?php echo esc_html( $input_name ); ?>][<?php echo esc_attr( $field_name ); ?>][]"/>
1723 - </div>
1724 - </div>
1725 - <?php if ( $edit_contact ) : ?>
1726 - <div class="ui four wide middle aligned hidden token column" style="display:none">
1727 - [<?php echo esc_html( $field_name ); ?>]
1728 - </div>
1729 - <?php endif; ?>
1730 - </div>
1731 - <?php
1616 + $is_first_contact = false;
1732 1617
1733 - if ( 'contact.role' === $field_name ) {
1734 - ?>
1735 - <div class="ui grid field">
1736 - <label class="six wide column middle aligned"><?php esc_html_e( 'Contact photo', 'mainwp' ); ?></label>
1737 - <div class="six wide column" data-tooltip="<?php esc_attr_e( 'Upload a client photo.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1738 - <div class="ui file fluid input">
1739 - <input type="file" name="mainwp_client_image_uploader[<?php echo esc_html( $input_name ); ?>][]" accept="image/*" data-inverted="" data-tooltip="<?php esc_attr_e( "Image must be 500KB maximum. It will be cropped to 310px wide and 70px tall. For best results us an image of this site. Allowed formats: jpeg, gif and png. Note that animated gifs aren't going to be preserved.", 'mainwp' ); ?>" />
1740 - </div>
1741 - </div>
1742 - </div>
1618 + if ( $updated ) {
1619 + $contact_data = MainWP_DB_Client::instance()->get_wp_client_contact_by( 'contact_id', $contact_id );
1620 + $contact_image = '';
1621 + if ( isset( $_POST['mainwp_add_edit_contact_uploaded_icon_hidden']['contacts_field'][ $indx ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
1622 + $contact_image = sanitize_text_field( wp_unslash( $_POST['mainwp_add_edit_contact_uploaded_icon_hidden']['contacts_field'][ $indx ] ) ); // phpcs:ignore WordPress.Security.NonceVerification
1623 + }
1624 + if ( $contact_data && $contact_data->contact_image !== $contact_image && $contact_id ) {
1625 + $old_file = $contact_data->contact_image;
1626 + if ( $old_file !== $contact_image && ! empty( $old_file ) ) {
1627 + MainWP_Utility::instance()->delete_uploaded_icon_file( 'client-images', $old_file );
1628 + }
1629 + $update = array(
1630 + 'contact_id' => $contact_id,
1631 + 'contact_image' => $contact_image,
1632 + );
1633 + MainWP_DB_Client::instance()->update_client_contact( $update );
1634 + }
1635 + }
1636 + }
1637 + }
1743 1638
1744 - <?php if ( ! empty( $contact_image ) ) : ?>
1745 - <div class="ui grid field">
1746 - <label class="six wide column middle aligned"></label>
1747 - <div class="six wide column">
1748 - <img class="ui tiny circular image" src="<?php echo esc_url( MainWP_Client_Handler::get_client_image_url( $contact_image ) ); ?>" /><br/>
1749 - <div class="ui toggle checkbox" data-tooltip="<?php esc_attr_e( 'If enabled, delete contact image.', 'mainwp' ); ?>" data-inverted="" data-position="bottom left">
1750 - <input type="checkbox" value="<?php echo intval( $contact_id ); ?>" id="mainwp_client_delete_image[contacts_field][<?php echo intval( $contact_id ); ?>]" name="mainwp_client_delete_image[contacts_field][<?php echo intval( $contact_id ); ?>]" />
1751 - <label for="mainwp_client_delete_image[contacts_field][<?php echo intval( $contact_id ); ?>]"><?php esc_html_e( 'Delete photo', 'mainwp' ); ?></label>
1752 - </div>
1639 + if ( $client_id && isset( $client_fields['new_contacts_field'] ) ) {
1753 1640
1754 - </div>
1755 - </div>
1756 - <?php
1757 - endif;
1758 - }
1759 - }
1641 + foreach ( $client_fields['new_contacts_field']['client.contact.name'] as $indx => $contact_name ) {
1642 + $contact_to_add = array();
1643 + if ( empty( $contact_name ) ) {
1644 + continue;
1645 + }
1646 + $contact_to_add['contact_name'] = $contact_name;
1760 1647
1761 - ?>
1762 - <div class="ui grid field remove-contact-field-parent">
1763 - <label class="six wide column middle aligned"><?php esc_html_e( 'Remove contact', 'mainwp' ); ?></label>
1764 - <div class="ui six wide column">
1765 - <div class="ui left labeled input">
1766 - <a href="javascript:void(0);" contact-id="<?php echo intval( $contact_id ); ?>" class="ui basic button mainwp-client-remove-contact"><?php esc_html_e( 'Remove contact', 'mainwp' ); ?></a>
1767 - </div>
1768 - <?php
1769 - if ( $edit_contact ) {
1770 - ?>
1771 - <input type="hidden" value="<?php echo intval( $edit_contact->contact_id ); ?>" name="client_fields[contacts_field][contact_id][]"/>
1772 - <?php
1773 - }
1774 - ?>
1775 - </div>
1776 - </div>
1777 - <div class="ui section hidden divider bottom-contact-fields"></div>
1778 - <?php
1779 - $html = ob_get_clean();
1648 + $contact_email = $client_fields['new_contacts_field']['contact.email'][ $indx ];
1649 + if ( empty( $contact_email ) ) {
1650 + continue;
1651 + }
1652 + $contact_to_add['contact_email'] = $contact_email;
1780 1653
1781 - if ( $echo_out ) {
1782 - echo $html; //phpcs:ignore -- validated content.
1783 - }
1654 + $contact_to_add['contact_phone'] = isset( $client_fields['new_contacts_field']['contact.phone'][ $indx ] ) ? $client_fields['new_contacts_field']['contact.phone'][ $indx ] : '';
1655 + $contact_to_add['contact_role'] = $client_fields['new_contacts_field']['contact.role'][ $indx ];
1656 + $contact_to_add['facebook'] = isset( $client_fields['new_contacts_field']['contact.facebook'][ $indx ] ) ? $client_fields['new_contacts_field']['contact.facebook'][ $indx ] : '';
1657 + $contact_to_add['twitter'] = isset( $client_fields['new_contacts_field']['contact.twitter'][ $indx ] ) ? $client_fields['new_contacts_field']['contact.twitter'][ $indx ] : '';
1658 + $contact_to_add['instagram'] = isset( $client_fields['new_contacts_field']['contact.instagram'][ $indx ] ) ? $client_fields['new_contacts_field']['contact.instagram'][ $indx ] : '';
1659 + $contact_to_add['linkedin'] = isset( $client_fields['new_contacts_field']['contact.linkedin'][ $indx ] ) ? $client_fields['new_contacts_field']['contact.linkedin'][ $indx ] : '';
1784 1660
1785 - return $html;
1786 - }
1661 + $cust_icon = isset( $client_fields['new_contacts_field']['selected_icon'][ $indx ] ) ? sanitize_text_field( wp_unslash( $client_fields['new_contacts_field']['selected_icon'][ $indx ] ) ) : '';
1662 + $cust_color = isset( $client_fields['new_contacts_field']['selected_color'][ $indx ] ) ? sanitize_hex_color( wp_unslash( $client_fields['new_contacts_field']['selected_color'][ $indx ] ) ) : '';
1787 1663
1788 - /**
1789 - * Method save_client_field().
1790 - *
1791 - * Save custom fields.
1792 - */
1793 - public static function save_client_field() {
1664 + $contact_to_add['contact_icon_info'] = 'selected:' . $cust_icon . ';color:' . $cust_color;
1794 1665
1795 - $return = array(
1796 - 'success' => false,
1797 - 'error' => '',
1798 - 'message' => '',
1799 - );
1666 + $contact_to_add['contact_client_id'] = $client_id;
1800 1667
1801 - // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1802 - $client_id = isset( $_POST['client_id'] ) ? intval( $_POST['client_id'] ) : 0; // 0 is global client's field.
1803 - $field_id = isset( $_POST['field_id'] ) ? intval( $_POST['field_id'] ) : 0;
1804 - $field_desc = isset( $_POST['field_desc'] ) ? sanitize_text_field( wp_unslash( $_POST['field_desc'] ) ) : '';
1805 - $field_name = isset( $_POST['field_name'] ) ? sanitize_text_field( wp_unslash( $_POST['field_name'] ) ) : '';
1806 - $field_name = trim( $field_name, '[]' );
1807 - // phpcs:enable
1668 + $inserted = MainWP_DB_Client::instance()->update_client_contact( $contact_to_add );
1808 1669
1809 - // update general or individual client field.
1810 - if ( $field_id ) {
1811 - $current = MainWP_DB_Client::instance()->get_client_fields_by( 'field_id', $field_id );
1812 - if ( $current && $current->field_name === $field_name && $current->field_desc === $field_desc ) {
1813 - $return['success'] = true;
1814 - $return['message'] = esc_html__( 'Field has been saved without changes.', 'mainwp' );
1815 - } else {
1816 - $current = MainWP_DB_Client::instance()->get_client_fields_by( 'field_name', $field_name, $client_id ); // check if other field with the same name existed.
1817 - if ( $current && (int) $current->field_id !== $field_id ) {
1818 - $return['error'] = esc_html__( 'Field already exists, try different field name.', 'mainwp' );
1819 - } else {
1820 - // update general or individual field name.
1821 - $field = MainWP_DB_Client::instance()->update_client_field(
1822 - $field_id,
1823 - array(
1824 - 'field_name' => $field_name,
1825 - 'field_desc' => $field_desc,
1826 - 'client_id' => $client_id,
1827 - )
1828 - );
1829 - if ( $field ) {
1830 - $return['success'] = true;
1831 - }
1832 - }
1833 - }
1834 - } else { // add new.
1835 - $current = MainWP_DB_Client::instance()->get_client_fields_by( 'field_name', $field_name, $client_id );
1836 - if ( $current ) { // checking general or individual field name.
1837 - $return['error'] = esc_html__( 'Field already exists, try different field name.', 'mainwp' );
1838 - } else {
1839 - // insert general or individual field name.
1840 - $field = MainWP_DB_Client::instance()->add_client_field(
1841 - array(
1842 - 'field_name' => $field_name,
1843 - 'field_desc' => $field_desc,
1844 - 'client_id' => $client_id,
1845 - )
1846 - );
1670 + if ( $inserted ) {
1847 1671
1848 - if ( $field ) {
1849 - $return['success'] = true;
1850 - } else {
1851 - $return['error'] = esc_html__( 'Undefined error occurred. Please try again.', 'mainwp' ); }
1852 - }
1853 - }
1854 - echo wp_json_encode( $return );
1855 - exit;
1856 - }
1672 + $contact_id = $inserted->contact_id;
1673 + $contact_image = '';
1674 + if ( isset( $_POST['mainwp_add_edit_contact_uploaded_icon_hidden']['new_contacts_field'][ $indx ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
1675 + $contact_image = sanitize_text_field( wp_unslash( $_POST['mainwp_add_edit_contact_uploaded_icon_hidden']['new_contacts_field'][ $indx ] ) ); // phpcs:ignore WordPress.Security.NonceVerification
1676 + }
1857 1677
1858 - /**
1859 - * Method save_note()
1860 - *
1861 - * Save Client Note.
1862 - */
1863 - public static function save_note() {
1864 - if ( isset( $_POST['clientid'] ) && ! empty( $_POST['clientid'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1865 - $note = isset( $_POST['note'] ) ? wp_unslash( $_POST['note'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1866 - $esc_note = MainWP_Utility::esc_content( $note );
1867 - $update = array(
1868 - 'client_id' => intval( $_POST['clientid'] ), // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1869 - 'note' => $esc_note,
1870 - );
1871 - MainWP_DB_Client::instance()->update_client( $update );
1872 - die( wp_json_encode( array( 'result' => 'SUCCESS' ) ) );
1873 - }
1874 - die( wp_json_encode( array( 'undefined_error' => true ) ) );
1875 - }
1678 + if ( '' !== $contact_image && $contact_id ) {
1679 + $update = array(
1680 + 'contact_id' => $contact_id,
1681 + 'contact_image' => $contact_image,
1682 + );
1683 + MainWP_DB_Client::instance()->update_client_contact( $update );
1684 + }
1876 1685
1877 - /**
1878 - * Hooks the section help content to the Help Sidebar element.
1879 - */
1880 - public static function mainwp_help_content() {
1881 - if ( isset( $_GET['page'] ) && ( 'ManageClients' === $_GET['page'] || 'ClientAddNew' === $_GET['page'] || 'UpdateAdminPasswords' === $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1882 - ?>
1883 - <p><?php esc_html_e( 'If you need help with managing clients, please review following help documents', 'mainwp' ); ?></p>
1884 - <div class="ui relaxed bulleted list">
1885 - <div class="item"><a href="https://kb.mainwp.com/docs/manage-clients/" target="_blank">Manage Clients</a> <i class="external alternate icon"></i></div>
1886 - <?php
1887 - /**
1888 - * Action: mainwp_clients_help_item
1889 - *
1890 - * Fires at the bottom of the help articles list in the Help sidebar on the Clients page.
1891 - *
1892 - * Suggested HTML markup:
1893 - *
1894 - * <div class="item"><a href="Your custom URL">Your custom text</a></div>
1895 - *
1896 - * @since 4.1
1897 - */
1898 - do_action( 'mainwp_clients_help_item' );
1899 - ?>
1900 - </div>
1901 - <?php
1902 - }
1903 - }
1686 + if ( $is_first_contact && empty( $auto_assign_contact_id ) ) {
1687 + $auto_assign_contact_id = $contact_id;
1688 + }
1689 + }
1690 + }
1691 + }
1692 +
1693 + if ( $client_id && isset( $client_fields['delele_contacts'] ) && is_array( $client_fields['delele_contacts'] ) ) {
1694 + foreach ( $client_fields['delele_contacts'] as $delete_id ) {
1695 + MainWP_DB_Client::instance()->delete_client_contact( $client_id, $delete_id );
1696 + $is_first_contact = false;
1697 + }
1698 + }
1699 +
1700 + if ( $is_first_contact && $auto_assign_contact_id && $client_id ) {
1701 + // auto assign.
1702 + $update = array(
1703 + 'client_id' => $client_id,
1704 + 'primary_contact_id' => $auto_assign_contact_id,
1705 + );
1706 + MainWP_DB_Client::instance()->update_client( $update );
1707 + }
1708 +
1709 + // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1710 + if ( isset( $_POST['is_first_client'] ) && ! empty( $_POST['is_first_client'] ) ) {
1711 + delete_transient( 'mainwp_transient_just_connected_site_id' );
1712 + }
1713 + //phpcs:enable
1714 +
1715 + $snapshot_info = MainWP_DB_Client::instance()->get_clients_snapshot_info();
1716 +
1717 + /**
1718 + * Action: mainwp_insert_update_client
1719 + *
1720 + * @since 6.0
1721 + *
1722 + * @param int $client_id Client ID.
1723 + * @param bool $add_new True if adding a new client, false if updating an existing one.
1724 + * @param array $snapshot_info Snapshot information.
1725 + */
1726 + do_action( 'mainwp_insert_update_client', $client_id, $add_new, $snapshot_info );
1727 +
1728 + echo wp_json_encode(
1729 + array(
1730 + 'success' => 'yes',
1731 + 'client_id' => $client_id,
1732 + )
1733 + );
1734 + }
1735 +
1736 + /**
1737 + * Method invalidate_warm_cache()
1738 + */
1739 + public static function invalidate_warm_cache() {
1740 + MainWP_Cache_Warm_Helper::invalidate_manage_pages( array( 'ManageClients', 'ClientAddField' ) );
1741 + }
1742 +
1743 + /**
1744 + * Method render_add_client_modal().
1745 + *
1746 + * Renders add client Modal window.
1747 + */
1748 + public static function render_add_client_modal() {
1749 + ?>
1750 + <div id="mainwp-creating-new-client-modal" class="ui modal">
1751 + <i class="close icon"></i>
1752 + <div class="header"><?php esc_html_e( 'New client', 'mainwp' ); ?></div>
1753 + <div class="ui message" id="mainwp-message-zone-client" style="display:none;"></div>
1754 + <div class="scrolling content mainwp-modal-content">
1755 + <form action="" method="post" enctype="multipart/form-data" name="createclient_form" id="createclient_form" class="add:clients: validate">
1756 + <?php
1757 + static::render_add_client_content();
1758 + ?>
1759 + </form>
1760 + </div>
1761 + <div class="actions">
1762 + <div class="ui button green" current-page="modal-add" id="bulk_add_createclient"><?php esc_html_e( 'Add Client', 'mainwp' ); ?></div>
1763 + </div>
1764 + </div>
1765 +
1766 + <script type="text/javascript">
1767 + jQuery(document).on('click', '.edit-site-new-client-button', function () {
1768 + jQuery('#mainwp-creating-new-client-modal').modal({
1769 + allowMultiple: true,
1770 + }).modal('show');
1771 + return false;
1772 + });
1773 + </script>
1774 + <?php
1775 + }
1776 +
1777 + /**
1778 + * Method render_add_client_content().
1779 + *
1780 + * Renders add client content window.
1781 + *
1782 + * @param mixed $edit_client The client data.
1783 + */
1784 + public static function render_add_client_content( $edit_client = false ) { // phpcs:ignore -- NOSONAR -Current complexity is required to achieve desired results. Pull request solutions appreciated.
1785 + $client_id = $edit_client ? $edit_client->client_id : 0;
1786 + $default_client_fields = MainWP_Client_Handler::get_default_client_fields();
1787 + $custom_fields = MainWP_DB_Client::instance()->get_client_fields( true, $client_id, true );
1788 + $client_image = $edit_client ? $edit_client->image : '';
1789 +
1790 + $icon_info_array = array();
1791 + if ( $edit_client ) {
1792 + $arr_fields = array(
1793 + 'image',
1794 + 'selected_icon_info',
1795 + );
1796 + $icon_info_array = MainWP_Utility::map_fields( $edit_client, $arr_fields, false );
1797 + }
1798 +
1799 + $uploaded_icon_src = '';
1800 + if ( ! empty( $client_image ) ) {
1801 + $uploaded_icon_src = MainWP_Client_Handler::get_client_contact_image( $icon_info_array, 'client', 'uploaded_icon' );
1802 + }
1803 +
1804 + $field_groups = array(
1805 + 'client_info' => array( 'client.name', 'client.email', 'client.suspended' ),
1806 + 'contact_details' => array( 'client.phone', 'client.contact.address.1', 'client.contact.address.2', 'client.city', 'client.state', 'client.zip', 'client.country' ),
1807 + 'social_links' => array( 'client.facebook', 'client.twitter', 'client.instagram', 'client.linkedin' ),
1808 + 'notes_meta' => array( 'client.note', 'client.created' ),
1809 + );
1810 +
1811 + ?>
1812 + <div class="ui form">
1813 + <input type="hidden" name="nonce_client_id" value="<?php echo esc_attr( wp_create_nonce( 'editing-client-' . $client_id ) ); ?>">
1814 +
1815 + <div class="ui basic accordion mainwp-blank-accordion mainwp-sidebar-accordion" id="mainwp-client-info-accordion">
1816 + <h2 class="ui dividing header active title">
1817 + <i class="right dropdown icon"></i>
1818 + <?php esc_html_e( 'Client Info', 'mainwp' ); ?>
1819 + <div class="sub header">
1820 + <?php esc_html_e( 'Set the basics used to identify this client in your dashboard, name and email are primary, logo is optional, and status controls whether they\'re active.', 'mainwp' ); ?>
1821 + </div>
1822 + </h2>
1823 + <div class="content active">
1824 + <?php
1825 + foreach ( $field_groups['client_info'] as $field_name ) {
1826 + if ( ! isset( $default_client_fields[ $field_name ] ) ) {
1827 + continue;
1828 + }
1829 + $field = $default_client_fields[ $field_name ];
1830 + $db_field = isset( $field['db_field'] ) ? $field['db_field'] : '';
1831 + $val = $edit_client && '' !== $db_field && property_exists( $edit_client, $db_field ) ? $edit_client->{$db_field} : '';
1832 + $tip = isset( $field['tooltip'] ) ? $field['tooltip'] : '';
1833 + ?>
1834 + <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-edit-client">
1835 + <label class="six wide column middle aligned" for="client_fields[default_field][<?php echo esc_attr( $field_name ); ?>]" <?php echo ! empty( $tip ) ? 'data-tooltip="' . esc_attr( $tip ) . '" data-inverted="" data-position="top left"' : ''; // phpcs:ignore WordPress.Security.EscapeOutput ?>>
1836 + <?php
1837 + $indi_val = $val && $edit_client ? 1 : 0;
1838 + MainWP_Settings_Indicator::render_not_default_indicator( 'none_preset_value', $indi_val );
1839 + echo esc_html( $field['title'] );
1840 + if ( ! empty( $field['required'] ) ) {
1841 + echo ' <span class="ui small red text">' . esc_html__( '(Required)', 'mainwp' ) . '</span>';
1842 + }
1843 + ?>
1844 + </label>
1845 + <div class="ui six wide column">
1846 + <div class="ui left labeled input">
1847 + <?php
1848 + if ( 'client.suspended' === $field_name ) {
1849 + $el_id_fln_2 = $field_name;
1850 + ?>
1851 + <select class="ui dropdown settings-field-value-change-handler" name="client_fields[default_field][<?php echo esc_attr( $field_name ); ?>]" id="client_fields[default_field][<?php echo esc_attr( $el_id_fln_2 ); ?>]" >
1852 + <option value="0" <?php echo '0' === $val ? 'selected' : ''; ?>><?php esc_html_e( 'Active', 'mainwp' ); ?></option>
1853 + <option value="1" <?php echo '1' === $val ? 'selected' : ''; ?>><?php esc_html_e( 'Suspended', 'mainwp' ); ?></option>
1854 + <option value="2" <?php echo '2' === $val ? 'selected' : ''; ?>><?php esc_html_e( 'Lead', 'mainwp' ); ?></option>
1855 + <option value="3" <?php echo '3' === $val ? 'selected' : ''; ?>><?php esc_html_e( 'Lost', 'mainwp' ); ?></option>
1856 + </select>
1857 + <?php
1858 + } else {
1859 + ?>
1860 + <input type="text" id="client_fields[default_field][<?php echo esc_attr( $field_name ); ?>]" class="regular-text settings-field-value-change-handler" value="<?php echo esc_html( $val ); ?>" name="client_fields[default_field][<?php echo esc_attr( $field_name ); ?>]"/>
1861 + <?php
1862 + }
1863 + ?>
1864 + </div>
1865 + </div>
1866 + <?php if ( $client_id ) : ?>
1867 + <div class="ui four wide middle aligned hidden token column" style="display:none">
1868 + <?php if ( 'client.suspended' !== $field_name ) { ?>
1869 + [<?php echo esc_html( $field_name ); ?>]
1870 + <?php } ?>
1871 + </div>
1872 + <?php endif; ?>
1873 + </div>
1874 +
1875 + <?php if ( 'client.email' === $field_name ) { ?>
1876 + <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-edit-client">
1877 + <label class="six wide column middle aligned">
1878 + <?php
1879 + $indi_val = $client_image && $edit_client ? 1 : 0;
1880 + MainWP_Settings_Indicator::render_not_default_indicator( 'none_preset_value', $indi_val );
1881 + $delnonce = MainWP_System_Utility::get_custom_nonce( 'client', esc_attr( $client_image ) );
1882 + ?>
1883 + <?php esc_html_e( 'Client logo (photo)', 'mainwp' ); ?>
1884 + </label>
1885 + <input type="hidden" name="mainwp_add_edit_client_uploaded_icon_hidden" class="settings-field-value-change-handler" id="mainwp_add_edit_client_uploaded_icon_hidden" value="<?php echo esc_attr( $client_image ); ?>">
1886 + <div class="ui six wide column">
1887 + <span class="ui circular bordered image">
1888 + <?php if ( ! empty( $client_image ) ) { ?>
1889 + <?php echo MainWP_Client_Handler::get_client_contact_image( $icon_info_array, 'client', 'display_edit' ); //phpcs:ignore --ok. ?>
1890 + <?php } else { ?>
1891 + <div style="display:inline-block;" id="mainwp_add_edit_client_upload_custom_icon"></div> <?php // used for icon holder. ?>
1892 + <?php } ?>
1893 + </span>
1894 + <div class="ui basic button mainwp-add-edit-client-icon-customable"
1895 + iconItemId="<?php echo intval( $client_id ); ?>"
1896 + iconFileSlug="<?php echo esc_attr( $client_image ); ?>"
1897 + del-icon-nonce="<?php echo esc_attr( $delnonce ); ?>"
1898 + icon-src="<?php echo esc_attr( $uploaded_icon_src ); ?>">
1899 + <i class="image icon"></i> <?php echo ! empty( $client_image ) ? esc_html__( 'Change Image', 'mainwp' ) : esc_html__( 'Upload Image', 'mainwp' ); ?>
1900 + </div>
1901 + </div>
1902 + </div>
1903 +
1904 + <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-edit-client" default-indi-indi-value="wordpress">
1905 + <label class="six wide column middle aligned">
1906 + <?php
1907 + $default_icons = MainWP_UI::get_default_icons();
1908 + $selected_icon = 'wordpress'; //phpcs:ignore -- WP icon.
1909 + $selected_color = '#34424D';
1910 +
1911 + $icon_info = $edit_client ? $edit_client->selected_icon_info : '';
1912 + if ( ! empty( $icon_info ) ) {
1913 + $selected_icon = static::get_cust_client_icon( $icon_info, 'selected' );
1914 + $selected_color = static::get_cust_client_icon( $icon_info, 'color' );
1915 + }
1916 +
1917 + $indi_val = 'wordpress' !== $selected_icon ? 1 : 0; //phpcs:ignore -- WP icon.
1918 + MainWP_Settings_Indicator::render_not_default_indicator( 'none_preset_value', $indi_val );
1919 + esc_html_e( 'Select icon', 'mainwp' );
1920 + ?>
1921 + </label>
1922 + <input type="hidden" name="client_fields[default_field][selected_icon]" class="settings-field-value-change-handler" id="client_fields[default_field][selected_icon]" value="<?php echo esc_attr( $selected_icon ); ?>">
1923 + <div class="six wide column" data-tooltip="<?php esc_attr_e( 'Select an icon if not using original client icon.', 'mainwp' ); ?>" data-inverted="" data-position="left center">
1924 + <div class="ui left action input mainwp-dropdown-color-picker-field">
1925 + <div class="ui five column selection search dropdown not-auto-init" id="mainwp_edit_clients_icon_select">
1926 + <div class="text">
1927 + <span style="color:<?php echo esc_attr( $selected_color ); ?>" ><?php echo ! empty( $selected_icon ) ? '<i class="' . esc_attr( $selected_icon ) . ' icon"></i>' : ''; ?></span>
1928 + </div>
1929 + <i class="dropdown icon"></i>
1930 + <div class="menu">
1931 + <?php foreach ( $default_icons as $icon ) : ?>
1932 + <?php echo '<div class="item" style="color:' . esc_attr( $selected_color ) . '" data-value="' . esc_attr( $icon ) . '"><i class="' . esc_attr( $icon ) . ' icon"></i></div>'; ?>
1933 + <?php endforeach; ?>
1934 + </div>
1935 + </div>
1936 + <input type="color" data-tooltip="Color will update on save" data-position="top center" data-inverted="" name="client_fields[default_field][selected_color]" class="mainwp-color-picker-input" id="client_fields[default_field][selected_color]" value="<?php echo esc_attr( $selected_color ); ?>" />
1937 + </div>
1938 + </div>
1939 + <div class="one wide column"></div>
1940 + </div>
1941 + <?php
1942 + }
1943 + }
1944 + ?>
1945 + </div>
1946 + </div>
1947 +
1948 + <div class="ui basic accordion mainwp-blank-accordion mainwp-sidebar-accordion" id="mainwp-contact-details-accordion">
1949 + <h2 class="ui dividing header active title">
1950 + <i class="right dropdown icon"></i>
1951 + <?php esc_html_e( 'Contact Details', 'mainwp' ); ?>
1952 + <div class="sub header">
1953 + <?php esc_html_e( 'Add the best ways to reach the client and where they\'re located. Include phone and full address details to keep records consistent.', 'mainwp' ); ?>
1954 + </div>
1955 + </h2>
1956 + <div class="content active">
1957 + <?php
1958 + foreach ( $field_groups['contact_details'] as $field_name ) {
1959 + if ( ! isset( $default_client_fields[ $field_name ] ) ) {
1960 + continue;
1961 + }
1962 + $field = $default_client_fields[ $field_name ];
1963 + $db_field = isset( $field['db_field'] ) ? $field['db_field'] : '';
1964 + $val = $edit_client && '' !== $db_field && property_exists( $edit_client, $db_field ) ? $edit_client->{$db_field} : '';
1965 + $tip = isset( $field['tooltip'] ) ? $field['tooltip'] : '';
1966 + ?>
1967 + <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-edit-client">
1968 + <label class="six wide column middle aligned" for="client_fields[default_field][<?php echo esc_attr( $field_name ); ?>]" <?php echo ! empty( $tip ) ? 'data-tooltip="' . esc_attr( $tip ) . '" data-inverted="" data-position="top left"' : ''; // phpcs:ignore WordPress.Security.EscapeOutput ?>>
1969 + <?php
1970 + $indi_val = $val && $edit_client ? 1 : 0;
1971 + MainWP_Settings_Indicator::render_not_default_indicator( 'none_preset_value', $indi_val );
1972 + echo esc_html( $field['title'] );
1973 + if ( ! empty( $field['required'] ) ) {
1974 + echo ' <span class="ui small red text">' . esc_html__( '(Required)', 'mainwp' ) . '</span>';
1975 + }
1976 + ?>
1977 + </label>
1978 + <div class="ui six wide column">
1979 + <div class="ui left labeled input">
1980 + <input type="text" id="client_fields[default_field][<?php echo esc_attr( $field_name ); ?>]" class="regular-text settings-field-value-change-handler" value="<?php echo esc_html( $val ); ?>" name="client_fields[default_field][<?php echo esc_attr( $field_name ); ?>]"/>
1981 + </div>
1982 + </div>
1983 + <?php if ( $client_id ) : ?>
1984 + <div class="ui four wide middle aligned hidden token column" style="display:none">
1985 + [<?php echo esc_html( $field_name ); ?>]
1986 + </div>
1987 + <?php endif; ?>
1988 + </div>
1989 + <?php
1990 + }
1991 + ?>
1992 + </div>
1993 + </div>
1994 +
1995 + <div class="ui basic accordion mainwp-blank-accordion mainwp-sidebar-accordion" id="mainwp-social-links-accordion">
1996 + <h2 class="ui dividing header active title">
1997 + <i class="right dropdown icon"></i>
1998 + <?php esc_html_e( 'Social Links', 'mainwp' ); ?>
1999 + <div class="sub header">
2000 + <?php esc_html_e( 'Link the client\'s public profiles for quick access. Paste full URLs (including https://) and leave anything you don\'t use blank.', 'mainwp' ); ?>
2001 + </div>
2002 + </h2>
2003 + <div class="content active">
2004 + <?php
2005 + foreach ( $field_groups['social_links'] as $field_name ) {
2006 + if ( ! isset( $default_client_fields[ $field_name ] ) ) {
2007 + continue;
2008 + }
2009 + $field = $default_client_fields[ $field_name ];
2010 + $db_field = isset( $field['db_field'] ) ? $field['db_field'] : '';
2011 + $val = $edit_client && '' !== $db_field && property_exists( $edit_client, $db_field ) ? $edit_client->{$db_field} : '';
2012 + $tip = isset( $field['tooltip'] ) ? $field['tooltip'] : '';
2013 + ?>
2014 + <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-edit-client">
2015 + <label class="six wide column middle aligned" for="client_fields[default_field][<?php echo esc_attr( $field_name ); ?>]" <?php echo ! empty( $tip ) ? 'data-tooltip="' . esc_attr( $tip ) . '" data-inverted="" data-position="top left"' : ''; // phpcs:ignore WordPress.Security.EscapeOutput ?>>
2016 + <?php
2017 + $indi_val = $val && $edit_client ? 1 : 0;
2018 + MainWP_Settings_Indicator::render_not_default_indicator( 'none_preset_value', $indi_val );
2019 + echo esc_html( $field['title'] );
2020 + if ( ! empty( $field['required'] ) ) {
2021 + echo ' <span class="ui small red text">' . esc_html__( '(Required)', 'mainwp' ) . '</span>';
2022 + }
2023 + ?>
2024 + </label>
2025 + <div class="ui six wide column">
2026 + <div class="ui left labeled input">
2027 + <input type="text" id="client_fields[default_field][<?php echo esc_attr( $field_name ); ?>]" class="regular-text settings-field-value-change-handler" value="<?php echo esc_html( $val ); ?>" name="client_fields[default_field][<?php echo esc_attr( $field_name ); ?>]"/>
2028 + </div>
2029 + </div>
2030 + <?php if ( $client_id ) : ?>
2031 + <div class="ui four wide middle aligned hidden token column" style="display:none">
2032 + [<?php echo esc_html( $field_name ); ?>]
2033 + </div>
2034 + <?php endif; ?>
2035 + </div>
2036 + <?php
2037 + }
2038 + ?>
2039 + </div>
2040 + </div>
2041 +
2042 + <div class="ui basic accordion mainwp-blank-accordion mainwp-sidebar-accordion" id="mainwp-notes-meta-accordion">
2043 + <h2 class="ui dividing header active title">
2044 + <i class="right dropdown icon"></i>
2045 + <?php esc_html_e( 'Notes & Meta', 'mainwp' ); ?>
2046 + <div class="sub header">
2047 + <?php esc_html_e( 'Store internal context for your team, notes, when the client was added, and any extra contact details that don\'t fit elsewhere.', 'mainwp' ); ?>
2048 + </div>
2049 + </h2>
2050 + <div class="content active">
2051 + <?php
2052 + foreach ( $field_groups['notes_meta'] as $field_name ) {
2053 + if ( ! isset( $default_client_fields[ $field_name ] ) ) {
2054 + continue;
2055 + }
2056 + $field = $default_client_fields[ $field_name ];
2057 + $db_field = isset( $field['db_field'] ) ? $field['db_field'] : '';
2058 + $val = $edit_client && '' !== $db_field && property_exists( $edit_client, $db_field ) ? $edit_client->{$db_field} : '';
2059 + $tip = isset( $field['tooltip'] ) ? $field['tooltip'] : '';
2060 + ?>
2061 + <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-edit-client">
2062 + <label class="six wide column middle aligned" for="client_fields[default_field][<?php echo esc_attr( $field_name ); ?>]" <?php echo ! empty( $tip ) ? 'data-tooltip="' . esc_attr( $tip ) . '" data-inverted="" data-position="top left"' : ''; // phpcs:ignore WordPress.Security.EscapeOutput ?>>
2063 + <?php
2064 + $indi_val = $val && $edit_client ? 1 : 0;
2065 + MainWP_Settings_Indicator::render_not_default_indicator( 'none_preset_value', $indi_val );
2066 + echo esc_html( $field['title'] );
2067 + if ( ! empty( $field['required'] ) ) {
2068 + echo ' <span class="ui small red text">' . esc_html__( '(Required)', 'mainwp' ) . '</span>';
2069 + }
2070 + ?>
2071 + </label>
2072 + <div class="ui six wide column">
2073 + <div class="ui left labeled input">
2074 + <?php
2075 + if ( 'client.note' === $field_name ) {
2076 + $el_id_fln_1 = $field_name;
2077 + ?>
2078 + <div class="editor">
2079 + <textarea class="code settings-field-value-change-handler" cols="80" rows="10" id="client_fields[default_field][<?php echo esc_attr( $el_id_fln_1 ); ?>]" name="client_fields[default_field][<?php echo esc_attr( $field_name ); ?>]"><?php echo esc_html( $val ); ?></textarea>
2080 + </div>
2081 + <?php
2082 + } elseif ( $client_id && 'client.created' === $field_name ) {
2083 + $created = empty( $val ) ? time() : $val;
2084 + ?>
2085 + <div class="ui calendar mainwp_datepicker" >
2086 + <div class="ui input left icon">
2087 + <i class="calendar icon"></i>
2088 + <input type="text" autocomplete="off" name="client_fields[default_field][<?php echo esc_attr( $field_name ); ?>]" placeholder="<?php esc_attr_e( 'Added date', 'mainwp' ); ?>" id="client_fields[default_field][<?php echo esc_attr( $field_name ); ?>]" value="<?php echo esc_attr( date( 'Y-m-d', $created ) ); // phpcs:ignore -- local time. ?>"/>
2089 + </div>
2090 + </div>
2091 + <?php
2092 + } else {
2093 + ?>
2094 + <input type="text" id="client_fields[default_field][<?php echo esc_attr( $field_name ); ?>]" class="regular-text settings-field-value-change-handler" value="<?php echo esc_html( $val ); ?>" name="client_fields[default_field][<?php echo esc_attr( $field_name ); ?>]"/>
2095 + <?php
2096 + }
2097 + ?>
2098 + </div>
2099 + </div>
2100 + <?php if ( $client_id ) : ?>
2101 + <div class="ui four wide middle aligned hidden token column" style="display:none">
2102 + [<?php echo esc_html( $field_name ); ?>]
2103 + </div>
2104 + <?php endif; ?>
2105 + </div>
2106 + <?php
2107 + }
2108 +
2109 + $client_contacts = array();
2110 + if ( $client_id ) {
2111 + $client_contacts = MainWP_DB_Client::instance()->get_wp_client_contact_by( 'client_id', $client_id );
2112 + ?>
2113 + <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-edit-client">
2114 + <label class="six wide column middle aligned">
2115 + <?php
2116 + $indi_val = $edit_client && $client_contacts ? 1 : 0;
2117 + MainWP_Settings_Indicator::render_not_default_indicator( 'none_preset_value', $indi_val );
2118 + esc_html_e( 'Client primary contact', 'mainwp' );
2119 + ?>
2120 + </label>
2121 + <div class="ui six wide column">
2122 + <div class="ui left labeled">
2123 + <div class="ui search selection dropdown" init-value="" id="client_fields[default_field][primary_contact_id]">
2124 + <input type="hidden" name="client_fields[default_field][primary_contact_id]" value="<?php echo $edit_client ? intval( $edit_client->primary_contact_id ) : 0; ?>">
2125 + <i class="dropdown icon"></i>
2126 + <div class="default text"><?php esc_attr_e( 'Select primary contact', 'mainwp' ); ?></div>
2127 + <div class="menu">
2128 + <div class="item" data-value="0"><?php esc_attr_e( 'Select primary contact', 'mainwp' ); ?></div>
2129 + <?php if ( $client_contacts ) : ?>
2130 + <?php foreach ( $client_contacts as $contact ) { ?>
2131 + <div class="item" data-value="<?php echo intval( $contact->contact_id ); ?>"><?php echo esc_html( stripslashes( $contact->contact_name ) ); ?></div>
2132 + <?php } ?>
2133 + <?php endif; ?>
2134 + </div>
2135 + </div>
2136 + </div>
2137 + </div>
2138 + <div class="ui four wide column">
2139 + </div>
2140 + </div>
2141 + <div class="ui section hidden divider"></div>
2142 + <?php
2143 + }
2144 +
2145 + if ( is_array( $custom_fields ) && count( $custom_fields ) > 0 ) {
2146 + $compatible_tokens = MainWP_Client_Handler::get_compatible_tokens();
2147 + foreach ( $custom_fields as $field ) {
2148 + if ( isset( $default_client_fields[ $field->field_name ] ) ) {
2149 + continue;
2150 + }
2151 + // do not show these tokens.
2152 + if ( isset( $compatible_tokens[ $field->field_name ] ) ) {
2153 + continue;
2154 + }
2155 + $field_val = ( property_exists( $field, 'field_value' ) && '' !== $field->field_value ) ? esc_html( $field->field_value ) : '';
2156 + ?>
2157 + <div class="ui grid field mainwp-field settings-field-indicator-wrapper settings-field-indicator-edit-client" field-id="<?php echo intval( $field->field_id ); ?>">
2158 + <label class="six wide column middle aligned field-description">
2159 + <?php
2160 + $indi_val = $edit_client && $field_val ? 1 : 0;
2161 + MainWP_Settings_Indicator::render_not_default_indicator( 'none_preset_value', $indi_val );
2162 + echo esc_html( $field->field_desc );
2163 + ?>
2164 + </label>
2165 + <div class="ui six wide column">
2166 + <div class="ui left labeled input">
2167 + <input type="text" value="<?php echo esc_attr( $field_val ); ?>" class="regular-text" name="client_fields[custom_fields][<?php echo esc_html( $field->field_name ); ?>][<?php echo esc_html( $field->field_id ); ?>]"/>
2168 + </div>
2169 + </div>
2170 + <div class="ui four wide column">
2171 + <?php if ( $client_id > 0 && $field->client_id > 0 ) { // edit client and it is individual field, then show to edit/delete field buttons. ?>
2172 + <div class="ui right pointing dropdown">
2173 + <i class="ellipsis vertical icon"></i>
2174 + <div class="menu">
2175 + <a class="item" id="mainwp-clients-edit-custom-field" href="#"><?php esc_html_e( 'Edit', 'mainwp' ); ?></a>
2176 + <a class="item" client-id="<?php echo intval( $client_id ); ?>" id="mainwp-clients-delete-individual-field" href="#"><?php esc_html_e( 'Delete', 'mainwp' ); ?></a>
2177 + </div>
2178 + </div>
2179 + <?php } ?>
2180 + <span class="field-name">[<?php echo esc_html( $field->field_name ); ?>]</span>
2181 + </div>
2182 + </div>
2183 + <?php
2184 + }
2185 + }
2186 +
2187 + $temp = static::get_add_contact_temp( false, false );
2188 +
2189 + if ( $client_id && $client_contacts ) {
2190 + foreach ( $client_contacts as $client_contact ) {
2191 + static::get_add_contact_temp( $client_contact, true, $client_id );
2192 + }
2193 + }
2194 + ?>
2195 + <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-edit-client">
2196 + <label class="six wide column middle aligned"><?php esc_html_e( 'Create a new contact for this client', 'mainwp' ); ?></label>
2197 + <div class="ui six wide column">
2198 + <div class="ui left labeled input">
2199 + <a href="javascript:void(0);" class="ui basic button mainwp-client-add-contact" add-contact-temp="<?php echo esc_attr( $temp ); ?>"><i class="user icon"></i><?php esc_html_e( 'Add Contact', 'mainwp' ); ?></a>
2200 + </div>
2201 + </div>
2202 + </div>
2203 + <div class="ui section hidden divider after-add-contact-field"></div>
2204 + </div>
2205 + </div>
2206 + </div>
2207 + <input type="hidden" name="client_fields[client_id]" value="<?php echo intval( $client_id ); ?>">
2208 + <script type="text/javascript">
2209 + jQuery( document ).ready( function () {
2210 + mainwp_sidebar_accordion_init();
2211 +
2212 + // to fix issue not loaded calendar js library
2213 + if (jQuery('.ui.calendar').length > 0) {
2214 + if (mainwpParams.use_wp_datepicker == 1) {
2215 + jQuery('#mainwp-add-new-client-form .ui.calendar input[type=text]').datepicker({ dateFormat: "yy-mm-dd" });
2216 + } else {
2217 + mainwp_init_ui_calendar( '#mainwp-add-new-client-form .ui.calendar' );
2218 + }
2219 + }
2220 +
2221 + let current_iconObj;
2222 +
2223 + jQuery(document).on('click', '.mainwp-add-edit-client-icon-customable', function () {
2224 + current_iconObj = jQuery(this);
2225 + jQuery('#mainwp_delete_image_field').hide();
2226 + jQuery('#mainwp-upload-custom-icon-modal').modal({
2227 + allowMultiple: true, // multiple modals.
2228 + closable: false,
2229 + }).modal('show');
2230 + jQuery('#update_custom_icon_btn').attr('uploading-icon', 'client');
2231 + jQuery('#update_custom_icon_btn').removeAttr('disabled');
2232 + jQuery('#mainwp_delete_image_field').find('#mainwp_delete_image_chk').attr('iconItemId', current_iconObj.attr('iconItemId') ); // @see used by mainwp_upload_custom_types_icon().
2233 + jQuery('#mainwp_delete_image_field').find('#mainwp_delete_image_chk').attr('iconFileSlug', current_iconObj.attr('iconFileSlug') ); // @see used by mainwp_upload_custom_types_icon().
2234 +
2235 + if (current_iconObj.attr('icon-src') != '') {
2236 + jQuery('#mainwp_delete_image_field').find('.ui.image').attr('src', current_iconObj.attr('icon-src'));
2237 + jQuery('#mainwp_delete_image_field').show();
2238 + }
2239 + });
2240 +
2241 + jQuery(document).on('click', '.mainwp-add-edit-contact-icon-customable', function () {
2242 + current_iconObj = jQuery(this);
2243 + jQuery('#mainwp_delete_image_field').hide();
2244 + jQuery('#mainwp-upload-custom-icon-modal').modal({
2245 + allowMultiple: true, // multiple modals.
2246 + closable: false,
2247 + }).modal('show');
2248 + jQuery('#update_custom_icon_btn').attr('uploading-icon', 'contact');
2249 + jQuery('#update_custom_icon_btn').removeAttr('disabled');
2250 + jQuery('#mainwp_delete_image_field').find('#mainwp_delete_image_chk').attr('iconItemId', current_iconObj.attr('iconItemId') ); // @see used by mainwp_upload_custom_types_icon().
2251 + jQuery('#mainwp_delete_image_field').find('#mainwp_delete_image_chk').attr('iconFileSlug', current_iconObj.attr('iconFileSlug') ); // @see used by mainwp_upload_custom_types_icon().
2252 +
2253 + if (current_iconObj.attr('icon-src') != '') {
2254 + jQuery('#mainwp_delete_image_field').find('.ui.image').attr('src', current_iconObj.attr('icon-src'));
2255 + jQuery('#mainwp_delete_image_field').show();
2256 + }
2257 + });
2258 +
2259 + // to fix conflict with other update custom icon click event.
2260 + jQuery(document).on('click', '#update_custom_icon_btn', function () {
2261 + if( 'client' === jQuery(this).attr( 'uploading-icon' ) ){
2262 + mainwp_update_custom_icon_client( current_iconObj );
2263 + } else if( 'contact' === jQuery(this).attr( 'uploading-icon' ) ){
2264 + mainwp_update_custom_icon_contact( current_iconObj );
2265 + }
2266 + });
2267 +
2268 + mainwp_update_custom_icon_client = function( iconObj ){
2269 + let deleteIcon = jQuery('#mainwp_delete_image_chk').is(':checked');
2270 + let iconItemId = iconObj.attr('iconItemId');
2271 + let iconFileSlug = iconObj.attr('iconFileSlug'); // to support delete file when iconItemId = 0.
2272 +
2273 + // upload/delete lient icon action.
2274 + mainwp_upload_custom_types_icon(iconObj, 'mainwp_add_edit_client_upload_client_icon', iconItemId, iconFileSlug, deleteIcon, function(response){
2275 + if (jQuery('#mainwp_add_edit_client_uploaded_icon_hidden').length > 0) {
2276 + if (typeof response.iconfile !== undefined) {
2277 + jQuery('#mainwp_add_edit_client_uploaded_icon_hidden').val(response.iconfile);
2278 + } else {
2279 + jQuery('#mainwp_add_edit_client_uploaded_icon_hidden').val('');
2280 + }
2281 + jQuery( '#mainwp_add_edit_client_uploaded_icon_hidden' ).trigger('change');
2282 + }
2283 + let deleteIcon = jQuery('#mainwp_delete_image_chk').is(':checked'); // to delete.
2284 + if(deleteIcon){
2285 + jQuery('#mainwp_add_edit_client_upload_custom_icon').hide();
2286 + } else if (jQuery('#mainwp_add_edit_client_upload_custom_icon').length > 0) {
2287 + if (typeof response.iconfile !== undefined) {
2288 + let icon_img = typeof response.iconimg !== undefined ? response.iconimg : '';
2289 + let icon_src = typeof response.iconsrc !== undefined ? response.iconsrc : '';
2290 + iconObj.attr('icon-src', icon_src);
2291 + iconObj.attr('iconFileSlug', response.iconfile); // to support delete file when iconItemId = 0.
2292 + iconObj.attr('del-icon-nonce', response.iconnonce);
2293 + jQuery('#mainwp_delete_image_field').find('.ui.image').attr('src', icon_src);
2294 + jQuery('#mainwp_add_edit_client_upload_custom_icon').html(icon_img);
2295 + jQuery('#mainwp_add_edit_client_upload_custom_icon').show();
2296 + }
2297 + }
2298 + setTimeout(function () {
2299 + jQuery('#mainwp-upload-custom-icon-modal').modal('hide');
2300 + }, 1000);
2301 + });
2302 + return false;
2303 + }
2304 +
2305 + mainwp_update_custom_icon_contact = function( iconObj ){
2306 + let deleteIcon = jQuery('#mainwp_delete_image_chk').is(':checked');
2307 + let iconItemId = iconObj.attr('iconItemId');
2308 + let iconFileSlug = iconObj.attr('iconFileSlug'); // to support delete file when iconItemId = 0.
2309 +
2310 + // upload/delete lient icon action.
2311 + mainwp_upload_custom_types_icon(iconObj, 'mainwp_add_edit_contact_upload_contact_icon', iconItemId, iconFileSlug, deleteIcon, function(response){
2312 + let parent = jQuery(iconObj).closest('.mainwp_edit_clients_contact_uploaded_icon_wrapper');
2313 +
2314 + if (jQuery('#mainwp_add_edit_client_uploaded_icon_hidden').length > 0) {
2315 + if (typeof response.iconfile !== undefined) {
2316 + jQuery(parent).find('.mainwp_add_edit_contact_uploaded_icon_hidden').val(response.iconfile);
2317 + } else {
2318 + jQuery(parent).find('.mainwp_add_edit_contact_uploaded_icon_hidden').val('');
2319 + }
2320 + jQuery(parent).find( '.mainwp_add_edit_contact_uploaded_icon_hidden' ).trigger('change');
2321 + }
2322 + let deleteIcon = jQuery('#mainwp_delete_image_chk').is(':checked'); // to delete.
2323 + if(deleteIcon){
2324 + jQuery(parent).find('.mainwp_add_edit_contact_upload_custom_icon').hide();
2325 + } else if (jQuery(parent).find('.mainwp_add_edit_contact_upload_custom_icon').length > 0) {
2326 + if (typeof response.iconfile !== undefined) {
2327 + let icon_img = typeof response.iconimg !== undefined ? response.iconimg : '';
2328 + let icon_src = typeof response.iconsrc !== undefined ? response.iconsrc : '';
2329 + iconObj.attr('icon-src', icon_src);
2330 + iconObj.attr('iconFileSlug', response.iconfile); // to support delete file when iconItemId = 0.
2331 + iconObj.attr('del-icon-nonce', response.iconnonce);
2332 + jQuery('#mainwp_delete_image_field').find('.ui.image').attr('src', icon_src);
2333 + jQuery(parent).find('.mainwp_add_edit_contact_upload_custom_icon').html(icon_img).show();
2334 + }
2335 + }
2336 + setTimeout(function () {
2337 + jQuery('#mainwp-upload-custom-icon-modal').modal('hide')
2338 + }, 1000);
2339 + });
2340 + return false;
2341 + }
2342 +
2343 + } );
2344 + </script>
2345 + <?php
2346 + }
2347 +
2348 + /**
2349 + * Method get_cust_client_icon()
2350 + *
2351 + * Get site icon.
2352 + *
2353 + * @param string $icon_data icon data.
2354 + * @param string $type Type: selected|color|display.
2355 + * @param string $what Icon display for what.
2356 + */
2357 + public static function get_cust_client_icon( $icon_data, $type = 'display', $what = 'default' ) {
2358 + if ( empty( $icon_data ) ) {
2359 + return '';
2360 + }
2361 + $data = explode( ';', $icon_data );
2362 + $selected_icon = str_replace( 'selected:', '', $data[0] );
2363 + $color = str_replace( 'color:', '', $data[1] );
2364 +
2365 + if ( empty( $color ) ) {
2366 + $color = '#34424D';
2367 + }
2368 +
2369 + $icon_cls = 'circular inverted icon';
2370 + if ( 'card' === $what ) {
2371 + $icon_cls = 'huge circular inverted icon';
2372 + }
2373 +
2374 + $output = '';
2375 + if ( 'selected' === $type ) {
2376 + $output = $selected_icon;
2377 + } elseif ( 'color' === $type ) {
2378 + $output = $color;
2379 + } elseif ( 'display' === $type || 'display_edit' === $what ) {
2380 + $color_style = '';
2381 + if ( ! empty( $color ) ) {
2382 + $color_style = 'background-color:' . esc_attr( $color ) . ';';
2383 + }
2384 + $icon_wrapper_attr = 'class="mainwp_client_icon_display"';
2385 + if ( 'display_edit' === $what ) {
2386 + $icon_wrapper_attr = ' id="mainwp_add_edit_client_upload_custom_icon" ' . $icon_wrapper_attr;
2387 + }
2388 + $output = '<div style="display:inline-block;" ' . $icon_wrapper_attr . ' ><i class="' . esc_attr( $selected_icon ) . ' ' . $icon_cls . '" style="' . $color_style . '"></i></div>';
2389 + }
2390 + return $output;
2391 + }
2392 +
2393 + /**
2394 + * Method get_add_contact_temp().
2395 + *
2396 + * Get add contact template.
2397 + *
2398 + * @param mixed $edit_contact The contact data to edit.
2399 + * @param bool $echo_out Echo template or not.
2400 + * @param int $client_id Client id.
2401 + */
2402 + public static function get_add_contact_temp( $edit_contact = false, $echo_out = false, $client_id = 0 ) { //phpcs:ignore -- NOSONAR - complex.
2403 +
2404 + $input_name = 'new_contacts_field';
2405 + $contact_id = 0;
2406 + $contact_image = '';
2407 + if ( $edit_contact ) {
2408 + $input_name = 'contacts_field';
2409 + $contact_id = $edit_contact->contact_id;
2410 + $contact_image = $edit_contact->contact_image;
2411 + }
2412 +
2413 + $uploaded_icon_src = '';
2414 + if ( ! empty( $contact_image ) ) {
2415 + $arr_fields = array(
2416 + 'contact_image',
2417 + 'contact_icon_info',
2418 + );
2419 + $icon_info_array = MainWP_Utility::map_fields( $edit_contact, $arr_fields, false );
2420 + $uploaded_icon_src = MainWP_Client_Handler::get_client_contact_image( $icon_info_array, 'contact', 'uploaded_icon' );
2421 + }
2422 +
2423 + ob_start();
2424 + ?>
2425 + <h3 class="ui dividing header top-contact-fields"> <?php // must have class: top-contact-fields. ?>
2426 + <?php if ( $edit_contact ) : ?>
2427 + <?php echo esc_html__( 'Edit Contact', 'mainwp' ); ?>
2428 + <div class="sub header"><?php esc_html_e( 'Edit contact person information.', 'mainwp' ); ?></div>
2429 + <?php else : ?>
2430 + <?php esc_html_e( 'Add Contact', 'mainwp' ); ?>
2431 + <div class="sub header"><?php esc_html_e( 'Enter contact person information.', 'mainwp' ); ?></div>
2432 + <?php endif; ?>
2433 + </h3>
2434 + <?php
2435 + $default_icons = MainWP_UI::get_default_icons();
2436 + $contact_fields = MainWP_Client_Handler::get_default_contact_fields();
2437 + foreach ( $contact_fields as $field_name => $field ) {
2438 + $db_field = isset( $field['db_field'] ) ? $field['db_field'] : '';
2439 + $val = $edit_contact && '' !== $db_field && property_exists( $edit_contact, $db_field ) ? $edit_contact->{$db_field} : '';
2440 + $contact_id = $edit_contact && property_exists( $edit_contact, 'contact_id' ) ? $edit_contact->contact_id : '';
2441 + ?>
2442 + <div class="ui grid field settings-field-indicator-wrapper">
2443 + <label class="six wide column middle aligned">
2444 + <?php
2445 + $indi_val = $edit_contact && $val ? 1 : 0;
2446 + MainWP_Settings_Indicator::render_not_default_indicator( 'none_preset_value', $indi_val );
2447 + echo esc_html( $field['title'] );
2448 + if ( ! empty( $field['required'] ) ) {
2449 + echo ' <span class="ui small red text">' . esc_html__( '(Required)', 'mainwp' ) . '</span>';
2450 + }
2451 + ?>
2452 + </label>
2453 + <div class="ui six wide column">
2454 + <div class="ui left labeled input">
2455 + <input type="text" value="<?php echo esc_attr( $val ); ?>" class="regular-text settings-field-value-change-handler" name="client_fields[<?php echo esc_attr( $input_name ); ?>][<?php echo esc_attr( $field_name ); ?>][]"/>
2456 + </div>
2457 + </div>
2458 + <?php if ( $edit_contact ) : ?>
2459 + <div class="ui four wide middle aligned hidden token column" style="display:none">
2460 + [<?php echo esc_html( $field_name ); ?>]
2461 + </div>
2462 + <?php endif; ?>
2463 + </div>
2464 + <?php
2465 + if ( 'contact.role' === $field_name ) {
2466 + ?>
2467 + <div class="ui grid field mainwp_edit_clients_contact_uploaded_icon_wrapper settings-field-indicator-wrapper">
2468 + <label class="six wide column middle aligned">
2469 + <?php
2470 + $indi_val = $edit_contact && $contact_image ? 1 : 0;
2471 + MainWP_Settings_Indicator::render_not_default_indicator( 'none_preset_value', $indi_val );
2472 + $delnonce = MainWP_System_Utility::get_custom_nonce( 'contact', esc_attr( $contact_image ) );
2473 + ?>
2474 + <?php esc_html_e( 'Contact photo', 'mainwp' ); ?>
2475 + </label>
2476 + <input type="hidden" name="mainwp_add_edit_contact_uploaded_icon_hidden[<?php echo esc_html( $input_name ); ?>][]" class="settings-field-value-change-handler mainwp_add_edit_contact_uploaded_icon_hidden" value="<?php echo esc_attr( $contact_image ); ?>">
2477 + <div class="three wide middle aligned column" data-tooltip="<?php esc_attr_e( 'Upload a contact photo.', 'mainwp' ); ?>" data-inverted="" data-position="left center">
2478 + <div class="ui green button basic mainwp-add-edit-contact-icon-customable" iconItemId="<?php echo intval( $contact_id ); ?>" iconFileSlug="<?php echo esc_attr( $contact_image ); ?>" del-icon-nonce="<?php echo esc_attr( $delnonce ); ?>" icon-src="<?php echo esc_attr( $uploaded_icon_src ); ?>"><?php esc_html_e( 'Upload Icon', 'mainwp' ); ?></div>
2479 + <?php
2480 + if ( ! empty( $contact_image ) ) {
2481 + ?>
2482 + <?php echo MainWP_Client_Handler::get_client_contact_image( $icon_info_array, 'contact', 'display_edit' ); //phpcs:ignore --ok. ?>
2483 + <?php } else { ?>
2484 + <div style="display:inline-block;" class="mainwp_add_edit_contact_upload_custom_icon"></div> <?php // used for icon holder. ?>
2485 + <?php } ?>
2486 + </div>
2487 + </div>
2488 + <div class="ui grid field mainwp_edit_clients_contact_icon_wrapper settings-field-indicator-wrapper" input-name="<?php echo esc_attr( $input_name ); ?>" default-indi-indi-value="wordpress">
2489 + <label class="six wide column middle aligned">
2490 + <?php
2491 + $selected_icon = 'wordpress'; //phpcs:ignore -- WP icon.
2492 + $selected_color = '#34424D';
2493 + $icon_info = $edit_contact ? $edit_contact->contact_icon_info : '';
2494 +
2495 + if ( ! empty( $icon_info ) ) {
2496 + $selected_icon = static::get_cust_client_icon( $icon_info, 'selected' );
2497 + $selected_color = static::get_cust_client_icon( $icon_info, 'color' );
2498 + }
2499 + $indi_val = 'wordpress' !== $selected_icon ? 1 : 0; //phpcs:ignore -- WP icon.
2500 + MainWP_Settings_Indicator::render_not_default_indicator( 'none_preset_value', $indi_val );
2501 + esc_html_e( 'Select icon', 'mainwp' );
2502 + ?>
2503 + </label>
2504 + <div class="six wide column" data-tooltip="<?php esc_attr_e( 'Select an icon if not using original contact icon.', 'mainwp' ); ?>" data-inverted="" data-position="left center">
2505 + <input type="hidden" class="settings-field-value-change-handler" name="client_fields[<?php echo esc_html( $input_name ); ?>][selected_icon][]" id="client_fields[<?php echo esc_attr( $input_name ); ?>][selected_icon][]" value="<?php echo esc_attr( $selected_icon ); ?>">
2506 + <div class="ui left action input mainwp-dropdown-color-picker-field">
2507 + <div class="ui five column selection search dropdown not-auto-init mainwp-edit-clients-select-contact-icon" style="min-width:21em">
2508 + <div class="text">
2509 + <span style="color:<?php echo esc_attr( $selected_color ); ?>" ><?php echo ! empty( $selected_icon ) ? '<i class="' . esc_attr( $selected_icon ) . ' icon"></i>' : ''; ?></span>
2510 + </div>
2511 + <i class="dropdown icon"></i>
2512 + <div class="menu">
2513 + <?php foreach ( $default_icons as $icon ) : ?>
2514 + <?php echo '<div class="item" style="color:' . esc_attr( $selected_color ) . '" data-value="' . esc_attr( $icon ) . '"><i class="' . esc_attr( $icon ) . ' icon"></i></div>'; ?>
2515 + <?php endforeach; ?>
2516 + </div>
2517 + </div>
2518 + <input type="color" data-tooltip="Color will update on save" data-position="top center" data-inverted="" name="client_fields[<?php echo esc_html( $input_name ); ?>][selected_color][]" class="mainwp-color-picker-input" id="client_fields[<?php echo esc_html( $input_name ); ?>][selected_color][]" value="<?php echo esc_attr( $selected_color ); ?>" />
2519 + </div>
2520 + </div>
2521 + <div class="one wide column"></div>
2522 + </div>
2523 + <?php
2524 + }
2525 + }
2526 +
2527 + ?>
2528 + <div class="ui grid field remove-contact-field-parent">
2529 + <label class="six wide column middle aligned"><?php esc_html_e( 'Remove contact', 'mainwp' ); ?></label>
2530 + <div class="ui six wide column">
2531 + <div class="ui left labeled input">
2532 + <a href="javascript:void(0);" contact-id="<?php echo intval( $contact_id ); ?>" class="ui basic button mainwp-client-remove-contact"><?php esc_html_e( 'Remove contact', 'mainwp' ); ?></a>
2533 + </div>
2534 + <?php
2535 + if ( $edit_contact ) {
2536 + ?>
2537 + <input type="hidden" value="<?php echo intval( $edit_contact->contact_id ); ?>" name="client_fields[contacts_field][contact_id][]"/>
2538 + <input type="hidden" value="<?php echo esc_attr( wp_create_nonce( 'editing-' . $client_id . '-contact-' . $edit_contact->contact_id ) ); ?>" name="client_fields[contacts_field][nonce_contact_id][]"/>
2539 + <?php
2540 + }
2541 + ?>
2542 + </div>
2543 + </div>
2544 + <div class="ui section hidden divider bottom-contact-fields"></div>
2545 + <?php
2546 + $html = ob_get_clean();
2547 +
2548 + if ( $echo_out ) {
2549 + echo $html; //phpcs:ignore -- validated content.
2550 + }
2551 +
2552 + return $html;
2553 + }
2554 +
2555 + /**
2556 + * Method save_client_field().
2557 + *
2558 + * Save custom fields.
2559 + */
2560 + public static function save_client_field() { //phpcs:ignore -- NOSONAR - complex.
2561 +
2562 + $return = array(
2563 + 'success' => false,
2564 + 'error' => '',
2565 + 'message' => '',
2566 + );
2567 +
2568 + // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
2569 + $client_id = isset( $_POST['client_id'] ) ? intval( $_POST['client_id'] ) : 0; // 0 is global client's field.
2570 + $field_id = isset( $_POST['field_id'] ) ? intval( $_POST['field_id'] ) : 0;
2571 + $field_desc = isset( $_POST['field_desc'] ) ? sanitize_text_field( wp_unslash( $_POST['field_desc'] ) ) : '';
2572 + $field_name = isset( $_POST['field_name'] ) ? sanitize_text_field( wp_unslash( $_POST['field_name'] ) ) : '';
2573 + $field_name = trim( $field_name, '[]' );
2574 + // phpcs:enable
2575 +
2576 + // update general or individual client field.
2577 + if ( $field_id ) {
2578 + $current = MainWP_DB_Client::instance()->get_client_fields_by( 'field_id', $field_id );
2579 + if ( $current && $current->field_name === $field_name && $current->field_desc === $field_desc ) {
2580 + $return['success'] = true;
2581 + $return['message'] = esc_html__( 'Field has been saved without changes.', 'mainwp' );
2582 + } else {
2583 + $current = MainWP_DB_Client::instance()->get_client_fields_by( 'field_name', $field_name, $client_id ); // check if other field with the same name existed.
2584 + if ( $current && (int) $current->field_id !== $field_id ) {
2585 + $return['error'] = esc_html__( 'Field already exists, try different field name.', 'mainwp' );
2586 + } else {
2587 + // update general or individual field name.
2588 + $field = MainWP_DB_Client::instance()->update_client_field(
2589 + $field_id,
2590 + array(
2591 + 'field_name' => $field_name,
2592 + 'field_desc' => $field_desc,
2593 + 'client_id' => $client_id,
2594 + )
2595 + );
2596 + if ( $field ) {
2597 + $return['success'] = true;
2598 + }
2599 + }
2600 + }
2601 + } else { // add new.
2602 + $current = MainWP_DB_Client::instance()->get_client_fields_by( 'field_name', $field_name, $client_id );
2603 + if ( $current ) { // checking general or individual field name.
2604 + $return['error'] = esc_html__( 'Field already exists, try different field name.', 'mainwp' );
2605 + } else {
2606 + // insert general or individual field name.
2607 + $field = MainWP_DB_Client::instance()->add_client_field(
2608 + array(
2609 + 'field_name' => $field_name,
2610 + 'field_desc' => $field_desc,
2611 + 'client_id' => $client_id,
2612 + )
2613 + );
2614 +
2615 + if ( $field ) {
2616 + $return['success'] = true;
2617 + } else {
2618 + $return['error'] = esc_html__( 'Undefined error occurred. Please try again.', 'mainwp' );
2619 + }
2620 + }
2621 + }
2622 + echo wp_json_encode( $return );
2623 + exit;
2624 + }
2625 +
2626 + /**
2627 + * Method save_note()
2628 + *
2629 + * Save Client Note.
2630 + */
2631 + public static function save_note() {
2632 + if ( isset( $_POST['clientid'] ) && ! empty( $_POST['clientid'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
2633 + $note = isset( $_POST['note'] ) ? wp_unslash( $_POST['note'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
2634 + $esc_note = MainWP_Utility::esc_content( $note );
2635 + $update = array(
2636 + 'client_id' => intval( $_POST['clientid'] ), // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
2637 + 'note' => $esc_note,
2638 + );
2639 + MainWP_DB_Client::instance()->update_client( $update );
2640 + die(
2641 + wp_json_encode(
2642 + array(
2643 + 'result' => 'SUCCESS',
2644 + 'esc_note_content' => $esc_note,
2645 + )
2646 + )
2647 + );
2648 + }
2649 + die( wp_json_encode( array( 'undefined_error' => true ) ) );
2650 + }
1904 2651 }