PluginProbe
User Profile Builder – Beautiful User Registration Forms, User Profiles & User Role Editor / 4.0.2
User Profile Builder – Beautiful User Registration Forms, User Profiles & User Role Editor v4.0.2
4.0.2 4.0.1 4.0.0 3.16.6 3.16.5 3.16.4 3.16.3 3.16.2 3.16.1 3.16.0 3.15.9 3.9.9 3.9.5 3.9.6 3.9.7 3.9.8 1.1.7 1.1.8 1.1.9 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 All 340 releases
← All changes | admin/admin-functions.php +1068 -168 2.0.44.0.2 View file →
@@ -1,168 +1,1068 @@
1 -<?php
2 -/**
3 - * Function which returns the same field-format over and over again.
4 - *
5 - * @since v.2.0
6 - *
7 - * @param string $field
8 - * @param string $field_title
9 - *
10 - * @return string
11 - */
12 -function wppb_field_format ( $field_title, $field ){
13 -
14 - return trim( $field_title ).' ( '.trim( $field ).' )';
15 -}
16 -
17 -
18 -/**
19 - * Add a notification for either the Username or the Email field letting the user know that, even though it is there, it won't do anything
20 - *
21 - * @since v.2.0
22 - *
23 - * @param string $form
24 - * @param integer $id
25 - * @param string $value
26 - *
27 - * @return string $form
28 - */
29 -function wppb_manage_fields_display_field_title_slug( $form, $i, $value ){
30 - $wppb_generalSettings = get_option( 'wppb_general_settings', 'not_found' );
31 - if ( $wppb_generalSettings != 'not_found' ){
32 - if ( $wppb_generalSettings['loginWith'] == 'email' )
33 - if ( ( $value == 'Username ( Default - Username )' ) || ( $value == 'Username' ) )
34 - $form .= '<div id="wppb-login-email-nag" class="wppb-backend-notice">' . sprintf( __( 'Login is set to be done using the E-mail. This field will NOT appear in the front-end! ( you can change these settings under the "%s" tab )', 'profilebuilder' ), '<a href="'.admin_url( 'admin.php?page=profile-builder-general-settings' ).'" target="_blank">' . __('General Settings', 'profilebuilder') . '</a>' ) . '</div>';
35 - }
36 -
37 - return $form;
38 -}
39 -add_filter( "wck_before_listed_wppb_manage_fields_element_0", 'wppb_manage_fields_display_field_title_slug', 10, 3 );
40 -add_filter( "wck_before_listed_wppb_epf_fields_element_0", 'wppb_manage_fields_display_field_title_slug', 10, 3 );
41 -add_filter( "wck_before_listed_wppb_rf_fields_element_0", 'wppb_manage_fields_display_field_title_slug', 10, 3 );
42 -
43 -
44 -
45 -
46 -
47 -/**
48 - * Function that adds a custom class to the existing container
49 - *
50 - * @since v.2.0
51 - *
52 - * @param string $update_container_class - the new class name
53 - * @param string $meta - the name of the meta
54 - * @param array $results
55 - * @param integer $element_id - the ID of the element
56 - *
57 - * @return string
58 - */
59 -function wppb_update_container_class( $update_container_class, $meta, $results, $element_id ) {
60 - $wppb_element_type = Wordpress_Creation_Kit_PB::wck_generate_slug( $results[$element_id]["field"] );
61 -
62 - return "class='update_container_$meta update_container_$wppb_element_type element_type_$wppb_element_type'";
63 -}
64 -add_filter( 'wck_update_container_class_wppb_manage_fields', 'wppb_update_container_class', 10, 4 );
65 -
66 -
67 -/**
68 - * Function that adds a custom class to the existing element
69 - *
70 - * @since v.2.0
71 - *
72 - * @param string $element_class - the new class name
73 - * @param string $meta - the name of the meta
74 - * @param array $results
75 - * @param integer $element_id - the ID of the element
76 - *
77 - * @return string
78 - */
79 -function wppb_element_class( $element_class, $meta, $results, $element_id ){
80 - $wppb_element_type = Wordpress_Creation_Kit_PB::wck_generate_slug( $results[$element_id]["field"] );
81 -
82 - return "class='element_type_$wppb_element_type added_fields_list'";
83 -}
84 -add_filter( 'wck_element_class_wppb_manage_fields', 'wppb_element_class', 10, 4 );
85 -
86 -/**
87 - * Functions to check password length and strength
88 - *
89 - * @since v.2.0
90 - */
91 -/* on add user and update profile from WP admin area */
92 -add_action( 'user_profile_update_errors', 'wppb_password_check_on_profile_update', 0, 3 );
93 -function wppb_password_check_on_profile_update( $errors, $update, $user ){
94 - wppb_password_check_extra_conditions( $errors, $user );
95 -}
96 -
97 -/* on reset password */
98 -add_action( 'validate_password_reset', 'wppb_password_check_extra_conditions', 10, 2 );
99 -function wppb_password_check_extra_conditions( $errors, $user ){
100 - $password = ( isset( $_POST[ 'pass1' ] ) && trim( $_POST[ 'pass1' ] ) ) ? $_POST[ 'pass1' ] : false;
101 -
102 - if( $password ){
103 - $wppb_generalSettings = get_option( 'wppb_general_settings' );
104 - if( !empty( $wppb_generalSettings['minimum_password_length'] ) ){
105 - if( strlen( $password ) < $wppb_generalSettings['minimum_password_length'] )
106 - $errors->add( 'pass', __( '<strong>ERROR</strong>: The password must have the minimum length of '. $wppb_generalSettings['minimum_password_length'] .' characters', 'profilebuilder' ) );
107 - }
108 -
109 - if( isset( $_POST['wppb_password_strength'] ) && !empty( $wppb_generalSettings['minimum_password_strength'] ) ){
110 -
111 - $password_strength_array = array( 'short' => 0, 'bad' => 1, 'good' => 2, 'strong' => 3 );
112 - $password_strength_text = array( 'short' => __( 'Very weak', 'profilebuilder' ), 'bad' => __( 'Weak', 'profilebuilder' ), 'good' => __( 'Medium', 'profilebuilder' ), 'strong' => __( 'Strong', 'profilebuilder' ) );
113 -
114 - foreach( $password_strength_text as $psr_key => $psr_text ){
115 - if( $psr_text == $_POST['wppb_password_strength'] ){
116 - $password_strength_result_slug = $psr_key;
117 - break;
118 - }
119 - }
120 -
121 - if( !empty( $password_strength_result_slug ) ){
122 - if( $password_strength_array[$password_strength_result_slug] < $password_strength_array[$wppb_generalSettings['minimum_password_strength']] )
123 - $errors->add( 'pass', __( '<strong>ERROR</strong>: The password must have a minimum strength of '. $password_strength_text[$wppb_generalSettings['minimum_password_strength']], 'profilebuilder' ) );
124 - }
125 - }
126 - }
127 -
128 - return $errors;
129 -}
130 -
131 -/* we need to create a hidden field that contains the results of the password strength from the js strength tester */
132 -add_action( 'admin_footer', 'wppb_add_hidden_password_strength_on_backend' );
133 -add_action( 'login_footer', 'wppb_add_hidden_password_strength_on_backend' );
134 -function wppb_add_hidden_password_strength_on_backend(){
135 - if( $GLOBALS['pagenow'] == 'profile.php' || $GLOBALS['pagenow'] == 'user-new.php' || ( $GLOBALS['pagenow'] == 'wp-login.php' && isset( $_GET['action'] ) && ( $_GET['action'] == 'rp' || $_GET['action'] == 'resetpass' ) ) ){
136 - $wppb_generalSettings = get_option( 'wppb_general_settings' );
137 - if( !empty( $wppb_generalSettings['minimum_password_strength'] ) ){
138 - ?>
139 - <script type="text/javascript">
140 - jQuery( document ).ready( function() {
141 - var passswordStrengthResult = jQuery( '#pass-strength-result' );
142 - // Check for password strength meter
143 - if ( passswordStrengthResult.length ) {
144 - // Attach submit event to form
145 - passswordStrengthResult.parents( 'form' ).on( 'submit', function() {
146 - // Store check results in hidden field
147 - jQuery( this ).append( '<input type="hidden" name="wppb_password_strength" value="' + passswordStrengthResult.text() + '">' );
148 - });
149 - }
150 - });
151 - </script>
152 - <?php
153 - }
154 - }
155 -}
156 -
157 -
158 -/* Modify the Add Entry buttons for WCK metaboxes according to context */
159 -add_filter( 'wck_add_entry_button', 'wppb_change_add_entry_button', 10, 2 );
160 -function wppb_change_add_entry_button( $string, $meta ){
161 - if( $meta == 'wppb_manage_fields' || $meta == 'wppb_epf_fields' || $meta == 'wppb_rf_fields' ){
162 - return __( "Add Field", 'profilebuilder' );
163 - }elseif( $meta == 'wppb_epf_page_settings' || $meta == 'wppb_rf_page_settings' || $meta == 'wppb_ul_page_settings' ){
164 - return __( "Save Settings", 'profilebuilder' );
165 - }
166 -
167 - return $string;
168 -}
1 +<?php
2 +if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
3 +
4 +/**
5 + * Function which returns the same field-format over and over again.
6 + *
7 + * @since v.2.0
8 + *
9 + * @param string $field
10 + * @param string $field_title
11 + *
12 + * @return string
13 + */
14 +function wppb_field_format ( $field_title, $field ){
15 +
16 + return trim( $field_title ).' ( '.trim( $field ).' )';
17 +}
18 +
19 +/**
20 + * Add a notification for either the Username or the Email field letting the user know that, even though it is there, it won't do anything
21 + *
22 + * @since v.2.0
23 + *
24 + * @param string $form
25 + * @param integer $id
26 + * @param string $value
27 + *
28 + * @return string $form
29 + */
30 +
31 +function wppb_manage_fields_display_field_title_slug( $form ){
32 + // add a notice to fields
33 + global $wppb_results_field;
34 + switch ($wppb_results_field){
35 + case 'Default - Username':
36 + $wppb_generalSettings = get_option( 'wppb_general_settings', 'not_found' );
37 + if ( $wppb_generalSettings != 'not_found' && $wppb_generalSettings['loginWith'] == 'email' ) {
38 + $form .= '<div id="wppb-login-email-nag" class="wppb-backend-notice">' . sprintf(__('Login is set to be done using the Email. This field will NOT appear in the front-end! ( you can change these settings under the "%s" tab )', 'profile-builder'), '<a href="' . admin_url('admin.php?page=profile-builder-general-settings') . '" target="_blank">' . __('General Settings', 'profile-builder') . '</a>') . '</div>';
39 + }
40 + break;
41 + case 'Default - Display name publicly as':
42 + $form .= '<div id="wppb-display-name-nag" class="wppb-backend-notice">' . __( 'Display name publicly as - only appears on the Edit Profile page!', 'profile-builder' ) . '</div>';
43 + break;
44 + case 'Default - Blog Details':
45 + $form .= '<div id="wppb-blog-details-nag" class="wppb-backend-notice">' . __( 'Blog Details - only appears on the Registration page!', 'profile-builder' ) . '</div>';
46 + break;
47 + }
48 +
49 + return $form;
50 +}
51 +
52 +add_filter( 'wck_after_content_element', 'wppb_manage_fields_display_field_title_slug' );
53 +
54 +/**
55 + * Check if field type is 'Default - Display name publicly as' so we can add a notification for it
56 + *
57 + * @since v.2.2
58 + *
59 + * @param string $wck_element_class
60 + * @param string $meta
61 + * @param array $results
62 + * @param integer $element_id
63 + *
64 + */
65 +function wppb_manage_fields_display_name_notice( $wck_element_class, $meta, $results, $element_id ) {
66 + global $wppb_results_field;
67 +
68 + $wppb_results_field = $results[$element_id]['field'];
69 +}
70 +add_filter( 'wck_element_class_wppb_manage_fields', 'wppb_manage_fields_display_name_notice', 10, 4 );
71 +
72 +/**
73 + * Function that adds a custom class to the existing container
74 + *
75 + * @since v.2.0
76 + *
77 + * @param string $update_container_class - the new class name
78 + * @param string $meta - the name of the meta
79 + * @param array $results
80 + * @param integer $element_id - the ID of the element
81 + *
82 + * @return string
83 + */
84 +function wppb_update_container_class( $update_container_class, $meta, $results, $element_id ) {
85 + $wppb_element_type = Wordpress_Creation_Kit_PB::wck_generate_slug( $results[$element_id]["field"] );
86 +
87 + return "class='wck_update_container update_container_$meta update_container_$wppb_element_type element_type_$wppb_element_type'";
88 +}
89 +add_filter( 'wck_update_container_class_wppb_manage_fields', 'wppb_update_container_class', 10, 4 );
90 +
91 +/**
92 + * Function that adds a custom class to the existing element
93 + *
94 + * @since v.2.0
95 + *
96 + * @param string $element_class - the new class name
97 + * @param string $meta - the name of the meta
98 + * @param array $results
99 + * @param integer $element_id - the ID of the element
100 + *
101 + * @return string
102 + */
103 +function wppb_element_class( $element_class, $meta, $results, $element_id ){
104 + $wppb_element_type = Wordpress_Creation_Kit_PB::wck_generate_slug( $results[$element_id]["field"] );
105 +
106 + return "class='element_type_$wppb_element_type added_fields_list'";
107 +}
108 +add_filter( 'wck_element_class_wppb_manage_fields', 'wppb_element_class', 10, 4 );
109 +
110 +/**
111 + * Functions to check password length and strength
112 + *
113 + * @since v.2.0
114 + */
115 +/* on add user and update profile from WP admin area */
116 +add_action( 'user_profile_update_errors', 'wppb_password_check_on_profile_update', 0, 3 );
117 +function wppb_password_check_on_profile_update( $errors, $update, $user ){
118 + wppb_password_check_extra_conditions( $errors, $user );
119 +}
120 +
121 +/* on reset password */
122 +add_action( 'validate_password_reset', 'wppb_password_check_extra_conditions', 10, 2 );
123 +function wppb_password_check_extra_conditions( $errors, $user ){
124 + $password = ( isset( $_POST[ 'pass1' ] ) && trim( $_POST[ 'pass1' ] ) ) ? $_POST[ 'pass1' ] : false; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
125 +
126 + if( $password && ( !isset( $_POST['pw_weak'] ) || $_POST['pw_weak'] != 'on' ) ){
127 + $wppb_generalSettings = get_option( 'wppb_general_settings' );
128 +
129 + if( !empty( $wppb_generalSettings['minimum_password_length'] ) ){
130 + if( strlen( $password ) < $wppb_generalSettings['minimum_password_length'] )
131 + $errors->add( 'pass', sprintf( __( '<strong>ERROR:</strong> The password must have the minimum length of %s characters', 'profile-builder' ), $wppb_generalSettings['minimum_password_length'] ) );
132 + }
133 +
134 + if( isset( $_POST['wppb_password_strength'] ) && !empty( $wppb_generalSettings['minimum_password_strength'] ) ){
135 + $password_strength_array = array( 'short' => 0, 'bad' => 1, 'good' => 2, 'strong' => 3 );
136 + $password_strength_text = array( 'short' => __( 'Very weak', 'profile-builder' ), 'bad' => __( 'Weak', 'profile-builder' ), 'good' => __( 'Medium', 'profile-builder' ), 'strong' => __( 'Strong', 'profile-builder' ) );
137 +
138 + foreach( $password_strength_text as $psr_key => $psr_text ){
139 + if( $psr_text == sanitize_text_field( $_POST['wppb_password_strength'] ) ){
140 + $password_strength_result_slug = $psr_key;
141 + break;
142 + }
143 + }
144 +
145 + if( !empty( $password_strength_result_slug ) ){
146 + if( $password_strength_array[$password_strength_result_slug] < $password_strength_array[$wppb_generalSettings['minimum_password_strength']] )
147 + $errors->add( 'pass', sprintf( __( '<strong>ERROR:</strong> The password must have a minimum strength of %s', 'profile-builder' ), $password_strength_text[$wppb_generalSettings['minimum_password_strength']] ) );
148 + }
149 + }
150 + }
151 +
152 + return $errors;
153 +}
154 +
155 +/* we need to create a hidden field that contains the results of the password strength from the js strength tester */
156 +add_action( 'admin_footer', 'wppb_add_hidden_password_strength_on_backend' );
157 +add_action( 'login_footer', 'wppb_add_hidden_password_strength_on_backend' );
158 +function wppb_add_hidden_password_strength_on_backend(){
159 + if( $GLOBALS['pagenow'] == 'profile.php' || $GLOBALS['pagenow'] == 'user-new.php' || ( $GLOBALS['pagenow'] == 'wp-login.php' && isset( $_GET['action'] ) && ( $_GET['action'] === 'rp' || $_GET['action'] === 'resetpass' ) ) ){
160 + $wppb_generalSettings = get_option( 'wppb_general_settings' );
161 + if( !empty( $wppb_generalSettings['minimum_password_strength'] ) ){
162 + ?>
163 + <script type="text/javascript">
164 + jQuery( document ).ready( function() {
165 + var passswordStrengthResult = jQuery( '#pass-strength-result' );
166 + // Check for password strength meter
167 + if ( passswordStrengthResult.length ) {
168 + // Attach submit event to form
169 + passswordStrengthResult.parents( 'form' ).on( 'submit', function() {
170 + // Store check results in hidden field
171 + jQuery( this ).append( '<input type="hidden" name="wppb_password_strength" value="' + passswordStrengthResult.text() + '">' );
172 + });
173 + }
174 + });
175 + </script>
176 + <?php
177 + }
178 + }
179 +}
180 +
181 +/* Modify the Add Entry buttons for WCK metaboxes according to context */
182 +add_filter( 'wck_add_entry_button', 'wppb_change_add_entry_button', 10, 2 );
183 +function wppb_change_add_entry_button( $string, $meta ){
184 + if( $meta == 'wppb_manage_fields' || $meta == 'wppb_epf_fields' || $meta == 'wppb_rf_fields' ){
185 + return __( "Add Field", 'profile-builder' );
186 + }elseif( $meta == 'wppb_epf_page_settings' || $meta == 'wppb_rf_page_settings' || $meta == 'wppb_ul_page_settings' ){
187 + return __( "Save Settings", 'profile-builder' );
188 + }
189 +
190 + return $string;
191 +}
192 +
193 +/**
194 + * add links on plugin page
195 + */
196 +add_filter( 'plugin_action_links', 'wppb_plugin_action_links', 10, 2 );
197 +function wppb_plugin_action_links( $links, $file ) {
198 + if ( $file != WPPB_PLUGIN_BASENAME ) {
199 + return $links;
200 + }
201 +
202 + if ( ! current_user_can( 'manage_options' ) ) {
203 + return $links;
204 + }
205 +
206 + $settings_link = sprintf( '<a href="%1$s">%2$s</a>',
207 + menu_page_url( 'profile-builder-general-settings', false ),
208 + esc_html( __( 'Settings', 'profile-builder' ) ) );
209 +
210 + array_unshift( $links, $settings_link );
211 +
212 + return $links;
213 +}
214 +
215 +/**
216 + * add links on plugin page
217 + */
218 +add_filter( 'plugin_row_meta', 'wppb_plugin_row_meta', 10, 2 );
219 +function wppb_plugin_row_meta( $links, $file ) {
220 + if ( WPPB_PLUGIN_BASENAME == $file ) {
221 + $row_meta = array(
222 + 'docs' => '<a href="' . esc_url( 'https://www.cozmoslabs.com/docs/profile-builder/' ) . '" target="_blank" aria-label="' . esc_attr__( 'View Profile Builder documentation', 'profile-builder' ) . '">' . esc_html__( 'Docs', 'profile-builder' ) . '</a>',
223 + 'get_support' => '<a href="' . esc_url( apply_filters( 'wppb_docs_url', 'https://wordpress.org/support/plugin/profile-builder/' ) ) . '" title="' . esc_attr( __( 'Get Support', 'profile-builder' ) ) . '" target="_blank">' . __( 'Get Support', 'profile-builder' ) . '</a>',
224 + );
225 +
226 + return array_merge( $links, $row_meta );
227 + }
228 +
229 + return (array) $links;
230 +}
231 +
232 +/**
233 + * Send deactivation feedback from the plugins screen modal.
234 + *
235 + * @param array $reason_data Sanitized reason payload from the popup form.
236 + */
237 +function wppb_send_deactivation_feedback( $reason_data ) {
238 +
239 + if ( ! is_array( $reason_data ) || empty( $reason_data['reason'] ) )
240 + return;
241 +
242 + $body = array(
243 + 'unique_identifier' => hash( 'sha256', home_url( '', 'https' ) ),
244 + 'product' => 'wppb',
245 + 'action' => 'end',
246 + 'reason' => sanitize_key( $reason_data['reason'] ),
247 + );
248 +
249 + $reason_key = $reason_data['reason'] . '_reason';
250 +
251 + if ( ! empty( $reason_data[ $reason_key ] ) )
252 + $body['extra_metadata'] = sanitize_text_field( $reason_data[ $reason_key ] );
253 +
254 + wp_remote_post( 'https://usagetracker.cozmoslabs.com/syncPlugin', array(
255 + 'body' => $body,
256 + 'timeout' => 3,
257 + 'blocking' => false,
258 + ) );
259 +}
260 +
261 +/**
262 + * Store the deactivation reason selected in the popup
263 + */
264 +function wppb_store_deactivation_reason() {
265 +
266 + if ( ! check_ajax_referer( 'wppb_deactivation_reason', 'nonce', false ) )
267 + wp_send_json_error( array( 'message' => __( 'We could not verify your request. Please refresh the page and try again.', 'profile-builder' ) ), 403 );
268 +
269 + if ( ! current_user_can( 'activate_plugins' ) )
270 + wp_send_json_error( array( 'message' => __( 'You do not have permission to deactivate plugins on this site.', 'profile-builder' ) ), 403 );
271 +
272 + $valid_reasons = array(
273 + 'dont_need_it',
274 + 'switched_to_another_plugin',
275 + 'missing_features',
276 + 'did_not_work',
277 + 'temporary_deactivation',
278 + 'other',
279 + 'skip',
280 + );
281 +
282 + $reason = '';
283 +
284 + if ( isset( $_POST['reason'] ) )
285 + $reason = sanitize_key( wp_unslash( $_POST['reason'] ) );
286 +
287 + if ( ! in_array( $reason, $valid_reasons, true ) )
288 + wp_send_json_error( array( 'message' => __( 'We could not save your deactivation feedback. Please try again.', 'profile-builder' ) ), 400 );
289 +
290 + $reason_data = array(
291 + 'reason' => $reason,
292 + );
293 +
294 + if ( $reason === 'switched_to_another_plugin' && ! empty( $_POST['switched_to_another_plugin_reason'] ) )
295 + $reason_data['switched_to_another_plugin_reason'] = sanitize_text_field( wp_unslash( $_POST['switched_to_another_plugin_reason'] ) );
296 +
297 + if ( $reason === 'missing_features' && ! empty( $_POST['missing_features_reason'] ) )
298 + $reason_data['missing_features_reason'] = sanitize_text_field( wp_unslash( $_POST['missing_features_reason'] ) );
299 +
300 + if ( $reason === 'other' && ! empty( $_POST['other_reason'] ) )
301 + $reason_data['other_reason'] = sanitize_text_field( wp_unslash( $_POST['other_reason'] ) );
302 +
303 + wppb_send_deactivation_feedback( $reason_data );
304 +
305 + wp_send_json_success();
306 +}
307 +add_action( 'wp_ajax_wppb_store_deactivation_reason', 'wppb_store_deactivation_reason' );
308 +
309 +/* hook to create pages for out forms when a user press the create pages/setup button */
310 +add_action( 'admin_init', 'wppb_create_form_pages' );
311 +function wppb_create_form_pages(){
312 +
313 + if( !isset( $_GET['page'] ) || $_GET['page'] != 'profile-builder-basic-info' || !isset( $_GET['wppb_create_pages'] ) || $_GET['wppb_create_pages'] != 'true' )
314 + return;
315 +
316 + if( !isset( $_GET['_wpnonce'] ) || !wp_verify_nonce( sanitize_text_field( $_GET['_wpnonce'] ), 'wppb_create_pages' ) )
317 + return;
318 +
319 + if( !current_user_can( 'manage_options' ) )
320 + return;
321 +
322 + $wppb_pages_created = get_option( 'wppb_pages_created' );
323 +
324 + if( empty( $wppb_pages_created ) || ( isset( $_GET['wppb_force_create_pages'] ) && $_GET['wppb_force_create_pages'] === 'true' ) ) {
325 + $register_page = array(
326 + 'post_title' => 'Register',
327 + 'post_content' => '[wppb-register]',
328 + 'post_status' => 'publish',
329 + 'post_type' => 'page'
330 + );
331 + $register_id = wp_insert_post($register_page);
332 +
333 + $edit_page = array(
334 + 'post_title' => 'Edit Profile',
335 + 'post_content' => '[wppb-edit-profile]',
336 + 'post_status' => 'publish',
337 + 'post_type' => 'page'
338 + );
339 + $edit_id = wp_insert_post($edit_page);
340 +
341 + $login_page = array(
342 + 'post_title' => 'Log In',
343 + 'post_content' => '[wppb-login]',
344 + 'post_status' => 'publish',
345 + 'post_type' => 'page'
346 + );
347 + $login_id = wp_insert_post($login_page);
348 +
349 + update_option('wppb_pages_created', 'true' );
350 +
351 + wp_safe_redirect( admin_url('edit.php?s=%5Bwppb-&post_status=all&post_type=page&action=-1&m=0&paged=1&action2=-1') );
352 + }
353 +}
354 +
355 +/**
356 + * Function that prepares labels to pass to the WCK api...we have a quirk in wck api that labels are wrapped
357 + * in %label%...so if we want to have % inside the label for example 25% off...we will have a bad time
358 + * @param string $label
359 + * @return string|string[]
360 + */
361 +function wppb_prepare_wck_labels( $label ){
362 + return trim( str_replace( '%', '&#37;', $label ) );
363 +}
364 +
365 +/**
366 + * Function that returns the reserved meta name list
367 + */
368 +function wppb_get_reserved_meta_name_list( $all_fields, $posted_values ){
369 +
370 + $unique_meta_name_list = array( 'first_name', 'last_name', 'nickname', 'description', 'role' );
371 +
372 + // Default contact methods were removed in WP 3.6. A filter dictates contact methods.
373 + if ( apply_filters( 'wppb_remove_default_contact_methods', get_site_option( 'initial_db_version' ) < 23588 ) ){
374 + $unique_meta_name_list[] = 'aim';
375 + $unique_meta_name_list[] = 'yim';
376 + $unique_meta_name_list[] = 'jabber';
377 + }
378 +
379 + $add_reserved = true;
380 +
381 + // source: https://codex.wordpress.org/Reserved_Terms
382 + $reserved_meta_names = array( 'action', 'attachment', 'attachment_id', 'author', 'author_name', 'calendar', 'cat', 'category', 'category__and', 'category__in', 'category__not_in', 'category_name', 'comments_per_page',
383 + 'comments_popup', 'custom', 'customize_messenger_channel', 'customized', 'cpage', 'day', 'debug', 'embed', 'error', 'exact', 'feed', 'fields', 'hour', 'link_category', 'm', 'map', 'minute', 'monthnum', 'more',
384 + 'name', 'nav_menu', 'nonce', 'nopaging', 'offset', 'order', 'orderby', 'p', 'page', 'page_id', 'paged', 'pagename', 'pb', 'perm', 'post', 'post__in', 'post__not_in', 'post_format', 'post_mime_type',
385 + 'post_status', 'post_tag', 'post_type', 'posts', 'posts_per_archive_page', 'posts_per_page', 'preview', 'robots', 's', 'search', 'second', 'sentence', 'showposts', 'static', 'status', 'subpost',
386 + 'subpost_id', 'tag', 'tag__and', 'tag__in', 'tag__not_in', 'tag_id', 'tag_slug__and', 'tag_slug__in', 'taxonomy', 'tb', 'term', 'terms', 'theme', 'title', 'type', 'types', 'w', 'withcomments', 'withoutcomments', 'year' );
387 +
388 + $args = array(
389 + 'public' => true,
390 + '_builtin' => true
391 + );
392 + $post_types = get_post_types( $args, 'names', 'or' );
393 + $taxonomies = get_taxonomies( $args, 'names', 'or' );
394 +
395 +
396 + /*reserved meta names were added in PB 3.1.2 so to avoid the situation where someone updates an already existing field
397 + with a reserved name and gets an error check if it is an update or new field */
398 + if( !empty( $all_fields ) && !empty($posted_values['id'] ) && !empty($posted_values['meta-name']) ){
399 + foreach( $all_fields as $field ){
400 + if( $field['id'] === $posted_values['id'] && $field['meta-name'] === $posted_values['meta-name'] ){//it is an update
401 + $add_reserved = false;
402 + }
403 + }
404 + }
405 +
406 + if( $add_reserved )
407 + $unique_meta_name_list = array_merge( $unique_meta_name_list, $reserved_meta_names, $post_types, $taxonomies );
408 +
409 + return apply_filters ( 'wppb_unique_meta_name_list', $unique_meta_name_list );
410 +}
411 +
412 +add_action('admin_head', 'wppb_maybe_remove_add_new_button_for_cpt' );
413 +function wppb_maybe_remove_add_new_button_for_cpt() {
414 +
415 + global $pagenow;
416 +
417 + // Registration ('wppb-rf-cpt') and Edit Profile ('wppb-epf-cpt') forms are deliberately excluded: form
418 + // creation is gated on an active paid VERSION at the CPT capability level (see
419 + // wppb_fb_multiple_forms_available() in form-builder/form-builder-licensing.php), not on the LICENSE. Gating
420 + // them here would disable a button an expired-but-paid install may still use, and -- since the capability gate
421 + // makes core skip the button entirely on free -- would inject an empty, label-less stand-in next to the page
422 + // title (no button left to read a label from). The free-tier stand-in comes from
423 + // wppb_fb_enqueue_locked_add_new_button() instead. Same narrowing as wppb_filter_own_post_creation() below.
424 + $target_slugs = [ 'wppb-ul-cpt' ];
425 + $current_slug = '';
426 + $pointer_content = '';
427 +
428 + $correct_page = false;
429 +
430 + if ( $pagenow === 'edit.php' && isset( $_GET['post_type'] ) && in_array( sanitize_text_field( $_GET['post_type'] ), $target_slugs ) ) {
431 + $correct_page = true;
432 + $current_slug = sanitize_text_field( $_GET['post_type'] );
433 + } else if( $pagenow === 'post.php' && isset( $_GET['post'] ) ) {
434 +
435 + $post_type = get_post_type( absint( $_GET['post'] ) );
436 +
437 + if ( in_array( $post_type, $target_slugs ) ) {
438 + $correct_page = true;
439 + $current_slug = $post_type;
440 + }
441 +
442 + }
443 +
444 + if ( $correct_page ) {
445 + $license_status = wppb_get_serial_number_status();
446 +
447 + if( $current_slug === 'wppb-ul-cpt' ) {
448 + if( $license_status == 'missing' ) {
449 + $pointer_content .= '<p>' . sprintf( __( 'Please %1$senter your license key%2$s first, to add new User Listing.', 'profile-builder' ), '<a href="'. admin_url( 'admin.php?page=profile-builder-general-settings' ) .'">', '</a>' ) . '</p>';
450 + } else {
451 + $pointer_content .= '<p>' . sprintf( __( 'You need an active license to add a new User Listing. %1$sRenew%2$s or %3$spurchase a new one%4$s.', 'profile-builder' ), '<a href="https://www.cozmoslabs.com/account/?utm_source=pb-user-listing&utm_medium=client-site&utm_campaign=pb-expired-license">', '</a>', '<a href="https://www.cozmoslabs.com/wordpress-profile-builder/?utm_source=pb-user-listing&utm_medium=client-site&utm_campaign=pb-user-listing-addon#pricing" target="_blank">', '</a>' ) . '</p>';
452 + }
453 + }
454 +
455 + if( $license_status !== 'valid' ) {
456 + wp_enqueue_style('wp-pointer');
457 + wp_enqueue_script('wp-pointer');
458 +
459 + echo '
460 + <script>
461 + jQuery(document).ready(function($) {
462 + let button_text = $(".page-title-action").text();
463 + $(".page-title-action").remove();
464 +
465 + $(".wrap .wp-heading-inline").after(`<a class="page-title-action page-title-action-disabled" style="cursor:pointer;">${button_text}</a>`);
466 +
467 + $(".page-title-action-disabled").on("click", function(e) {
468 + e.preventDefault();
469 +
470 + let pointer_content = '. json_encode( $pointer_content ) .';
471 +
472 + jQuery( this ).pointer({
473 + content: pointer_content,
474 + position: { edge: "right", align: "middle" }
475 + }).pointer("open");
476 + });
477 + });
478 + </script>';
479 + }
480 +
481 + }
482 +
483 + // This shows the Add new button. Since the above action removes it completelty, we can just attempt to show it here
484 + echo '<script>
485 + jQuery(document).ready(function($) {
486 + if( $(".page-title-action").length > 0 ) {
487 + $(".page-title-action").css("display", "inline-flex");
488 + }
489 + });
490 + </script>';
491 +
492 + // Manage fields
493 + if( isset( $_GET['page'] ) && $_GET['page'] === 'manage-fields' ) {
494 + $license_status = wppb_get_serial_number_status();
495 + $pointer_content_cl = '';
496 + $pointer_content_fv = '';
497 + $pointer_content_epaa = '';
498 +
499 + if( $license_status == 'missing' ) {
500 + $pointer_content_cl .= '<p>' . sprintf( __( 'Please %1$senter your license key%2$s first, to use the Conditional Logic feature.', 'profile-builder' ), '<a href="'. admin_url( 'admin.php?page=profile-builder-general-settings' ) .'">', '</a>' ) . '</p>';
501 + $pointer_content_fv .= '<p>' . sprintf( __( 'Please %1$senter your license key%2$s first, to configure Field Visibility options.', 'profile-builder' ), '<a href="'. admin_url( 'admin.php?page=profile-builder-general-settings' ) .'">', '</a>' ) . '</p>';
502 + $pointer_content_epaa .= '<p>' . sprintf( __( 'Please %1$senter your license key%2$s first, to use the Edit Profile Updates Approved by Admin addon feature.', 'profile-builder' ), '<a href="'. admin_url( 'admin.php?page=profile-builder-general-settings' ) .'">', '</a>' ) . '</p>';
503 + } else {
504 + $pointer_content_cl .= '<p>' . sprintf( __( 'You need an active license to configure the Condi tional Logic feature. %1$sRenew%2$s or %3$spurchase a new one%4$s.', 'profile-builder' ), '<a href="https://www.cozmoslabs.com/account/?utm_source=pb-form-fields-conditional&utm_medium=client-site&utm_campaign=pb-expired-license">', '</a>', '<a href="https://www.cozmoslabs.com/wordpress-profile-builder/?utm_source=pb-form-fields-conditional&utm_medium=client-site&utm_campaign=pb-conditional-logic#pricing" target="_blank">', '</a>' ) . '</p>';
505 + $pointer_content_fv .= '<p>' . sprintf( __( 'You need an active license to configure Field Visibility options. %1$sRenew%2$s or %3$spurchase a new one%4$s.', 'profile-builder' ), '<a href="https://www.cozmoslabs.com/account/?utm_source=pb-form-fields-visibility&utm_medium=client-site&utm_campaign=pb-expired-license">', '</a>', '<a href="https://www.cozmoslabs.com/wordpress-profile-builder/?utm_source=pb-form-fields-visibility&utm_medium=client-site&utm_campaign=pb-field-visibility#pricing" target="_blank">', '</a>' ) . '</p>';
506 + $pointer_content_epaa .= '<p>' . sprintf( __( 'You need an active license to use the Edit Profile Updates Approved by Admin addon. %1$sRenew%2$s or %3$spurchase a new one%4$s.', 'profile-builder' ), '<a href="https://www.cozmoslabs.com/account/?utm_source=pb-form-fields-approval-on-edit-profile&utm_medium=client-site&utm_campaign=pb-expired-license">', '</a>', '<a href="https://www.cozmoslabs.com/wordpress-profile-builder/?utm_source=pb-form-fields-approval-on-edit-profile&utm_medium=client-site&utm_campaign=pb-approval-on-edit-profile#pricing" target="_blank">', '</a>' ) . '</p>';
507 + }
508 +
509 + if( $license_status != 'valid' ) {
510 + wp_enqueue_style('wp-pointer');
511 + wp_enqueue_script('wp-pointer');
512 +
513 + echo '
514 + <script>
515 + jQuery(document).ready(function($) {
516 +
517 + $(document).on( "wpbFormMetaLoaded", function(e, meta) {
518 +
519 + wppb_manage_fields_license_invalid( e );
520 +
521 + });
522 +
523 + wppb_manage_fields_license_invalid();
524 +
525 + function wppb_manage_fields_license_invalid(){
526 +
527 + if( $(".row-conditional-logic-enabled").length > 0 ) {
528 +
529 + $(".row-conditional-logic").hide();
530 +
531 + $("#edit_form_conditional-logic-enabled_yes, label[for=conditional-logic-enabled_yes]").on("click", function(e) {
532 + e.preventDefault();
533 + e.stopPropagation();
534 + e.stopImmediatePropagation();
535 +
536 + let pointer_content = '. json_encode( $pointer_content_cl ) .';
537 + let pointer_target = jQuery( this ).parent( ".cozmoslabs-toggle-container" );
538 +
539 + if( e && e.currentTarget && jQuery( e.currentTarget ).hasClass( "cozmoslabs-form-field-label" ) ) {
540 + pointer_target = jQuery( this );
541 + }
542 +
543 + pointer_target.pointer({
544 + content: pointer_content,
545 + position: { edge: "right", align: "middle" }
546 + }).pointer("open");
547 + });
548 + }
549 +
550 + if( $(".row-edit-profile-approved-by-admin").length > 0 ) {
551 +
552 + $("#edit_form_edit-profile-approved-by-admin_yes, label[for=edit-profile-approved-by-admin_yes]").on("click", function(e) {
553 + e.preventDefault();
554 + e.stopPropagation();
555 + e.stopImmediatePropagation();
556 +
557 + let pointer_content = '. json_encode( $pointer_content_epaa ) .';
558 + let pointer_target = jQuery( this ).parent( ".cozmoslabs-toggle-container" );
559 +
560 + if( e && e.currentTarget && jQuery( e.currentTarget ).hasClass( "cozmoslabs-form-field-label" ) ) {
561 + pointer_target = jQuery( this );
562 + }
563 +
564 + pointer_target.pointer({
565 + content: pointer_content,
566 + position: { edge: "right", align: "middle" }
567 + }).pointer("open");
568 + });
569 + }
570 +
571 + if( $(".row-visibility").length > 0 ) {
572 +
573 + $("select#visibility").on("mousedown", function(e) {
574 + e.preventDefault();
575 + e.stopPropagation();
576 + e.stopImmediatePropagation();
577 +
578 + let pointer_content = '. json_encode( $pointer_content_fv ) .';
579 +
580 + jQuery( this ).pointer({
581 + content: pointer_content,
582 + position: { edge: "right", align: "middle" }
583 + }).pointer("open");
584 + });
585 +
586 + }
587 +
588 + if( $(".row-user-role-visibility").length > 0 ) {
589 +
590 + $(".row-user-role-visibility .wck-checkboxes input").attr("disabled", true).css("pointer-events", "none");
591 +
592 + $(".row-user-role-visibility .wck-checkboxes").on("click", function(e) {
593 + e.preventDefault();
594 + e.stopPropagation();
595 + e.stopImmediatePropagation();
596 +
597 + let pointer_content = '. json_encode( $pointer_content_fv ) .';
598 +
599 + jQuery( this ).pointer({
600 + content: pointer_content,
601 + position: { edge: "right", align: "middle" }
602 + }).pointer("open");
603 + });
604 +
605 + }
606 +
607 + if( $(".row-location-visibility").length > 0 ) {
608 +
609 + $(".row-location-visibility .wck-checkboxes input").attr("disabled", true).css("pointer-events", "none");
610 +
611 + $(".row-location-visibility .wck-checkboxes").on("click", function(e) {
612 + e.preventDefault();
613 + e.stopPropagation();
614 + e.stopImmediatePropagation();
615 +
616 + let pointer_content = '. json_encode( $pointer_content_fv ) .';
617 +
618 + jQuery( this ).pointer({
619 + content: pointer_content,
620 + position: { edge: "right", align: "middle" }
621 + }).pointer("open");
622 + });
623 +
624 + }
625 +
626 + }
627 +
628 + });
629 + </script>';
630 + }
631 + }
632 +
633 +}
634 +
635 +function wppb_filter_own_post_creation( $data, $postarr ) {
636 + // Only User Listing still needs a valid license here; RF/EPF free/multiple-forms gating lives in form-builder-licensing.php.
637 + if ( in_array( $data['post_type'], [ 'wppb-ul-cpt' ] ) && empty( $postarr['ID'] ) ) {
638 +
639 + $license_status = wppb_get_serial_number_status();
640 +
641 + if( $license_status != 'valid' ) {
642 + wp_die( 'An active Profile Builder license is required to create new posts of this type.' );
643 + }
644 +
645 + }
646 +
647 + return $data;
648 +}
649 +add_filter( 'wp_insert_post_data', 'wppb_filter_own_post_creation', 10, 2 );
650 +
651 +add_filter( 'wck_update_meta_filter_values_wppb_manage_fields', 'wppb_filter_extra_manage_fields_options', 10, 2 );
652 +function wppb_filter_extra_manage_fields_options( $values, $element_id ) {
653 +
654 + $license_status = wppb_get_serial_number_status();
655 +
656 + if( $license_status == 'valid' )
657 + return $values;
658 +
659 + if( !empty( $values['id'] ) ) {
660 + $manage_fields = get_option( 'wppb_manage_fields', array() );
661 + $existing_field = false;
662 +
663 + if( !empty( $manage_fields ) ) {
664 + foreach( $manage_fields as $field ) {
665 + if( $field['id'] == $values['id'] ) {
666 + $existing_field = $field;
667 + break;
668 + }
669 + }
670 + }
671 +
672 + if( !empty( $existing_field ) ) {
673 +
674 + $target_keys = [
675 + 'visibility',
676 + 'location-visibility',
677 + 'user-role-visibility',
678 + 'conditional-logic-enabled',
679 + 'edit-profile-approved-by-admin',
680 + ];
681 +
682 + foreach( $target_keys as $key ) {
683 + if( !empty( $existing_field[$key] ) ) {
684 + $values[$key] = $existing_field[$key];
685 + }
686 + }
687 +
688 + }
689 +
690 + }
691 +
692 + return $values;
693 +
694 +}
695 +
696 +function wppb_form_builder_transition_admin_notification() {
697 +
698 + if( !current_user_can( 'manage_options' ) )
699 + return;
700 +
701 + /* don't advertise the Form Builder unless it actually loaded */
702 + if( !function_exists( 'wppb_fb_loaded' ) )
703 + return;
704 +
705 + /* initiate the plugin notifications class */
706 + $notifications = WPPB_Plugin_Notifications::get_instance();
707 + /* this must be unique */
708 + $notification_id = 'wppb_form_builder_transition_notification';
709 +
710 + $forms_url = admin_url( 'edit.php?post_type=wppb-rf-cpt' );
711 +
712 + /* Filterable so the documentation link can be pointed at the Form Builder
713 + * article without a code change. */
714 + $docs_url = apply_filters( 'wppb_fb_transition_notice_docs_url', 'https://www.cozmoslabs.com/docs/profile-builder/manage-user-fields/?utm_source=wpbackend&utm_medium=clientsite&utm_content=form_builder_transition_notification&utm_campaign=PBDocs' );
715 +
716 + $notification_message = '<p style="font-size: 15px; margin-top:4px;">' . esc_html__( 'Registration and Edit Profile forms are now built with a drag-and-drop editor: pick fields from the inserter, arrange them on the canvas, and edit each one in place.', 'profile-builder' ) . '</p>';
717 +
718 + $notification_message .= '<p style="font-size: 15px; margin-top:4px;">' . esc_html__( 'Your existing forms and fields carried over automatically, and your live forms keep rendering exactly as before.', 'profile-builder' ) . '</p>';
719 +
720 + $notification_message .= '<p style="font-size: 15px; margin-top:4px;">' . wp_kses_post( sprintf(
721 + /* translators: 1: opening Forms link (HTML), 2: closing Forms link, 3: opening documentation link (HTML), 4: closing documentation link */
722 + __( 'Open %1$sProfile Builder → Forms%2$s to take a look, or %3$sread the documentation%4$s.', 'profile-builder' ),
723 + '<a href="' . esc_url( $forms_url ) . '">',
724 + '</a>',
725 + '<a href="' . esc_url( $docs_url ) . '" target="_blank" rel="noopener noreferrer">',
726 + '</a>'
727 + ) ) . '</p>';
728 +
729 + $pb_icon_url = ( file_exists( WPPB_PLUGIN_DIR . 'assets/images/pb-logo.svg' ) ) ? WPPB_PLUGIN_URL . 'assets/images/pb-logo.svg' : '';
730 + $pb_icon = ( !empty( $pb_icon_url ) ) ? '<img src="' . esc_url( $pb_icon_url ) . '" width="64" height="64" style="float: left; margin: 15px 12px 15px 0; max-width: 100px;" alt="Profile Builder">' : '';
731 +
732 + $message = $pb_icon;
733 + $message .= '<div style="overflow: hidden;">';
734 + $message .= '<h3 style="margin-bottom: 0;">' . esc_html__( 'Introducing the new Profile Builder Form Builder.', 'profile-builder' ) . '</h3>';
735 + $message .= $notification_message;
736 + $message .= '</div>';
737 + $message .= '<a href="' . esc_url( wp_nonce_url( add_query_arg( array( 'wppb_dismiss_admin_notification' => $notification_id ) ), 'wppb_plugin_notice_dismiss' ) ) . '" type="button" class="notice-dismiss"><span class="screen-reader-text">' . esc_html__( 'Dismiss this notice.', 'profile-builder' ) . '</span></a>';
738 +
739 + $notifications->add_marketing_notification( $notification_id, $message, 'wppb-notice notice notice-info', true, array( 'edit.php?post_type=wppb-rf-cpt' ) );
740 +
741 +}
742 +add_action( 'admin_init', 'wppb_form_builder_transition_admin_notification' );
743 +
744 +/**
745 + * Get the Profile Builder Page or Post slug
746 + *
747 + */
748 +function wppb_get_pb_page_post_slug() {
749 + if ( isset( $_GET['post_type'] ) )
750 + $post_type = sanitize_text_field( $_GET['post_type'] );
751 + elseif ( isset( $_GET['post'] ) )
752 + $post_type = get_post_type( (int)$_GET['post'] );
753 + elseif ( isset( $_GET['page'] ) )
754 + $post_type = sanitize_text_field( $_GET['page'] );
755 + else $post_type = '';
756 +
757 + $possible_slugs = array(
758 + 'pb',
759 + 'wppb',
760 + 'profile-builder',
761 + 'user-email-customizer',
762 + 'admin-email-customizer',
763 + 'manage-fields',
764 + 'custom-redirects',
765 + 'profile-user-profile-picture'
766 + );
767 +
768 + if ( !empty( $post_type ) ) {
769 + foreach ( $possible_slugs as $slug ) {
770 + if ( ($post_type === $slug || strpos( $post_type, $slug ) === 0) && strpos($post_type, 'pb_backupbuddy') === false ) {
771 +
772 + return $post_type;
773 +
774 + }
775 + }
776 + }
777 +
778 + return '';
779 +}
780 +
781 +/**
782 + * Insert the PB Admin area Header Banner
783 + *
784 + */
785 +function wppb_insert_page_banner() {
786 + $pb_slug = wppb_get_pb_page_post_slug();
787 +
788 + if ( $pb_slug === 'profile-builder-dashboard' && isset( $_GET['subpage'] ) && $_GET['subpage'] === 'wppb-setup' )
789 + return;
790 +
791 + $page_name = '';
792 + if ( $pb_slug == 'profile-builder-add-ons' )
793 + $page_name = ' Add-Ons';
794 +
795 + if ( !empty( $pb_slug ) )
796 + wppb_output_page_banner($page_name);
797 +
798 +}
799 +add_action( 'in_admin_header', 'wppb_insert_page_banner' );
800 +
801 +/**
802 + * Output the PB Admin area Header Banner content
803 + *
804 + */
805 +function wppb_output_page_banner( $page_name ) {
806 +
807 + $upgrade_button = '<a class="cozmoslabs-banner-link cozmoslabs-upgrade-link" href="https://www.cozmoslabs.com/wordpress-profile-builder/?utm_source=pb-settings&utm_medium=client-site&utm_campaign=pb-header-upsell#pricing" target="_blank">
808 + <img src="'. esc_url(WPPB_PLUGIN_URL) . 'assets/images/upgrade-link-icon.svg" alt="">
809 + Upgrade to PRO
810 + </a>';
811 +
812 + $upgrade_button_basic = '<a class="cozmoslabs-banner-link cozmoslabs-upgrade-link" href="https://www.cozmoslabs.com/wordpress-profile-builder/?utm_source=pb-settings&utm_medium=client-site&utm_campaign=pb-header-upsell#pricing" target="_blank">
813 + <img src="'. esc_url(WPPB_PLUGIN_URL) . 'assets/images/upgrade-link-icon.svg" alt="">
814 + Upgrade to PRO
815 + </a>';
816 +
817 + $support_url = 'https://wordpress.org/support/plugin/profile-builder/';
818 +
819 + $output = '<div class="cozmoslabs-banner">
820 + <div class="cozmoslabs-banner-title">
821 + <img src="'. esc_url(WPPB_PLUGIN_URL) . 'assets/images/pb-logo.svg" alt="">
822 + <h4>Profile Builder'. $page_name .'</h4>
823 + </div>
824 + <div class="cozmoslabs-banner-buttons">
825 + <a class="cozmoslabs-banner-link cozmoslabs-support-link" href="'. $support_url .'" target="_blank">
826 + <img src="'. esc_url(WPPB_PLUGIN_URL) . 'assets/images/support-link-icon.svg" alt="">
827 + Support
828 + </a>
829 +
830 + <a class="cozmoslabs-banner-link cozmoslabs-documentation-link" href="https://www.cozmoslabs.com/docs/profile-builder/?utm_source=pb-settings&utm_medium=client-site&utm_campaign=pb-header-upsell" target="_blank">
831 + <img src="'. esc_url(WPPB_PLUGIN_URL) . 'assets/images/docs-link-icon.svg" alt="">
832 + Documentation
833 + </a>';
834 +
835 + if ( !defined( 'WPPB_PAID_PLUGIN_DIR' ) || ( defined( 'PROFILE_BUILDER_PAID_VERSION' ) && PROFILE_BUILDER_PAID_VERSION === 'dev' ) )
836 + $output .= $upgrade_button;
837 +
838 + // Add Basic version upgrade button (not to account, to plugin purchase page)
839 + if( defined( 'PROFILE_BUILDER' ) && PROFILE_BUILDER == 'Profile Builder Basic' ){
840 + $output .= $upgrade_button_basic;
841 + }
842 +
843 + $output .= ' </div>
844 + </div>';
845 +
846 + echo $output; //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
847 +}
848 +
849 +
850 +/**
851 + * Remove PMS Styles from PB Pages and Posts
852 + *
853 + */
854 +function wppb_maybe_remove_pms_styles() {
855 + if ( !empty( wppb_get_pb_page_post_slug() ) && wp_style_is('pms-style-back-end', 'enqueued') ) {
856 + wp_dequeue_style('pms-style-back-end');
857 + }
858 +}
859 +add_action('admin_enqueue_scripts', 'wppb_maybe_remove_pms_styles', 100);
860 +
861 +
862 +/**
863 + * Output the deactivation confirmation popup on the Plugins page
864 + *
865 + */
866 +function wppb_output_deactivation_popup() {
867 +
868 + if ( defined( 'WPPB_PAID_PLUGIN_DIR' ) )
869 + return;
870 +
871 + $screen = get_current_screen();
872 +
873 + if ( empty( $screen ) )
874 + return;
875 +
876 + $is_plugins_screen = in_array( $screen->base, array( 'plugins', 'plugins-network' ), true ) || in_array( $screen->id, array( 'plugins', 'plugins-network' ), true );
877 +
878 + if ( !$is_plugins_screen )
879 + return;
880 +
881 + ?>
882 + <div id="wppb-deactivation-popup" title="<?php esc_attr_e( 'Before You Go', 'profile-builder' ); ?>" data-plugin="<?php echo esc_attr( WPPB_PLUGIN_BASENAME ); ?>">
883 + <div class="wppb-deactivation-popup-header">
884 + <img src="<?php echo esc_url( WPPB_PLUGIN_URL . 'assets/images/pb-logo.svg' ); ?>" alt="<?php esc_attr_e( 'Profile Builder', 'profile-builder' ); ?>" width="44" height="44">
885 +
886 + <p class="wppb-deactivation-popup-description">
887 + <?php esc_html_e( 'If you have a moment, please share the reason you are deactivating Profile Builder:', 'profile-builder' ); ?>
888 + </p>
889 + </div>
890 +
891 + <form class="wppb-deactivation-popup-form">
892 + <fieldset class="wppb-deactivation-popup-fieldset">
893 + <label class="wppb-deactivation-popup-option">
894 + <input type="radio" name="wppb_deactivation_reason" value="dont_need_it">
895 + <span><?php esc_html_e( 'I no longer need the plugin', 'profile-builder' ); ?></span>
896 + </label>
897 +
898 + <label class="wppb-deactivation-popup-option">
899 + <input type="radio" name="wppb_deactivation_reason" value="switched_to_another_plugin">
900 + <span><?php esc_html_e( 'I found a better plugin', 'profile-builder' ); ?></span>
901 + <input type="text" name="switched_to_another_plugin_reason" class="wppb-deactivation-popup-extra" data-reason="switched_to_another_plugin" placeholder="<?php esc_attr_e( 'Which plugin', 'profile-builder' ); ?>">
902 + </label>
903 +
904 + <label class="wppb-deactivation-popup-option">
905 + <input type="radio" name="wppb_deactivation_reason" value="missing_features">
906 + <span><?php esc_html_e( 'I didn\'t find the feature I need', 'profile-builder' ); ?></span>
907 + <input type="text" name="missing_features_reason" class="wppb-deactivation-popup-extra" data-reason="missing_features" placeholder="<?php esc_attr_e( 'Which feature', 'profile-builder' ); ?>">
908 + </label>
909 +
910 + <label class="wppb-deactivation-popup-option">
911 + <input type="radio" name="wppb_deactivation_reason" value="did_not_work">
912 + <span><?php esc_html_e( 'I couldn\'t get the plugin to work', 'profile-builder' ); ?></span>
913 + </label>
914 +
915 + <label class="wppb-deactivation-popup-option">
916 + <input type="radio" name="wppb_deactivation_reason" value="temporary_deactivation">
917 + <span><?php esc_html_e( 'Temporary deactivation', 'profile-builder' ); ?></span>
918 + </label>
919 +
920 + <label class="wppb-deactivation-popup-option">
921 + <input type="radio" name="wppb_deactivation_reason" value="other">
922 + <span><?php esc_html_e( 'Other', 'profile-builder' ); ?></span>
923 + <input type="text" name="other_reason" class="wppb-deactivation-popup-extra" data-reason="other" placeholder="<?php esc_attr_e( 'Please tell us more', 'profile-builder' ); ?>">
924 + </label>
925 + </fieldset>
926 +
927 + <p class="wppb-deactivation-popup-error"></p>
928 + </form>
929 +
930 + <div class="wppb-deactivation-popup-actions">
931 + <button type="button" class="button button-primary wppb-deactivation-popup-confirm">
932 + <?php esc_html_e( 'Submit & deactivate', 'profile-builder' ); ?>
933 + </button>
934 +
935 + <button type="button" class="button wppb-deactivation-popup-skip">
936 + <?php esc_html_e( 'Skip & deactivate', 'profile-builder' ); ?>
937 + </button>
938 + </div>
939 + </div>
940 + <style>
941 + #wppb-deactivation-popup {
942 + display: none;
943 + }
944 +
945 + .wppb-deactivation-popup-header {
946 + display: flex;
947 + align-items: center;
948 + gap: 16px;
949 + margin-bottom: 20px;
950 + }
951 +
952 + .wppb-deactivation-popup-description {
953 + margin: 0;
954 + }
955 +
956 + .wppb-deactivation-popup-fieldset {
957 + margin: 0;
958 + padding: 0;
959 + border: 0;
960 + }
961 +
962 + .wppb-deactivation-popup-option {
963 + display: block;
964 + margin-bottom: 12px;
965 + }
966 +
967 + .wppb-deactivation-popup-extra {
968 + display: none;
969 + width: 100%;
970 + margin-top: 8px;
971 + }
972 +
973 + .wppb-deactivation-popup-error {
974 + display: none;
975 + color: #b32d2e;
976 + margin: 0px 0px 12px 0px;
977 + }
978 +
979 + .wppb-deactivation-popup-actions {
980 + display: flex;
981 + align-items: center;
982 + justify-content: space-between;
983 + gap: 12px;
984 + }
985 +
986 + .wppb-deactivation-popup-extra.error {
987 + border: 1px solid #b32d2e;
988 + }
989 +
990 + .ui-dialog[aria-describedby="wppb-deactivation-popup"] .ui-dialog-titlebar {
991 + background: transparent;
992 + border: none;
993 + }
994 + </style>
995 + <?php
996 +}
997 +add_action( 'admin_footer', 'wppb_output_deactivation_popup' );
998 +
999 +
1000 +/**
1001 + * Check if current screen is a Profile Builder admin page.
1002 + *
1003 + * @return bool
1004 + */
1005 +function wppb_is_profile_builder_admin_page() {
1006 +
1007 + if ( ! is_admin() )
1008 + return false;
1009 +
1010 + $screen = get_current_screen();
1011 +
1012 + if ( ! $screen )
1013 + return false;
1014 +
1015 + $pb_pages = array(
1016 + 'profile-builder',
1017 + 'profile-builder-dashboard',
1018 + 'profile-builder-basic-info',
1019 + 'profile-builder-general-settings',
1020 + 'profile-builder-add-ons',
1021 + 'manage-fields',
1022 + );
1023 +
1024 + foreach ( $pb_pages as $page ) {
1025 +
1026 + if ( strpos( $screen->id, $page ) !== false )
1027 + return true;
1028 +
1029 + }
1030 +
1031 + if ( ! empty( $screen->post_type ) ) {
1032 + $pb_cpt_pages = array( 'wppb-ul-cpt', 'wppb-rf-cpt', 'wppb-epf-cpt' );
1033 +
1034 + if ( in_array( $screen->post_type, $pb_cpt_pages, true ) )
1035 + return true;
1036 + }
1037 +
1038 + return false;
1039 +}
1040 +
1041 +
1042 +/**
1043 + * Output the popup markup used for documentation links from the admin.
1044 + *
1045 + * @return void
1046 + */
1047 +function wppb_output_docs_link_popup() {
1048 +
1049 + if ( ! wppb_is_profile_builder_admin_page() )
1050 + return;
1051 +
1052 + ?>
1053 + <div id="wppb-docs-link-popup" class="wppb-docs-link-popup" title="<?php echo esc_attr__( 'Need Help?', 'profile-builder' ); ?>" style="display:none;">
1054 + <div class="wppb-docs-link-popup-content">
1055 + <img src="<?php echo esc_url( WPPB_PLUGIN_URL . 'assets/images/pb-logo.svg' ); ?>" alt="<?php esc_attr_e( 'Profile Builder', 'profile-builder' ); ?>" width="44" height="44" class="wppb-docs-link-popup-logo">
1056 + <div>
1057 + <p class="wppb-docs-link-popup-description"><?php esc_html_e( 'If you need a hand with this setting, you can check the documentation or open a support ticket on WordPress.org.', 'profile-builder' ); ?></p>
1058 + <p class="wppb-docs-link-popup-description"><?php esc_html_e( 'We will do our best to help you figure it out.', 'profile-builder' ); ?></p>
1059 + </div>
1060 + </div>
1061 + <div class="wppb-docs-link-popup-actions cozmoslabs-wrap">
1062 + <a href="#" target="_blank" rel="noopener noreferrer" class="button button-primary wppb-docs-link-popup-open-docs"><?php esc_html_e( 'View Documentation', 'profile-builder' ); ?></a>
1063 + <a href="https://wordpress.org/support/plugin/profile-builder/#new-topic-0" target="_blank" rel="noopener noreferrer" class="button button-primary wppb-docs-link-popup-open-wporg"><?php esc_html_e( 'Open Support Ticket', 'profile-builder' ); ?></a>
1064 + </div>
1065 + </div>
1066 + <?php
1067 +}
1068 +add_action( 'admin_footer', 'wppb_output_docs_link_popup' );