Skip to content

Instantly share code, notes, and snippets.

@rocketgeek
Last active January 30, 2025 14:52
Show Gist options
  • Save rocketgeek/fe4af544cb8202007b6f6887e290c5af to your computer and use it in GitHub Desktop.
Save rocketgeek/fe4af544cb8202007b6f6887e290c5af to your computer and use it in GitHub Desktop.
WP-Members 3.5.0 patch files
<?php
/**
Replaces wp-members/includes/admin/tabs/class-wp-members-admin-tab-fields.php
Patches included:
* fixes bug in 3.5.0 that causes radio/multicheckbox textarea input to show on select/multiselect edit view (and vice versa)
* code improvement to clean whitespace from radio/multicheckbox/select/multiselect input values
*/
/**
* WP-Members Admin Functions
*
* Functions to manage the fields tab.
*
* This file is part of the WP-Members plugin by Chad Butler
* You can find out more about this plugin at https://rocketgeek.com
* Copyright (c) 2006-2024 Chad Butler
* WP-Members(tm) is a trademark of butlerblog.com
*
* @package WP-Members
* @author Chad Butler
* @copyright 2006-2024
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit();
}
class WP_Members_Admin_Tab_Fields {
/**
* Creates the fields tab.
*
* @since 3.0.1
* @since 3.3.0 Renamed wpmem_a_fields_tab() to do_tab().
*
* @param string $tab The admin tab being displayed.
* @return string|bool The fields tab, otherwise false.
*/
public static function do_tab( $tab ) {
if ( $tab == 'fields' ) {
// Render the fields tab.
WP_Members_Admin_Tab_Fields::build_settings();
return;
}
}
/**
* Scripts needed for the fields tab.
*
* @since 3.1.8
* @sinec 3.3.0 Renamed wpmem_a_fields_tab_scripts() to enqueue_scripts
*/
public static function enqueue_scripts() {
wp_enqueue_script( 'jquery-ui-sortable' );
}
/**
* Renders the content of the fields tab.
*
* @since 3.1.8
* @since 3.3.0 Renamed from wpmem_a_render_fields_tab() to build_settings().
*
* @global object $wpmem The WP_Members Object.
* @global string $did_update
* @global string $delete_action
*/
public static function build_settings() {
global $wpmem, $did_update, $delete_action;
$wpmem_fields = wpmem_fields();
$edit_meta = sanitize_text_field( wpmem_get( 'field', false, 'get' ) );
$add_meta = sanitize_text_field( wpmem_get( 'add_field', false ) );
if ( 'delete' == $delete_action ) {
$delete_fields = wpmem_sanitize_array( wpmem_get( 'delete' ) );?>
<?php if ( empty( $delete_fields ) ) { ?>
<p><?php _e( 'No fields selected for deletion', 'wp-members' ); ?></p>
<?php } else { ?>
<p><?php _e( 'Are you sure you want to delete the following fields?', 'wp-members' ); ?></p>
<?php foreach ( $delete_fields as $meta ) {
$meta = esc_html( $meta );
echo esc_html( $wpmem->fields[ $meta ]['label'] ) . ' (meta key: ' . $meta . ')<br />';
} ?>
<form name="<?php echo esc_attr( $delete_action ); ?>" id="<?php echo esc_attr( $delete_action ); ?>" method="post" action="<?php echo esc_url( wpmem_admin_form_post_url() ); ?>">
<?php wp_nonce_field( 'wpmem-confirm-delete' ); ?>
<input type="hidden" name="delete_fields" value="<?php echo esc_attr( implode( ",", $delete_fields ) ); ?>" />
<input type="hidden" name="dodelete" value="delete_confirmed" />
<?php submit_button( 'Delete Fields' ); ?>
</form><?php
}
} else {
if ( 'delete_confirmed' == wpmem_get( 'dodelete' ) ) {
check_admin_referer( 'wpmem-confirm-delete' );
$delete_fields = sanitize_text_field( wpmem_get( 'delete_fields', array() ) );
$delete_fields = explode( ",", $delete_fields );
$wpmem_new_fields = array();
foreach ( $wpmem_fields as $field ) {
if ( ! in_array( $field[2], $delete_fields ) ) {
$wpmem_new_fields[] = $field;
}
}
update_option( 'wpmembers_fields', $wpmem_new_fields );
$did_update = esc_html__( 'Fields deleted', 'wp-members' );
}
if ( $did_update ) { ?>
<div id="message" class="updated fade"><p><strong><?php echo $did_update; ?></strong></p></div>
<?php }
if ( $edit_meta || $add_meta ) {
$mode = ( $edit_meta ) ? sanitize_text_field( wpmem_get( 'mode', false, 'get' ) ) : 'add';
self::build_field_edit( $mode, $wpmem_fields, $edit_meta );
} else {
self::build_field_table();
} ?>
<h3><span><?php _e( 'Need help?', 'wp-members' ); ?></span></h3>
<div class="inside">
<strong><i><a href="https://rocketgeek.com/plugins/wp-members/docs/plugin-settings/fields/" target="_blank"><?php _e( 'Field Manager Documentation', 'wp-members' ); ?></a></i></strong>
</div>
<?php
}
}
/**
* Function to dispay the add/edit field form.
*
* @since 2.8
* @since 3.1.8 Changed name from wpmem_a_field_edit().
* @since 3.3.0 Changed name from wpmem_a_render_fields_tab_field_edit() to build_field_edit().
*
* @global object $wpmem The WP_Members Object.
* @param string $mode The mode for the function (edit|add)
* @param array|null $wpmem_fields The array of fields
* @param string|null $field The field being edited
*/
public static function build_field_edit( $mode, $wpmem_fields, $meta_key ) {
global $wpmem;
$fields = wpmem_fields();
if ( $mode == 'edit' ) {
$field = $fields[ $meta_key ];
} else {
$field['checkbox_label'] = ''; // fixes unset variable at 308/309 since $field would not be set.
}
$form_action = ( $mode == 'edit' ) ? 'editfieldform' : 'addfieldform';
$span_optional = '<span class="description">' . esc_html__( '(optional)', 'wp-members' ) . '</span>';
$span_required = '<span class="req">' . esc_html__( '(required)', 'wp-members' ) . '</span>';
$form_submit = array( 'mode' => $mode );
if ( isset( $_GET['field'] ) ) {
$form_submit['field'] = $meta_key;
} ?>
<h3 class="title"><?php ( $mode == 'edit' ) ? _e( 'Edit Field', 'wp-members' ) : _e( 'Add a Field', 'wp-members' ); ?></h3>
<form name="<?php echo $form_action; ?>" id="<?php echo $form_action; ?>" method="post" action="<?php echo wpmem_admin_form_post_url( $form_submit ); ?>">
<?php wp_nonce_field( 'wpmem_add_field' ); ?>
<ul>
<li>
<label><?php _e( 'Field Label', 'wp-members' ); ?> <?php echo $span_required; ?></label>
<input type="text" name="add_name" value="<?php echo ( $mode == 'edit' ) ? $field['label'] : false; ?>" required />
<?php _e( 'The name of the field as it will be displayed to the user.', 'wp-members' ); ?>
</li>
<li>
<label><?php _e( 'Meta Key', 'wp-members' ); ?> <?php echo $span_required; ?></label>
<?php if ( $mode == 'edit' ) {
echo "<span>$meta_key</span>"; ?>
<input type="hidden" name="add_option" value="<?php echo $meta_key; ?>" required />
<?php } else { ?>
<input type="text" name="add_option" value="" />
<?php _e( 'The database meta value for the field. It must be unique and contain no spaces (underscores are ok).', 'wp-members' ); ?>
<?php } ?>
</li>
<li>
<label><?php _e( 'Field Type', 'wp-members' ); ?></label>
<?php if ( $mode == 'edit' ) {
echo '<span>' . $field['type'] . '</span>'; ?>
<input type="hidden" name="add_type" value="<?php echo $field['type']; ?>" />
<?php } else { ?>
<select name="add_type" id="wpmem_field_type_select">
<option value="text"><?php _e( 'text', 'wp-members' ); ?></option>
<option value="email"><?php _e( 'email', 'wp-members' ); ?></option>
<option value="textarea"><?php _e( 'textarea', 'wp-members' ); ?></option>
<option value="checkbox"><?php _e( 'checkbox', 'wp-members' ); ?></option>
<option value="multicheckbox"><?php _e( 'multiple checkbox', 'wp-members' ); ?></option>
<option value="select"><?php _e( 'select (dropdown)', 'wp-members' ); ?></option>
<option value="multiselect"><?php _e( 'multiple select', 'wp-members' ); ?></option>
<option value="radio"><?php _e( 'radio group', 'wp-members' ); ?></option>
<option value="password"><?php _e( 'password', 'wp-members' ); ?></option>
<option value="image"><?php _e( 'image', 'wp-members' ); ?></option>
<option value="file"><?php _e( 'file', 'wp-members' ); ?></option>
<option value="url"><?php _e( 'url', 'wp-members' ); ?></option>
<option value="number"><?php _e( 'number', 'wp-members' ); ?></option>
<option value="date"><?php _e( 'date', 'wp-members' ); ?></option>
<option value="timestamp"><?php _e( 'timestamp', 'wp-members' ); ?></option>
<option value="hidden"><?php _e( 'hidden', 'wp-members' ); ?></option>
<?php if ( $wpmem->enable_products ) { ?>
<option value="membership"><?php _e( 'membership', 'wp-members' ); ?></option>
<?php } ?>
</select>
<?php } ?>
</li>
<li>
<label><?php _e( 'Display?', 'wp-members' ); ?></label>
<?php if ( 'username' != $meta_key && 'user_email' != $meta_key ) { ?>
<input type="checkbox" name="add_display" value="y" <?php echo ( $mode == 'edit' ) ? checked( true, $field['register'] ) : false; ?> />
<?php } else { ?>
<span><?php _e( 'This field is always displayed', 'wp-members' ); ?></span>
<input type="hidden" name="add_display" value="y" />
<?php } ?>
</li>
<li>
<label><?php _e( 'Required?', 'wp-members' ); ?></label>
<?php if ( 'username' != $meta_key && 'user_email' != $meta_key ) { ?>
<input type="checkbox" name="add_required" value="y" <?php echo ( $mode == 'edit' ) ? checked( true, $field['required'] ) : false; ?> />
<?php } else { ?>
<span><?php _e( 'This field is always required', 'wp-members' ); ?></span>
<input type="hidden" name="add_required" value="y" />
<?php } ?>
</li>
<!--<div id="wpmem_allowhtml">
<li>
<label><?php //_e( 'Allow HTML?', 'wp-members' ); ?></label>
<input type="checkbox" name="add_html" value="y" <?php //echo ( $mode == 'edit' ) ? checked( true, $field['html'] ) : false; ?> />
</li>
</div>-->
<?php
/**
@todo add default value entry for field properties.
if ( $mode == 'add' || ( $mode == 'edit' && ( in_array( $field['type'], array( 'text', 'number', 'date' ) ) ) ) ) {
echo ( $mode == 'add' ) ? '<div id="wpmem_default_value">' : '';
<li>
<label><?php _e( 'Default value', 'wp-members' ); ?></label>
<input type="text" name="add_default_value" value="<?php echo ( $mode == 'edit' ) ? ( isset( $field['default_value'] ) ? $field['default_value'] : false ) : false; ?>" /> <?php echo __( 'This will pre-populate the field with a default value. Leave empty if no default value is desired', 'wp-members' ) . ' ' . $span_optional; ?>
</li>
echo ( $mode == 'add' ) ? '</div>' : '';
}
*/ ?>
<?php if ( $mode == 'add' || ( $mode == 'edit' && ( in_array( $field['type'], array( 'text', 'password', 'email', 'url', 'number', 'date', 'textarea', 'timestamp' ) ) ) ) ) { ?>
<?php echo ( $mode == 'add' ) ? '<div id="wpmem_placeholder">' : ''; ?>
<li>
<label><?php _e( 'Placeholder', 'wp-members' ); ?></label>
<input type="text" name="add_placeholder" value="<?php echo ( $mode == 'edit' ) ? ( isset( $field['placeholder'] ) ? $field['placeholder'] : false ) : false; ?>" /> <?php echo $span_optional; ?>
</li>
<?php echo ( $mode == 'add' ) ? '</div>' : ''; ?>
<?php } ?>
<?php if ( $mode == 'add' || ( $mode == 'edit' && ( in_array( $field['type'], array( 'text', 'password', 'email', 'url', 'date', 'timestamp' ) ) ) ) ) { ?>
<?php echo ( $mode == 'add' ) ? '<div id="wpmem_pattern">' : ''; ?>
<li>
<label><?php _e( 'Pattern', 'wp-members' ); ?></label>
<input type="text" name="add_pattern" value="<?php echo ( $mode == 'edit' ) ? ( isset( $field['pattern'] ) ? $field['pattern'] : false ) : false; ?>" /> <?php echo $span_optional; ?>
</li>
<?php echo ( $mode == 'add' ) ? '</div>' : ''; ?>
<?php } ?>
<?php if ( $mode == 'add' || ( $mode == 'edit' && ( in_array( $field['type'], array( 'text', 'password', 'email', 'url', 'number', 'date', 'timestamp' ) ) ) ) ) { ?>
<?php echo ( $mode == 'add' ) ? '<div id="wpmem_title">' : ''; ?>
<li>
<label><?php _e( 'Title', 'wp-members' ); ?></label>
<input type="text" name="add_title" value="<?php echo ( $mode == 'edit' ) ? ( isset( $field['title'] ) ? $field['title'] : false ) : false; ?>" /> <?php echo $span_optional; ?>
</li>
<?php echo ( $mode == 'add' ) ? '</div>' : ''; ?>
<?php } ?>
<?php if ( $mode == 'add' || ( $mode == 'edit' && ( in_array( $field['type'], array( 'timestamp' ) ) ) ) ) { ?>
<?php echo ( $mode == 'add' ) ? '<div id="wpmem_date_format">' : ''; ?>
<li>
<label><?php _e( 'PHP Date Format', 'wp-members' ); ?></label>
<input type="text" name="add_timestamp_display" value="<?php echo ( $mode == 'edit' ) ? ( isset( $field['timestamp_display'] ) ? $field['timestamp_display'] : false ) : false; ?>" /> <?php echo $span_optional; ?>
</li>
<?php echo ( $mode == 'add' ) ? '</div>' : ''; ?>
<?php } ?>
<?php if ( $mode == 'add' || ( $mode == 'edit' && ( in_array( $field['type'], array( 'number', 'date' ) ) ) ) ) { ?>
<?php echo ( $mode == 'add' ) ? '<div id="wpmem_min_max">' : ''; ?>
<li>
<label><?php _e( 'Minimum Value', 'wp-members' ); ?></label>
<input type="text" name="add_min" value="<?php echo ( $mode == 'edit' ) ? ( isset( $field['min'] ) ? $field['min'] : false ) : false; ?>" /> <?php echo $span_optional; ?>
</li>
<li>
<label><?php _e( 'Maximum Value', 'wp-members' ); ?></label>
<input type="text" name="add_max" value="<?php echo ( $mode == 'edit' ) ? ( isset( $field['max'] ) ? $field['max'] : false ) : false; ?>" /> <?php echo $span_optional; ?>
</li>
<?php echo ( $mode == 'add' ) ? '</div>' : ''; ?>
<?php } ?>
<?php if ( $mode == 'add' || ( $mode == 'edit' && ( in_array( $field['type'], array( 'textarea' ) ) ) ) ) { ?>
<?php echo ( $mode == 'add' ) ? '<div id="wpmem_rows_cols">' : ''; ?>
<li>
<label><?php _e( 'Rows', 'wp-members' ); ?></label>
<input type="number" name="add_rows" value="<?php echo ( $mode == 'edit' ) ? ( isset( $field['rows'] ) ? $field['rows'] : false ) : false; ?>" /> <?php echo $span_optional; ?>
</li>
<li>
<label><?php _e( 'Columns', 'wp-members' ); ?></label>
<input type="number" name="add_cols" value="<?php echo ( $mode == 'edit' ) ? ( isset( $field['cols'] ) ? $field['cols'] : false ) : false; ?>" /> <?php echo $span_optional; ?>
</li>
<?php echo ( $mode == 'add' ) ? '</div>' : ''; ?>
<?php } ?>
<?php if ( $mode == 'add' || ( $mode == 'edit' && ( $field['type'] == 'file' || $field['type'] == 'image' ) ) ) { ?>
<?php echo ( $mode == 'add' ) ? '<div id="wpmem_file_info">' : ''; ?>
<li>
<label><?php _e( 'Accepted file types:', 'wp-members' ); ?></label>
<input type="text" name="add_file_value" value="<?php echo ( $mode == 'edit' && ( $field['type'] == 'file' || $field['type'] == 'image' ) ) ? $field['file_types'] : false; ?>" />
</li>
<li>
<label>&nbsp;</label>
<span class="description"><?php _e( 'Accepted file types should be set like this: jpg|jpeg|png|gif', 'wp-members' ); ?></span>
</li>
<?php echo ( $mode == 'add' ) ? '</div>' : ''; ?>
<?php } ?>
<?php if ( $mode == 'add' || ( $mode == 'edit' && $field['type'] == 'checkbox' ) ) { ?>
<?php echo ( $mode == 'add' ) ? '<div id="wpmem_checkbox_info">' : ''; ?>
<li>
<label><?php _e( 'Checked by default?', 'wp-members' ); ?></label>
<input type="checkbox" name="add_checked_default" value="y" <?php echo ( $mode == 'edit' && $field['type'] == 'checkbox' ) ? checked( true, $field['checked_default'] ) : false; ?> />
</li>
<li>
<label><?php _e( 'HTML label position', 'wp-members' ); ?></label>
<select name="add_checkbox_label">
<option value="0" <?php selected( $field['checkbox_label'], 0 ); ?>><?php _e( 'Before the input tag', 'wp-members' ); ?></option>
<option value="1" <?php selected( $field['checkbox_label'], 1 ); ?>><?php _e( 'After the input tag', 'wp-members' ); ?></option>
</select> <span class="description"><?php _e( 'Selecting "after" will generally display the label to the right of the checkbox', 'wp-members' ); ?></span>
</li>
<li>
<label><?php _e( 'Stored value if checked:', 'wp-members' ); ?> <span class="req"><?php _e( '(required)', 'wp-members' ); ?></span></label>
<input type="text" name="add_checked_value" id="add_checked_value" value="<?php echo ( $mode == 'edit' && $field['type'] == 'checkbox' ) ? $field['checked_value'] : false; ?>" />
</li>
<?php echo ( $mode == 'add' ) ? '</div>' : ''; ?>
<?php }
if ( isset( $field['type'] ) ) {
$additional_settings = ( $field['type'] == 'select' || $field['type'] == 'multiselect' || $field['type'] == 'multicheckbox' || $field['type'] == 'radio' ) ? true : false;
$delimiter_settings = ( $field['type'] == 'multiselect' || $field['type'] == 'multicheckbox' ) ? true : false;
}
if ( $mode == 'add' || ( $mode == 'edit' && $additional_settings ) ) { ?>
<?php echo ( $mode == 'add' ) ? '<div id="wpmem_dropdown_info">' : ''; ?>
<?php if ( $mode == 'add' || ( $mode == 'edit' && $delimiter_settings ) ) {
echo ( $mode == 'add' ) ? '<div id="wpmem_delimiter_info">' : '';
if ( isset( $field['delimiter'] ) && ( "|" == $field['delimiter'] || "," == $field['delimiter'] ) ) {
$delimiter = $field['delimiter'];
} else {
$delimiter = "|";
}
?>
<li>
<label><?php _e( 'Stored values delimiter:', 'wp-members' ); ?></label>
<select name = "add_delimiter_value">
<option value="|" <?php selected( '|', $delimiter ); ?>>pipe "|"</option>
<option value="," <?php selected( ',', $delimiter ); ?>>comma ","</option>
</select>
</li>
<?php echo ( $mode == 'add' ) ? '</div>' : '';
} ?>
<?php if ( $mode == 'add' || ( $mode == 'edit' && ( $field['type'] == 'select' || $field['type'] == 'multiselect' ) ) ) { ?>
<li>
<label style="vertical-align:top"><?php _e( 'Values (Displayed|Stored):', 'wp-members' ); ?> <?php echo $span_required; ?></label>
<textarea name="add_dropdown_value" id="add_dropdown_value" rows="5" cols="40"><?php
// Accomodate editing the current dropdown values or create dropdown value example.
if ( $mode == 'edit' ) {
for ( $row = 0; $row < count( $field['values'] ); $row++ ) {
// If the row contains commas (i.e. 1,000-10,000), wrap in double quotes.
if ( strstr( $field['values'][ $row ], ',' ) ) {
echo '"' . $field['values'][ $row ]; echo ( $row == count( $field['values'] )- 1 ) ? '"' : "\",\n";
} else {
echo $field['values'][ $row ]; echo ( $row == count( $field['values'] )- 1 ) ? "" : ",\n";
} }
} else { ?>
---- Select One ----|,
Choice One|choice_one,
"1,000|one_thousand",
"1,000-10,000|1,000-10,000",
Last Row|last_row
<?php } ?></textarea>
</li>
<?php } ?>
<?php if ( $mode == 'add' || ( $mode == 'edit' && ( $field['type'] == 'radio' || $field['type'] == 'multicheckbox' ) ) ) { ?>
<li>
<label style="vertical-align:top"><?php _e( 'Values (Displayed|Stored):', 'wp-members' ); ?> <?php echo $span_required; ?></label>
<textarea name="add_radio_value" id="add_radio_value" rows="5" cols="40"><?php
// Accomodate editing the current radio values or create radio value example.
if ( $mode == 'edit' ) {
for ( $row = 0; $row < count( $field['values'] ); $row++ ) {
// If the row contains commas (i.e. 1,000-10,000), wrap in double quotes.
if ( strstr( $field['values'][ $row ], ',' ) ) {
echo '"' . $field['values'][ $row ]; echo ( $row == count( $field['values'] )- 1 ) ? '"' : "\",\n";
} else {
echo $field['values'][ $row ]; echo ( $row == count( $field['values'] )- 1 ) ? "" : ",\n";
} }
} else { ?>
Choice One|choice_one,
"1,000|one_thousand",
"1,000-10,000|1,000-10,000",
Last Row|last_row
<?php } ?></textarea>
</li>
<?php } ?>
<li>
<label>&nbsp;</label>
<span class="description"><?php _e( 'Options should be Option Name|option_value,', 'wp-members' ); ?></span>
</li>
<li>
<label>&nbsp;</label>
<span class="description"><a href="https://rocketgeek.com/plugins/wp-members/docs/registration/choosing-fields/" target="_blank"><?php _e( 'Visit plugin site for more information', 'wp-members' ); ?></a></span>
</li>
<?php echo ( $mode == 'add' ) ? '</div>' : ''; ?>
<?php } ?>
<?php if ( $mode == 'add' || ( $mode == 'edit' && $field['type'] == 'hidden' ) ) { ?>
<?php echo ( $mode == 'add' ) ? '<div id="wpmem_hidden_info">' : ''; ?>
<li>
<label><?php _e( 'Value', 'wp-members' ); ?> <?php echo $span_required; ?></label>
<input type="text" name="add_hidden_value" id="add_hidden_value" value="<?php echo ( $mode == 'edit' && $field['type'] == 'hidden' ) ? $field['value'] : ''; ?>" />
</li>
<?php echo ( $mode == 'add' ) ? '</div>' : ''; ?>
<?php } ?>
</ul><br />
<?php if ( $mode == 'edit' ) { ?><input type="hidden" name="field_arr" value="<?php echo $meta_key; ?>" /><?php } ?>
<?php if ( 'add' == $mode ) {
$ids = array();
foreach ( $fields as $f ) {
$ids[] = $f[0];
}
sort( $ids );
$field_order_id = end( $ids ) + 1;
} else {
$field_order_id = $field[0];
} ?>
<input type="hidden" name="add_order_id" value="<?php echo intval( $field_order_id ); ?>" />
<input type="hidden" name="wpmem_admin_a" value="<?php echo ( $mode == 'edit' ) ? 'edit_field' : 'add_field'; ?>" />
<?php $text = ( $mode == 'edit' ) ? esc_html__( 'Save Changes', 'wp-members' ) : esc_html__( 'Add Field', 'wp-members' ); ?>
<?php submit_button( $text ); ?>
<p><a href="<?php echo esc_url( add_query_arg( array( 'page' => 'wpmem-settings', 'tab' => 'fields' ), get_admin_url() . 'options-general.php' ) ); ?>">&laquo; <?php esc_html_e( 'Return to Fields Table', 'wp-members' ); ?></a></p>
</form><?php
}
/**
* Function to display the table of fields in the field manager tab.
*
* @since 2.8.0
* @since 3.1.8 Changed name from wpmem_a_field_table().
* @since 3.3.0 Changed namme from wpmem_a_render_fields_tab_field_table() to build_field_table().
*
* @global object $wpmem
*/
public static function build_field_table() {
global $wpmem;
$wpmem_ut_fields_skip = array( 'username', 'user_email', 'confirm_email', 'password', 'confirm_password' );
$wpmem_ut_fields = get_option( 'wpmembers_utfields' );
$wpmem_us_fields_skip = array( 'username', 'user_email', 'confirm_email', 'password', 'confirm_password' );
$wpmem_us_fields = get_option( 'wpmembers_usfields' );
if ( wpmem_is_woo_active() ) {
if ( 1 == $wpmem->woo->add_checkout_fields ) {
$wpmem_wc_checkout_skip = array_merge( rktgk_wc_checkout_fields(), array( 'username', 'user_login', 'user_email', 'confirm_email', 'password', 'confirm_password' ) );
$wpmem_wc_checkout_fields = get_option( 'wpmembers_wcchkout_fields' );
}
if ( 1 == $wpmem->woo->add_my_account_fields ) {
$wpmem_wc_acct_skip = array_merge( rktgk_wc_checkout_fields(), array( 'username', 'user_login', 'user_email', 'confirm_email', 'password', 'confirm_password' ) );
$wpmem_wc_acct_fields = get_option( 'wpmembers_wcacct_fields' );
}
if ( 1 == $wpmem->woo->add_update_fields ) {
$wpmem_wc_update_skip = array_merge( rktgk_wc_checkout_fields(), array( 'username', 'user_login', 'user_email', 'confirm_email', 'password', 'confirm_password' ) );
$wpmem_wc_update_fields = get_option( 'wpmembers_wcupdate_fields' );
}
}
$wpmem_fields = get_option( 'wpmembers_fields', array() );
foreach ( $wpmem_fields as $key => $field ) {
// @todo - transitional until new array keys (so maybe never, or maybe 3.5.0)
if ( is_numeric( $key ) ) {
// Adjust for profile @todo - temporary until new array keys.
if ( isset( $field['profile'] ) ) {
$profile = ( true == $field['profile'] ) ? 'y' : 'n';
} else {
$profile = $field[4];
}
$meta = $field[2];
$ut_checked = ( ( $wpmem_ut_fields ) && ( array_key_exists( $meta, $wpmem_ut_fields ) ) ) ? $meta : false;
$us_checked = ( ( $wpmem_us_fields ) && ( array_key_exists( $meta, $wpmem_us_fields ) ) ) ? $meta : false;
if ( wpmem_is_woo_active() ) {
if ( 1 == $wpmem->woo->add_checkout_fields ) {
$wc_chkout_checked = ( ( $wpmem_wc_checkout_fields ) && ( in_array( $meta, $wpmem_wc_checkout_fields ) ) ) ? $meta : false;
}
if ( 1 == $wpmem->woo->add_my_account_fields ) {
$wc_acct_checked = ( ( $wpmem_wc_acct_fields ) && ( in_array( $meta, $wpmem_wc_acct_fields ) ) ) ? $meta : false;
}
if ( 1 == $wpmem->woo->add_update_fields ) {
$wc_update_checked = ( ( $wpmem_wc_update_fields ) && ( in_array( $meta, $wpmem_wc_update_fields ) ) ) ? $meta : false;
}
}
$item['order'] = $field[0];
$item['label'] = $field[1];
$item['meta'] = $meta;
$item['type'] = $field[3];
$item['display'] = ( 'user_email' != $meta && 'username' != $meta ) ? wpmem_form_field( array(
'name' => "wpmem_fields_display[]",
'type' => 'checkbox',
'value' => $meta,
'compare' => ( ( 'y' == $field[4] ) ? $meta : false )
) ) : '';
$item['req'] = ( 'user_email' != $meta && 'username' != $meta ) ? wpmem_form_field( array(
'name' => "wpmem_fields_required[]",
'type' => 'checkbox',
'value' => $meta,
'compare' => ( ( 'y' == $field[5] ) ? $meta : false )
) ) : '';
$item['profile'] = ( 'user_email' != $meta && 'username' != $meta && 'password' != $meta && 'confirm_password' != $meta ) ? wpmem_form_field( array(
'name' => "wpmem_fields_profile[]",
'type' => "checkbox",
'value' => $meta,
'compare' => ( ( 'y' == $profile ) ? $meta : false )
) ) : '';
$item['userscrn'] = ( ! in_array( $meta, $wpmem_ut_fields_skip ) ) ? wpmem_form_field( array(
'name' => "wpmem_fields_uscreen[" . $meta . "]",
'type' => 'checkbox',
'value' => $field[1],
'compare' => ( ( $ut_checked == $meta ) ? $field[1] : false )
) ) : '';
$item['usearch'] = ( ! in_array( $meta, $wpmem_us_fields_skip ) ) ? wpmem_form_field( array(
'name' => "wpmem_fields_usearch[" . $meta . "]",
'type' => 'checkbox',
'value' => $field[1],
'compare' => ( ( $us_checked == $meta ) ? $field[1] : false )
) ) : '';
if ( wpmem_is_woo_active() ) {
//if ( wpmem_is_enabled( 'woo/add_checkout_fields' ) ) {
if ( 1 == $wpmem->woo->add_checkout_fields ) {
$item['wcchkout'] = ( ! in_array( $meta, $wpmem_wc_checkout_skip ) && $item['type'] != 'file' && $item['type'] != 'image' ) ? wpmem_form_field( array(
'name' => "wpmem_fields_wcchkout[]",
'type' => 'checkbox',
'value' => $meta,
'compare' => ( ( $wc_chkout_checked == $meta ) ? $meta : false )
) ) : '';
}
//if ( wpmem_is_enabled( 'woo/add_my_account_fields' ) ) {
if ( 1 == $wpmem->woo->add_my_account_fields ) {
$item['wcaccount'] = ( ! in_array( $meta, $wpmem_wc_acct_skip ) && $item['type'] != 'file' && $item['type'] != 'image' ) ? wpmem_form_field( array(
'name' => "wpmem_fields_wcaccount[]",
'type' => 'checkbox',
'value' => $meta,
'compare' => ( ( $wc_acct_checked == $meta ) ? $meta : false )
) ) : '';
}
//if ( wpmem_is_enabled( 'woo/add_update_fields' ) ) {
if ( 1 == $wpmem->woo->add_update_fields ) {
$item['wcupdate'] = ( ! in_array( $meta, $wpmem_wc_update_skip ) && $item['type'] != 'file' && $item['type'] != 'image' ) ? wpmem_form_field( array(
'name' => "wpmem_fields_wcupdate[]",
'type' => 'checkbox',
'value' => $meta,
'compare' => ( ( $wc_update_checked == $meta ) ? $meta : false )
) ) : '';
}
}
$item['edit'] = '<span class="dashicons dashicons-move" title="' . esc_html__( 'Drag and drop to reorder fields', 'wp-members' ) . '"></span>';
$field_items[] = $item;
}
}
$extra_user_screen_items = array(
'user_registered' => esc_html__( 'Registration Date', 'wp-members' ),
'_wpmem_user_confirmed' => esc_html__( 'Confirmed', 'wp-members' ),
'active' => esc_html__( 'Activated', 'wp-members' ),
'wpmem_reg_ip' => esc_html__( 'Registration IP', 'wp-members' ),
'exp_type' => esc_html__( 'Subscription Type', 'wp-members' ),
'expires' => esc_html__( 'Expires', 'wp-members' ),
'user_id' => esc_html__( 'User ID', 'wp-members' ),
);
foreach ( $extra_user_screen_items as $key => $item ) {
$ut_checked = ( ( $wpmem_ut_fields ) && ( in_array( $item, $wpmem_ut_fields ) ) ) ? $item : '';
if ( 'user_id' == $key
|| 'user_registered' == $key
|| 'wpmem_reg_ip' == $key
|| ( '_wpmem_user_confirmed' == $key && 1 == $wpmem->act_link )
|| ( 'active' == $key && 1 == $wpmem->mod_reg )
|| defined( 'WPMEM_EXP_MODULE' ) && $wpmem->use_exp == 1 && ( 'exp_type' == $key || 'expires' == $key ) ) {
$user_screen_items[ $key ] = array( 'label' => esc_html__( $item, 'wp-members' ), 'meta' => $key,
'userscrn' => wpmem_form_field( "wpmem_fields_uscreen[{$key}]", 'checkbox', $item, $ut_checked ),
);
}
}
foreach ( $user_screen_items as $screen_item ) {
$field_items[] = array(
'label' => $screen_item['label'],
'meta' => $screen_item['meta'],
'type' => '',
'display' => '',
'req' => '',
'profile' => '',
'userscrn' => $screen_item['userscrn'],
'usearch' => '',
'edit' => '',
'sort' => '',
);
}
$table = new WP_Members_Fields_Table();
$heading = esc_html__( 'Manage Fields', 'wp-members' );
//$description = esc_html__( 'Displaying fields for:', 'wp-members' );
//$which_form = $wpmem->form_tags[ $wpmem->admin->current_form ];
echo '<div class="wrap">';
printf( '<h3 class="title">%s</h3>', $heading );
//printf( '<p>%s <strong>%s</strong></p>', $description, $which_form );
printf( '<form name="updatefieldform" id="updatefieldform" method="post" action="%s">', wpmem_admin_form_post_url() );
$table->items = $field_items;
$table->prepare_items();
$table->display();
echo '</form>';
echo '</div>';
}
/**
* Javascript to ID the fields table and add curser style to rows.
*
* @since 3.1.8
* @since 3.3.0 Changed from wpmem_bulk_fields_actions() to bulk_actions().
*/
public static function bulk_actions() {
if ( 'wpmem-settings' == wpmem_get( 'page', false, 'get' ) && 'fields' == wpmem_get( 'tab', false, 'get' ) ) {
?><script type="text/javascript">(function($){$(document).ready(function(){$("table").attr("id","wpmem-fields");});})(jQuery);</script><?php
}
}
/**
* Updates fields.
*
* Derived from wpmem_update_fields()
*
* @since 3.1.8
* @since 3.3.0 Changed from wpmem_admin_fields_update() to update().
* @since 3.3.9 load_fields() moved to forms object class.
*
* @global object $wpmem
* @global string $did_update
* @global string $add_field_err_msg The add field error message
*/
public static function update() {
global $wpmem, $did_update, $delete_action;
if ( 'wpmem-settings' == wpmem_get( 'page', false, 'get' ) && 'fields' == wpmem_get( 'tab', false, 'get' ) ) {
// Get the current fields.
$wpmem_fields = get_option( 'wpmembers_fields' );
$action = sanitize_text_field( wpmem_get( 'action', false ) );
$action = ( -1 == $action ) ? sanitize_text_field( wpmem_get( 'action2' ) ) : $action;
$delete_action = false;
if ( 'save' == $action ) {
// Check nonce.
check_admin_referer( 'bulk-settings_page_wpmem-settings' );
// Update user table fields.
update_option( 'wpmembers_utfields', wpmem_sanitize_array( wpmem_get( 'wpmem_fields_uscreen', array() ) ) );
// Update user search fields.
update_option( 'wpmembers_usfields', wpmem_sanitize_array( wpmem_get( 'wpmem_fields_usearch', array() ) ) );
if ( wpmem_is_woo_active() ) {
if ( 1 == $wpmem->woo->add_checkout_fields ) {
update_option( 'wpmembers_wcchkout_fields', wpmem_sanitize_array( wpmem_get( 'wpmem_fields_wcchkout', array() ) ) );
}
if ( 1 == $wpmem->woo->add_my_account_fields ) {
update_option( 'wpmembers_wcacct_fields', wpmem_sanitize_array( wpmem_get( 'wpmem_fields_wcaccount', array() ) ) );
}
if ( 1 == $wpmem->woo->add_update_fields ) {
update_option( 'wpmembers_wcupdate_fields', wpmem_sanitize_array( wpmem_get( 'wpmem_fields_wcupdate', array() ) ) );
}
}
$wpmem_fields_display_post = wpmem_get( 'wpmem_fields_display', array() );
$wpmem_fields_required_post = wpmem_get( 'wpmem_fields_required', array() );
$wpmem_fields_profile_post = wpmem_get( 'wpmem_fields_profile', array() );
// Update display/required settings
foreach ( $wpmem_fields as $key => $field ) {
// What is the field?
$meta_key = $field[2];
// Main settings (display, required, profile).
if ( 'username' == $meta_key || 'user_email' == $meta_key ) {
$wpmem_fields[ $key ][4] = 'y';
$wpmem_fields[ $key ][5] = 'y';
$wpmem_fields[ $key ]['profile'] = ( 'username' == $meta_key ) ? false : true;
} else {
$wpmem_fields[ $key ][4] = ( in_array( $meta_key, $wpmem_fields_display_post ) ) ? 'y' : '';
$wpmem_fields[ $key ][5] = ( in_array( $meta_key, $wpmem_fields_required_post ) ) ? 'y' : '';
$wpmem_fields[ $key ]['profile'] = ( in_array( $meta_key, $wpmem_fields_profile_post ) ) ? true : false;
}
}
// Save updates.
update_option( 'wpmembers_fields', $wpmem_fields );
$wpmem->forms->load_fields();
// Set update message.
$did_update = esc_html__( 'WP-Members fields were updated', 'wp-members' );
// Return.
return $did_update;
} elseif ( 'delete' == $action ) {
// Check nonce.
check_admin_referer( 'bulk-settings_page_wpmem-settings' );
$delete_action = 'delete';
} elseif ( ( 'add_field' == wpmem_get( 'wpmem_admin_a' ) || 'edit_field' == wpmem_get( 'wpmem_admin_a' ) ) && check_admin_referer( 'wpmem_add_field' ) ) {
// Set action.
$action = sanitize_text_field( wpmem_get( 'wpmem_admin_a' ) );
global $add_field_err_msg;
$add_field_err_msg = false;
$add_name = sanitize_text_field( wpmem_get( 'add_name' ) );
$add_option = sanitize_text_field( wpmem_get( 'add_option' ) );
// Error check that field label and option name are included and unique.
$add_field_err_msg = ( ! $add_name ) ? esc_html__( 'Field Label is required. Nothing was updated.', 'wp-members' ) : $add_field_err_msg;
$add_field_err_msg = ( ! $add_option ) ? esc_html__( 'Meta Key is required. Nothing was updated.', 'wp-members' ) : $add_field_err_msg;
$add_field_err_msg = ( ! preg_match("/^[A-Za-z0-9_]*$/", $add_option ) ) ? esc_html__( 'Meta Key must contain only letters, numbers, and underscores', 'wp-members' ) : $add_field_err_msg;
// Check for duplicate field names.
$chk_fields = array();
foreach ( $wpmem_fields as $field ) {
$chk_fields[] = $field[2];
}
$add_field_err_msg = ( in_array( $add_option, $chk_fields ) ) ? esc_html__( 'A field with that meta key already exists', 'wp-members' ) : $add_field_err_msg;
// Error check for reserved terms.
$reserved_terms = wpmem_wp_reserved_terms();
if ( in_array( strtolower( $add_option ), $reserved_terms ) ) {
$add_field_err_msg = sprintf( esc_html__( 'Sorry, "%s" is a <a href="https://codex.wordpress.org/Function_Reference/register_taxonomy#Reserved_Terms" target="_blank">reserved term</a>. Field was not added.', 'wp-members' ), $add_option );
}
// Error check option name for spaces and replace with underscores.
$us_option = preg_replace( "/ /", '_', $add_option );
$arr = array();
$type = sanitize_text_field( wpmem_get( 'add_type' ) );
$arr[0] = filter_var( wpmem_get( 'add_order_id' ), FILTER_SANITIZE_NUMBER_INT );
$arr[1] = sanitize_text_field( stripslashes( wpmem_get( 'add_name' ) ) );
$arr[2] = $us_option;
$arr[3] = $type;
$arr[4] = ( 'y' == wpmem_get( 'add_display', 'n' ) ) ? 'y' : 'n';
$arr[5] = ( 'y' == wpmem_get( 'add_required', 'n' ) ) ? 'y' : 'n';
// Mark native fields:
$native_fields = array( 'user_login', 'user_pass', 'user_nicename', 'user_email', 'user_url', 'user_registered', 'display_name', 'first_name', 'last_name', 'nickname', 'description' );
$arr[6] = ( in_array( $us_option, $native_fields ) ) ? 'y' : 'n';
if ( 'text' == $type || 'email' == $type || 'textarea' == $type || 'password' == $type || 'url' == $type || 'number' == $type || 'date' == $type || 'timestamp' == $type ) {
$arr['placeholder'] = sanitize_text_field( stripslashes( wpmem_get( 'add_placeholder' ) ) );
}
if ( 'text' == $type || 'email' == $type || 'password' == $type || 'url' == $type || 'number' == $type || 'date' == $type || 'timestamp' == $type ) {
$arr['pattern'] = sanitize_text_field( stripslashes( wpmem_get( 'add_pattern' ) ) );
$arr['title'] = sanitize_text_field( stripslashes( wpmem_get( 'add_title' ) ) );
}
if ( 'number' == $type || 'date' == $type ) {
$arr['min'] = filter_var( wpmem_get( 'add_min' ), FILTER_SANITIZE_NUMBER_INT );
$arr['max'] = filter_var( wpmem_get( 'add_max' ), FILTER_SANITIZE_NUMBER_INT );
}
if ( 'textarea' == $type ) {
$arr['rows'] = filter_var( wpmem_get( 'add_rows' ), FILTER_SANITIZE_NUMBER_INT );
$arr['cols'] = filter_var( wpmem_get( 'add_cols' ), FILTER_SANITIZE_NUMBER_INT );
}
if ( $type == 'checkbox' ) {
$add_field_err_msg = ( ! $_POST['add_checked_value'] ) ? esc_html__( 'Checked value is required for checkboxes. Nothing was updated.', 'wp-members' ) : $add_field_err_msg;
$arr[7] = sanitize_text_field( wpmem_get( 'add_checked_value', false ) );
$arr[8] = ( 'y' == wpmem_get( 'add_checked_default', 'n' ) ) ? 'y' : 'n';
$arr['checkbox_label'] = intval( wpmem_get( 'add_checkbox_label', 0 ) );
}
if ( $type == 'select'
|| $type == 'multiselect'
|| $type == 'radio'
|| $type == 'multicheckbox'
) {
// Get the values.
$which_post = ( $type == 'radio' || $type == 'multicheckbox' ) ? 'add_radio_value' : 'add_dropdown_value';
$str = stripslashes( sanitize_textarea_field( $_POST[ $which_post ] ) );
// Remove linebreaks.
$str = trim( str_replace( array("\r", "\r\n", "\n"), '', $str ) );
// Create array.
if ( ! function_exists( 'str_getcsv' ) ) {
$clean_values = explode( ',', $str );
} else {
$clean_values = str_getcsv( $str, ',', '"' );
}
// Clean input values.
foreach ( $clean_values as $key => $raw_value ) {
$pieces = array_map( 'trim', explode( '|', $raw_value ) );
$clean_values[ $key ] = $pieces[0] . '|' . $pieces[1];
}
$arr[7] = $clean_values;
// If multiselect or multicheckbox, set delimiter.
if ( 'multiselect' == $type || 'multicheckbox' == $type ) {
$arr[8] = ( ',' === wpmem_get( 'add_delimiter_value', '|' ) ) ? ',' : '|';
}
}
if ( $type == 'file' || $type == 'image' ) {
$arr[7] = sanitize_text_field( stripslashes( $_POST['add_file_value'] ) );
}
if ( wpmem_get( 'add_type' ) == 'hidden' ) {
$add_field_err_msg = ( ! $_POST['add_hidden_value'] ) ? esc_html__( 'A value is required for hidden fields. Nothing was updated.', 'wp-members' ) : $add_field_err_msg;
$arr[7] = ( isset( $_POST['add_hidden_value'] ) ) ? sanitize_text_field( stripslashes( $_POST['add_hidden_value'] ) ) : '';
}
if ( 'timestamp' == wpmem_get( 'add_type' ) ) {
$arr['timestamp_display'] = sanitize_text_field( wpmem_get( 'add_timestamp_display', 'Y-m-d', 'post' ) );
}
if ( $action == 'add_field' ) {
if ( ! $add_field_err_msg ) {
array_push( $wpmem_fields, $arr );
$did_update = sprintf( esc_html__( '%s was added', 'wp-members' ), esc_html( $_POST['add_name'] ) );
} else {
$did_update = $add_field_err_msg;
}
} else {
for ( $row = 0; $row < count( $wpmem_fields ); $row++ ) {
if ( $wpmem_fields[ $row ][2] == wpmem_get( 'field', false, 'get' ) ) {
$arr[0] = $wpmem_fields[ $row ][0];
foreach ( $arr as $key => $value ) {
$wpmem_fields[ $row ][ $key ] = $arr[ $key ];
}
}
}
$did_update = sprintf( esc_html__( '%s was updated', 'wp-members' ), esc_html( stripslashes( $add_name ) ) );
$did_update.= '<p><a href="' . esc_url( add_query_arg( array( 'page' => 'wpmem-settings', 'tab' => 'fields' ), get_admin_url() . 'options-general.php' ) ) . '">&laquo; ' . esc_html__( 'Return to Fields Table', 'wp-members' ) . '</a></p>';
}
$wpmem_newfields = $wpmem_fields;
update_option( 'wpmembers_fields', $wpmem_newfields );
$wpmem->forms->load_fields();
return $did_update;
}
}
}
/**
* Reorders form fields.
*
* @since 2.5.1
* @since 3.1.8 Rebuilt for new List Table.
* @since 3.3.0 Merged do_field_reorder() and field_reorder().
* @since 3.4.8 Added nonce check.
*/
public static function do_field_reorder() {
// Check nonce.
if ( ! check_admin_referer( 'wpmem_settings_nonce', 'nonce' ) ) {
_e( 'The link has expired. Please reload the page, or make sure your request originates from the WP-Members Fields tab.', 'wp-members' );
die();
}
// Check user caps in case this is hit by a non-admin user.
if ( ! current_user_can( 'manage_options' ) ) {
_e( 'User lacks required capability to make this change.', 'wp-members' );
die();
}
// Start fresh.
$new_order = $wpmem_fields = $field = $key = $wpmem_new_fields = $id = $k = '';
$wpmem_fields = get_option( 'wpmembers_fields' );
// Get the list items
$new_order = $_POST;
// Put fields in the proper order for the current form.
$wpmem_new_fields = array();
foreach ( $new_order['list_items'] as $id ) {
foreach( $wpmem_fields as $val ) {
if ( $val[0] == intval( $id ) ) {
$wpmem_new_fields[] = $val;
}
}
}
// Save fields array with new current form field order.
update_option( 'wpmembers_fields', $wpmem_new_fields );
// Indicate successful transaction.
_e( 'Form field order updated.', 'wp-members' );
die(); // This is required to return a proper result.
}
}
// End of file.
<?php
/**
Replaces wp-members/includes/admin/tabs/class-wp-members-admin-tab-shortcodes.php
Patches included:
* fixes bug in 3.5.0 that causes a fatal php error (code execution halt) when updating the [wpmem_field]
shortcode setting. (Uncaught Error: Cannot use object of type WP_Members_Shortcodes as array)
*/
/**
* WP-Members Admin functions
*
* Static functions to manage the shortcodes tab.
*
* This file is part of the WP-Members plugin by Chad Butler
* You can find out more about this plugin at https://rocketgeek.com
* Copyright (c) 2006-2024 Chad Butler
* WP-Members(tm) is a trademark of butlerblog.com
*
* @package WP-Members
* @author Chad Butler
* @copyright 2006-2024
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit();
}
class WP_Members_Admin_Tab_Shortcodes {
/**
* Creates the tab.
*
* @since 3.2.0
*
* @param string $tab The admin tab being displayed.
* @return string|bool The tab html, otherwise false.
*/
static function do_tab( $tab ) {
if ( $tab == 'shortcodes' || ! $tab ) {
// Render the tab.
return self::build_settings();
} else {
return false;
}
}
/**
* Builds the dialogs panel.
*
* @since 2.2.2
* @since 3.3.0 Ported from wpmem_a_build_dialogs().
*
* @global object $wpmem
*/
static function build_settings() {
global $wpmem; ?>
<div class="metabox-holder has-right-sidebar">
<div class="inner-sidebar">
<?php wpmem_a_meta_box(); ?>
<div class="postbox">
<h3><span><?php esc_html_e( 'Need help?', 'wp-members' ); ?></span></h3>
<div class="inside">
<strong><i>See the <a href="https://rocketgeek.com/plugins/wp-members/docs/plugin-settings/shortcodes/" target="_blank">Users Guide on dialogs</a>.</i></strong>
</div>
</div>
</div> <!-- .inner-sidebar -->
<div id="post-body">
<div id="post-body-content">
<div class="postbox">
<div class="inside">
<form name="updateshortcodesform" id="updateshortcodesform" method="post" action="<?php echo esc_url( wpmem_admin_form_post_url() ); ?>">
<?php
wp_nonce_field( 'wpmem-update-shortcodes' );
$wpmem_enable_field_sc = $wpmem->shortcodes->enable_field;
$wpmem_enable_field_sc = ( $wpmem_enable_field_sc ) ? $wpmem_enable_field_sc : 0;
$sc_notice_start = '<a href="https://rocketgeek.com/plugins/wp-members/docs/shortcodes/field-shortcodes/#security" target="_blank">';
?>
<h3>WP-Members <?php esc_html_e( 'Shortcodes', 'wp-members' ); ?></h3>
<p><?php esc_html_e('&#91;wpmem_field&#93; shortcode settings:', 'wp-members'); ?></p>
<table>
<tr>
<td><input type="radio" name="wpmem_enable_field_sc" id="wpmem_enable_field_sc_1" value="0" <?php checked( $wpmem_enable_field_sc, 0 ); ?> /></td>
<td><label><?php esc_html_e('Fully disabled', 'wp-members'); ?></label>
<span class="description"><?php esc_html_e( 'Fully disables the &#91;wpmem_field&#93; shortcode.', 'wp-members' ); ?></span></td>
</tr>
<tr>
<td><input type="radio" name="wpmem_enable_field_sc" id="wpmem_enable_field_sc_2" value="1" <?php checked( $wpmem_enable_field_sc, 1 ); ?> /></td>
<td><label><?php esc_html_e('Partially enabled', 'wp-members'); ?></label>
<span class="description"><?php esc_html_e( 'Enables the shortcode to display only if the user has "list_users" capability.', 'wp-members' ); ?></span></td>
</tr>
<tr>
<td><input type="radio" name="wpmem_enable_field_sc" id="wpmem_enable_field_sc_3" value="2" <?php checked( $wpmem_enable_field_sc, 2 ); ?> /></td>
<td><label><?php esc_html_e('Fully enabled', 'wp-members'); ?></label>
<span class="description"><?php printf(esc_html__('%sSee docs for security implications%s.','wp-members'),$sc_notice_start,'</a>'); ?></span></td>
</tr>
<?php // @todo Future expansion ?>
<!--<tr>
<td colspan=2>
<label for="wpmem_fields_sc_allowed_meta"><?php // esc_html_e( 'Meta keys allowed for &#91;wpmem_field&#93; shortcode', 'wp-members' ); ?></label>
<textarea name="wpmem_fields_sc_allowed_meta" rows="3" cols="50" id="" class="large-text code"><?php // echo esc_textarea( $some_var ); ?></textarea>
</td>
</tr>-->
</table>
<input type="hidden" name="wpmem_admin_a" value="update_shortcodes" />
<?php submit_button(); ?>
</form>
</div><!-- .inside -->
</div><!-- #post-box -->
</div><!-- #post-body-content -->
</div><!-- #post-body -->
</div> <!-- .metabox-holder -->
<?php
}
/**
* Updates the dialog settings.
*
* @since 2.8.0
* @since 3.3.0 Ported from wpmem_update_dialogs().
*
* @global object $wpmem
* @return string The dialogs updated message.
*/
static function update() {
global $wpmem;
// Check nonce.
check_admin_referer( 'wpmem-update-shortcodes' );
$wpmem_settings = get_option( 'wpmembers_settings' );
if ( isset( $_POST['wpmem_enable_field_sc'] ) ) {
$wpmem_settings['shortcodes']['enable_field'] = intval( $_POST['wpmem_enable_field_sc'] );
} else {
$wpmem_settings['shortcodes']['enable_field'] = 0;
}
update_option( 'wpmembers_settings', $wpmem_settings );
$wpmem->shortcodes->enable_field = $wpmem_settings['shortcodes']['enable_field'];
return esc_html__( 'WP-Members shorcode settings were updated', 'wp-members' );
}
} // End of file.
<?php
/**
Replaces wp-members/includes/includes/class-wp-members-forms.php
Patches included:
* Fixes admin notification email shortcode bug that causes the [fields] shortcode to be empty.
*/
/**
* The WP_Members Forms Class.
*
* @package WP-Members
* @subpackage WP_Members Forms Object Class
* @since 3.1.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit();
}
class WP_Members_Forms {
public $reg_form_showing = false;
public $file_user_id; // A container for the uploaded file user ID.
/**
* Plugin initialization function.
*
* @since 3.1.0
*/
function __construct() {
}
/**
* Sets the registration fields.
*
* @since 3.0.0
* @since 3.1.5 Added $form argument.
* @since 3.3.0 Added $tag argument.
*
* @global stdClass $wpmem
* @param string $tag
* @param string $form The form being generated.
*/
function load_fields( $tag = "all", $form = 'default' ) {
global $wpmem;
// @todo Temp fix for admin notification bug.
$tag = ( 'admin_notify' == $tag ) ? 'register' : $tag;
// Get stored fields settings.
$fields = get_option( 'wpmembers_fields' );
// Validate fields settings.
if ( ! isset( $fields ) || empty( $fields ) ) {
// Update settings.
$fields = array( array( 10, esc_html__( 'Email', 'wp-members' ), 'user_email', 'email', 'y', 'y', 'y', 'profile'=>true ) );
}
// Check woo reg fields.
if ( 'woo' == $tag && 1 == $wpmem->woo->add_my_account_fields ) {
$woo_reg_fields = get_option( 'wpmembers_wcacct_fields' );
$woo_reg_fields = ( $woo_reg_fields ) ? $woo_reg_fields : array();
}
// Add new field array keys
foreach ( $fields as $key => $val ) {
// Start by checking if we need this field or not.
if (
( 'register' == $tag && 'y' == $val[4] )
|| ( 'profile' == $tag && ( ! isset( $val['profile'] ) || 1 == $val['profile'] ) ) // @todo Currently checking ! isset because some fields don't have $val['profile']. Should probably handle on update to set $val['profile'] for all fields.
|| ( 'all' == $tag )
|| ( 'woo' == $tag && 1 == $wpmem->woo->add_my_account_fields && in_array( $val[2], $woo_reg_fields ) )
) {
if ( 'woo' == $tag && in_array( $val[2], $woo_reg_fields ) ) {
$val[4] = 'y';
}
// Key fields with meta key.
$meta_key = $val[2];
// What is the field type.
$field_type = $val[3];
// Old format, new key.
foreach ( $val as $subkey => $subval ) {
$assembled_fields[ $meta_key ][ $subkey ] = $subval;
}
// Setup field properties.
$assembled_fields[ $meta_key ]['label'] = $val[1];
$assembled_fields[ $meta_key ]['type'] = $field_type;
$assembled_fields[ $meta_key ]['register'] = ( 'y' == $val[4] ) ? true : false;
$assembled_fields[ $meta_key ]['required'] = ( 'y' == $val[5] ) ? true : false;
$assembled_fields[ $meta_key ]['profile'] = ( isset( $val['profile'] ) ) ? $val['profile'] : ( ( 'y' == $val[4] ) ? true : false );
$assembled_fields[ $meta_key ]['native'] = ( 'y' == $val[6] ) ? true : false;
// These field types have additional properties.
switch ( $field_type ) {
case 'checkbox':
$assembled_fields[ $meta_key ]['checked_value'] = $val[7];
$assembled_fields[ $meta_key ]['checked_default'] = ( 'y' == $val[8] ) ? true : false;
$assembled_fields[ $meta_key ]['checkbox_label'] = ( isset( $val['checkbox_label'] ) ) ? $val['checkbox_label'] : 0;
break;
case 'select':
case 'multiselect':
case 'multicheckbox':
case 'radio':
case 'membership':
if ( 'membership' == $field_type ) {
/**
* Filter the membership field dropdown default.
*
* @since 3.5.0
*
* @param string $default
*/
$membership_default = apply_filters( 'wpmem_membership_field_default', wpmem_get_text( 'membership_field' ) );
$val[7] = array( $membership_default . '|' );
foreach( wpmem_get_memberships() as $membership_key => $membership_value ) {
$val[7][] = $membership_value['title'] . '|' . $membership_key;
}
}
// Correct a malformed value (if last value is empty due to a trailing comma).
if ( '' == end( $val[7] ) ) {
array_pop( $val[7] );
$assembled_fields[ $meta_key ][7] = $val[7];
}
$assembled_fields[ $meta_key ]['values'] = $val[7];
$assembled_fields[ $meta_key ]['delimiter'] = ( isset( $val[8] ) ) ? $val[8] : '|';
$assembled_fields[ $meta_key ]['options'] = array();
foreach ( $val[7] as $value ) {
$pieces = explode( '|', trim( $value ) );
if ( isset( $pieces[1] ) && $pieces[1] != '' ) {
$assembled_fields[ $meta_key ]['options'][ $pieces[1] ] = $pieces[0];
}
}
break;
case 'file':
case 'image':
$assembled_fields[ $meta_key ]['file_types'] = $val[7];
break;
case 'hidden':
$assembled_fields[ $meta_key ]['value'] = $val[7];
break;
default:
$assembled_fields[ $meta_key ]['value'] = ( isset( $val['value'] ) ) ? $val['value'] : ''; // @since 3.5.0 adds default value.
break;
}
}
}
// @todo Set for checking backwards compatibility, but eventually get $wpmem->fields out altogether.
$wpmem->fields = $assembled_fields;
return $assembled_fields;
}
/**
* Filter custom fields for localization.
*
* @since 3.3.9
*
* @param array $fields
*/
function localize_fields( $fields ) {
// @todo Find wpmem_custom_translation_strings()
if ( function_exists( 'wpmem_custom_translation_strings' ) ) {
$string_map = wpmem_custom_translation_strings( get_locale() );
foreach ( $string_map as $meta_key => $value ) {
if ( is_array( $value ) ) {
if ( isset( $fields[ $meta_key ]['placeholder'] ) && isset( $value['placeholder'] ) ) {
$fields[ $meta_key ]['placeholder'] = $string_map[ $meta_key ]['placeholder'];
}
if ( isset( $fields[ $meta_key ]['title'] ) && isset( $value['title'] ) ) {
$fields[ $meta_key ]['title'] = $string_map[ $meta_key ]['title'];
}
if ( isset( $fields[ $meta_key ]['label'] ) && isset( $value['label'] ) ) {
$fields[ $meta_key ]['label'] = $string_map[ $meta_key ]['label'];
}
} else {
$fields[ $meta_key ]['label'] = $string_map[ $meta_key ];
}
}
}
return $fields;
}
/**
* Get excluded meta fields.
*
* @since 3.0.0
* @since 3.3.3 Update $tag to match wpmem_fields() tags.
*
* @param string $tag A tag so we know where the function is being used.
* @return array The excluded fields.
*/
function excluded_fields( $tag ) {
// Default excluded fields.
$excluded_fields = array( 'password', 'confirm_password', 'confirm_email', 'password_confirm', 'email_confirm' );
if ( 'update' == $tag || 'admin-profile' == $tag || 'user-profile' == $tag || 'wp-register' == $tag ) {
$excluded_fields[] = 'username';
}
if ( 'admin-profile' == $tag || 'user-profile' == $tag ) {
array_push( $excluded_fields, 'first_name', 'last_name', 'nickname', 'display_name', 'user_email', 'description', 'user_url' );
// If WooCommerce is used, remove these meta - WC already adds them in their own section.
if ( class_exists( 'woocommerce' ) ) {
array_push( $excluded_fields,
'billing_first_name',
'billing_last_name',
'billing_company',
'billing_address_1',
'billing_address_2',
'billing_city',
'billing_postcode',
'billing_country',
'billing_state',
'billing_email',
'billing_phone',
'shipping_first_name',
'shipping_last_name',
'shipping_company',
'shipping_address_1',
'shipping_address_2',
'shipping_city',
'shipping_postcode',
'shipping_country',
'shipping_state'
);
}
}
/**
* Filter excluded meta fields.
*
* @since 2.9.3
* @since 3.0.0 Moved to new method in WP_Members Class.
* @since 3.3.3 Update $tag to match wpmem_fields() tags.
*
* @param array An array of the field meta names to exclude.
* @param string $tag A tag so we know where the function is being used.
*/
$excluded_fields = apply_filters( 'wpmem_exclude_fields', $excluded_fields, $tag );
// Return excluded fields.
return $excluded_fields;
}
/**
* Creates form fields
*
* Creates various form fields and returns them as a string.
*
* @since 3.1.0
* @since 3.1.1 Added $delimiter.
* @since 3.1.2 Changed $valtochk to $compare.
* @since 3.1.6 Added $placeholder.
* @since 3.1.7 Added number type & $min, $max, $title and $pattern attributes.
* @since 3.2.0 Added $id argument.
* @since 3.2.4 Added radio group and multiple checkbox individual item labels.
*
* @global object $wpmem The WP_Members object class.
* @param array $args {
* @type string $id
* @type string $name
* @type string $type
* @type string $value
* @type string $compare
* @type string $class
* @type boolean $required
* @type string $delimiter
* @type string $placeholder
* @type string $pattern
* @type string $title
* @type string $min
* @type string $max
* @type string $rows Number of rows for a textarea (default:5).
* @type string $cols Number of columns for a textarea (default:20).
* }
* @return string $str The field returned as a string.
*/
function create_form_field( $args ) {
global $wpmem;
// Set defaults for most possible $args.
$id = ( isset( $args['id'] ) ) ? esc_attr( $args['id'] ) : esc_attr( $args['name'] );
$name = esc_attr( $args['name'] );
$type = esc_attr( $args['type'] );
$value = ( isset( $args['value'] ) ) ? $args['value'] : '';
$compare = ( isset( $args['compare'] ) ) ? $args['compare'] : '';
$class = ( isset( $args['class'] ) ) ? $args['class'] : 'textbox';
$required = ( isset( $args['required'] ) ) ? $args['required'] : false;
$delimiter = ( isset( $args['delimiter'] ) ) ? $args['delimiter'] : '|';
$placeholder = ( isset( $args['placeholder'] ) ) ? $args['placeholder'] : false;
$pattern = ( isset( $args['pattern'] ) ) ? $args['pattern'] : false;
$title = ( isset( $args['title'] ) ) ? $args['title'] : false;
$file_types = ( isset( $args['file_types'] ) ) ? $args['file_types'] : false;
$timestamp = ( isset( $args['timestamp_display'] ) ) ? $args['timestamp_display'] : 'Y-m-d';
// Handle field creation by type.
switch ( $type ) {
/*
* Field types text|url|email|number|date are all handled essentially the
* same. The primary differences are CSS class (with a default fallback
* of 'textbox'), how values are escaped, and the application of min|max
* values for number fields.
*/
case "text":
case "url":
case "email":
case "number":
case "date":
case "timestamp":
$class = ( 'textbox' == $class ) ? "textbox" : wpmem_sanitize_class( $class );
switch ( $type ) {
case 'url':
$value = esc_url( $value );
break;
case 'timestamp':
$value = ( '' != $value ) ? date( $timestamp, intval( $value ) ) : '';
break;
default:
$value = wp_unslash( esc_attr( $value ) );
break;
}
$required = ( $required ) ? ' required' : '';
$placeholder = ( $placeholder ) ? ' placeholder="' . esc_attr( __( $placeholder, 'wp-members' ) ) . '"' : '';
$title = ( $title ) ? ' title="' . esc_attr( __( $title, 'wp-members' ) ) . '"' : '';
$pattern = ( $pattern && 'number' != $type ) ? ' pattern="' . esc_attr( $pattern ) . '"' : '';
$min = ( isset( $args['min'] ) && $args['min'] != '' ) ? ' min="' . esc_attr( $args['min'] ) . '"' : '';
$max = ( isset( $args['max'] ) && $args['max'] != '' ) ? ' max="' . esc_attr( $args['max'] ). '"' : '';
$str = "<input name=\"$name\" type=\"$type\" id=\"$id\" value=\"$value\" class=\"$class\"$placeholder$title$pattern$min$max" . ( ( $required ) ? " required " : "" ) . " />";
break;
case "password":
$class = wpmem_sanitize_class( $class );
$placeholder = ( $placeholder ) ? ' placeholder="' . esc_attr( __( $placeholder, 'wp-members' ) ) . '"' : '';
$pattern = ( $pattern ) ? ' pattern="' . esc_attr( $pattern ) . '"' : '';
$title = ( $title ) ? ' title="' . esc_attr( __( $title, 'wp-members' ) ) . '"' : '';
$str = "<input name=\"$name\" type=\"$type\" id=\"$id\" class=\"$class\"$placeholder$title$pattern" . ( ( $required ) ? " required " : "" ) . " />";
break;
case "image":
case "file":
if ( $file_types ) {
$file_types = explode( '|', $file_types );
foreach( $file_types as $file_type ) {
$array[] = "." . $file_type;
}
$accept = ' accept="' . implode( ",", $array ) . '"';
} else {
$accept = '';
}
$class = ( 'textbox' == $class ) ? "file" : wpmem_sanitize_class( $class );
$str = "<input name=\"$name\" type=\"file\" id=\"$id\" value=\"" . esc_attr( $value ) . "\" class=\"$class\"$accept" . ( ( $required ) ? " required " : "" ) . ( ( 'image' == $type ) ? ' onchange="loadFile(event, this.id)"' : '' ) . ' />';
break;
case "checkbox":
$class = ( 'textbox' == $class ) ? "checkbox" : wpmem_sanitize_class( $class );
$str = "<input name=\"$name\" type=\"$type\" id=\"$id\" value=\"" . esc_attr( $value ) . "\"" . checked( $value, $compare, false ) . ( ( $required ) ? " required " : "" ) . " />";
break;
case "textarea":
$value = esc_textarea( stripslashes( $value ) ); // stripslashes( esc_textarea( $value ) );
$class = ( 'textbox' == $class ) ? "textarea" : wpmem_sanitize_class( $class );
$placeholder = ( $placeholder ) ? ' placeholder="' . esc_attr( __( $placeholder, 'wp-members' ) ) . '"' : '';
$rows = ( isset( $args['rows'] ) && $args['rows'] ) ? esc_attr( $args['rows'] ) : '5';
$cols = ( isset( $args['cols'] ) && $args['cols'] ) ? esc_attr( $args['cols'] ) : '20';
$str = "<textarea cols=\"$cols\" rows=\"$rows\" name=\"$name\" id=\"$id\" class=\"$class\"$placeholder" . ( ( $required ) ? " required " : "" ) . ">$value</textarea>";
break;
case "hidden":
$str = "<input name=\"$name\" type=\"$type\" value=\"" . esc_attr( $value ) . "\" />";
break;
case "option":
$str = "<option value=\"" . esc_attr( $value ) . "\" " . selected( $value, $compare, false ) . " >" . __( $name, 'wp-members' ) . "</option>";
break;
case "select":
case "multiselect":
case "membership":
$class = ( 'textbox' == $class && 'multiselect' != $type ) ? "dropdown" : $class;
$class = ( 'textbox' == $class && 'multiselect' == $type ) ? "multiselect" : $class;
$pname = ( 'multiselect' == $type ) ? $name . "[]" : $name;
$str = "<select name=\"$pname\" id=\"$id\" class=\"$class\"" . ( ( 'multiselect' == $type ) ? " multiple " : "" ) . ( ( $required ) ? " required " : "" ) . ">\n";
if ( 'membership' == $type ) {
$value = array( wpmem_get_text( 'membership_field' ) . '|' );
foreach( wpmem_get_memberships() as $membership_key => $membership_value ) {
$value[] = $membership_value['title'] . '|' . $membership_key;
}
}
foreach ( $value as $option ) {
$pieces = array_map( 'trim', explode( '|', $option ) );
if ( 'multiselect' == $type ) {
$chk = '';
$values = ( empty( $compare ) ) ? array() : ( is_array( $compare ) ? $compare : explode( $delimiter, $compare ) );
} else {
$chk = $compare;
$values = array();
}
if ( isset( $pieces[1] ) && '' != $pieces[1] ) {
$chk = ( ( isset( $pieces[2] ) && '' == $compare ) || in_array( $pieces[1], $values ) ) ? $pieces[1] : $chk;
} else {
$chk = 'not selected';
}
$pieces[1] = ( isset( $pieces[1] ) ) ? $pieces[1] : ''; // If someone skipped a pipe, treat it as empty.
$str = $str . "<option value=\"$pieces[1]\"" . selected( $pieces[1], $chk, false ) . ">" . esc_attr( __( $pieces[0], 'wp-members' ) ) . "</option>\n";
}
$str = $str . "</select>";
break;
case "multicheckbox":
$class = ( 'textbox' == $class ) ? "checkbox" : $class;
$str = '';
$num = 1;
foreach ( $value as $option ) {
$pieces = explode( '|', $option );
$values = ( empty( $compare ) ) ? array() : ( is_array( $compare ) ? $compare : explode( $delimiter, $compare ) );
$chk = ( isset( $pieces[2] ) && '' == $compare ) ? $pieces[1] : '';
if ( isset( $pieces[1] ) && '' != $pieces[1] ) {
$id_value = esc_attr( $id . '[' . $pieces[1] . ']' );
$label = wpmem_form_label( array( 'meta_key'=>$id_value, 'label'=>esc_html( __( $pieces[0], 'wp-members' ) ), 'type'=>'multicheckbox', 'id'=>$id_value ) );
$str = $str . wpmem_form_field( array(
'id' => $id_value,
'name' => $name . '[]',
'type' => 'checkbox',
'value' => $pieces[1],
'compare' => ( in_array( $pieces[1], $values ) ) ? $pieces[1] : $chk,
) ) . "&nbsp;" . $label . "<br />\n";
} else {
$str = $str . '<span class="div_multicheckbox_separator">' . esc_html( __( $pieces[0], 'wp-members' ) ) . "</span><br />\n";
}
}
break;
case "radio":
$class = ( 'textbox' == $class ) ? "radio" : wpmem_sanitize_class( $class );
$str = '';
$num = 1;
foreach ( $value as $option ) {
$pieces = explode( '|', $option );
$id_num = $id . '_' . $num;
if ( isset( $pieces[1] ) && '' != $pieces[1] ) {
$label = wpmem_form_label( array( 'meta_key'=>esc_attr( $id_num ), 'label'=>esc_html( __( $pieces[0], 'wp-members' ) ), 'type'=>'radio', 'id'=>esc_attr( "label_" . $id_num ) ) );
$str = $str . "<input type=\"radio\" name=\"$name\" id=\"" . esc_attr( $id_num ) . "\" value=\"" . esc_attr( $pieces[1] ) . '"' . checked( $pieces[1], $compare, false ) . ( ( $required ) ? " required " : " " ) . "> $label<br />\n";
$num++;
} else {
$str = $str . '<span class="div_radio_separator">' . esc_html( __( $pieces[0], 'wp-members' ) ) . "</span><br />\n";
}
}
break;
}
return $str;
} // End create_form_field()
/**
* Create form label.
*
* @since 3.1.7
* @since 3.2.4 Added $id
*
* @param array $args {
* @type string $meta_key
* @type string $label
* @type string $type
* @type string $id (optional)
* @type string $class (optional)
* @type string $required (optional)
* @type string $req_mark (optional)
* }
* @return string $label
*/
function create_form_label( $args ) {
global $wpmem;
$meta_key = $args['meta_key'];
$label = $args['label'];
$type = $args['type'];
$class = ( isset( $args['class'] ) ) ? $args['class'] : false;
$id = ( isset( $args['id'] ) ) ? $args['id'] : false;
$required = ( isset( $args['required'] ) ) ? $args['required'] : false;
$req_mark = ( isset( $args['req_mark'] ) ) ? $args['req_mark'] : false;
//$req_mark = ( ! $req_mark ) ? wpmem_get_text( 'register_req_mark' ) : '*';
if ( ! $class ) {
$class = ( $type == 'password' || $type == 'email' || $type == 'url' ) ? 'text' : $type;
}
$id = ( $id ) ? ' id="' . esc_attr( $id ) . '"' : '';
$label = '<label for="' . esc_attr( $meta_key ) . '"' . $id . ' class="' . wpmem_sanitize_class( $class ) . '">' . __( $label, 'wp-members' );
$label = ( $required ) ? $label . $req_mark : $label;
$label = $label . '</label>';
return $label;
}
/**
* Uploads file from the user.
*
* @since 3.1.0
*
* @param array $file
* @param int $user_id
* @return int|bool
*/
function do_file_upload( $file = array(), $user_id = false ) {
// Filter the upload directory.
add_filter( 'upload_dir', array( &$this, 'file_upload_dir' ) );
// Set up user ID for use in upload process.
$this->file_user_id = ( $user_id ) ? $user_id : 0;
// Get WordPress file upload processing scripts.
require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once( ABSPATH . 'wp-admin/includes/media.php' );
$file_return = wp_handle_upload( $file, array( 'test_form' => false ) );
if ( isset( $file_return['error'] ) || isset( $file_return['upload_error_handler'] ) ) {
return false;
} else {
$attachment = array(
'post_mime_type' => $file_return['type'],
'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $file_return['file'] ) ),
'post_content' => '',
'post_status' => 'inherit',
'guid' => $file_return['url'],
'post_author' => ( $user_id ) ? $user_id : '',
);
$attachment_id = wp_insert_attachment( $attachment, $file_return['url'] );
require_once( ABSPATH . 'wp-admin/includes/image.php' );
$attachment_data = wp_generate_attachment_metadata( $attachment_id, $file_return['file'] );
wp_update_attachment_metadata( $attachment_id, $attachment_data );
if ( 0 < intval( $attachment_id ) ) {
// Returns an array with file information.
return $attachment_id;
}
}
return false;
} // End upload_file()
/**
* Sets the file upload directory.
*
* This is a filter function for upload_dir.
*
* @link https://codex.wordpress.org/Plugin_API/Filter_Reference/upload_dir
*
* @since 3.1.0
*
* @param array $param {
* The directory information for upload.
*
* @type string $path
* @type string $url
* @type string $subdir
* @type string $basedir
* @type string $baseurl
* @type string $error
* }
* @return array $param
*/
function file_upload_dir( $param ) {
$user_id = ( isset( $this->file_user_id ) ) ? $this->file_user_id : null;
$args = array(
'user_id' => $user_id,
'wpmem_dir' => wpmem_get_upload_base(),
'user_dir' => 'user_files/' . $user_id,
);
/**
* Filter the user directory elements.
*
* @since 3.1.0
*
* @param array $args
*/
$args = apply_filters( 'wpmem_user_upload_dir', $args );
$param['subdir'] = '/' . $args['wpmem_dir'] . '/' . $args['user_dir'];
$param['path'] = $param['basedir'] . '/' . $args['wpmem_dir'] . '/' . $args['user_dir'];
$param['url'] = $param['baseurl'] . '/' . $args['wpmem_dir'] . '/' . $args['user_dir'];
return $param;
}
/**
* Login Form Builder.
*
* Builds the form used for login, change password, and reset password.
*
* @since 2.5.1
* @since 3.1.7 Moved to forms object class as login_form().
* @since 3.1.7 Added WP action login_form.
* @since 3.2.6 Added nonce to the short form.
*
* @param string $page
* @param array $arr {
* The elements needed to generate the form (login|reset password|forgotten password).
*
* @type string $heading Form heading text.
* @type string $action The form action (login|pwdchange|pwdreset|getusername).
* @type string $button_text Form submit button text.
* @type array $inputs {
* The form input values.
*
* @type array {
*
* @type string $name The field label.
* @type string $type Input type.
* @type string $tag Input tag name.
* @type string $class Input tag class.
* @type string $div Div wrapper class.
* }
* }
* @type string $redirect_to Optional. URL to redirect to.
* }
* @return string $form The HTML for the form as a string.
*/
function login_form( $mixed, $arr = array() ) {
global $wpmem;
// Handle legacy use.
if ( is_array( $mixed ) ) {
$page = ( isset( $mixed['page'] ) ) ? $mixed['page'] : 'login';
$arr = $mixed;
} else {
$page = $mixed;
}
$action = ( ! isset( $arr['action'] ) ) ? 'login' : $arr['action'];
// Set up redirect_to
$redirect_to = wpmem_get_redirect_to( $arr );
// Set up default wrappers.
// NOTE: DO NOT EDIT! There is a filter hook for this -> wpmem_login_form_args.
$defaults = array(
// wrappers
'heading_before' => '<legend>',
'heading_after' => '</legend>',
'fieldset_before' => '<fieldset>',
'fieldset_after' => '</fieldset>',
'main_div_before' => '<div id="wpmem_login">',
'main_div_after' => '</div>',
'row_before' => '',
'row_after' => '',
'buttons_before' => '<div class="button_div">',
'buttons_after' => '</div>',
'link_before' => '<div class="link-text">',
'link_after' => '</div>',
'link_span_before' => '<span class="link-text-%s">',
'link_span_after' => '</span>',
// classes & ids
'form_id' => 'wpmem_' . $action . '_form',
'form_class' => 'form',
'button_id' => '',
'button_class' => 'buttons',
// other
'strip_breaks' => true,
'wrap_inputs' => true,
'remember_check' => true,
'n' => "\n",
't' => "\t",
'redirect_to' => $redirect_to,
'login_form_action' => true,
'novalidate' => false,
);
/**
* Filter the default form arguments.
*
* This filter accepts an array of various elements to replace the form defaults. This
* includes default tags, labels, text, and small items including various booleans.
*
* @since 2.9.0
* @since 3.3.0 Passes $defaults as an argument.
*
* @param array $args {
* An array of arguments to merge with defaults.
*
* @type string $heading_before Default: '<legend>'
* @type string $heading_after Default: '</legend>'
* @type string $fieldset_before Default: '<fieldset>'
* @type string $fieldset_after Default: '</fieldset>'
* @type string $main_div_before Default: '<div id="wpmem_login">'
* @type string $main_div_after Default: '</div>'
* @type string $row_before Default: ''
* @type string $row_after Default: ''
* @type string $buttons_before Default: '<div class="button_div">'
* @type string $buttons_after Default: '</div>'
* @type string $link_before Default: '<div class="link-text">'
* @type string $link_after Default: '</div>'
* @type string $link_span_before Default: '<span class="link-text-%s">'
* @type string $link_span_after Default: '</span>'
* @type string $form_id Default: 'wpmem_' . $action . '_form' (for example, wpmem_login_form or wpmem_pwdreset_form)
* @type string $form_class Default: 'form'
* @type string $button_id Default: ''
* @type string $button_class Default: buttons'
* @type boolean $strip_breaks Default: true (if true, strips all line breaks from the generated HTML)
* @type boolean $wrap_inputs Default: true (if true, includes main_div_before/after wrappers around input tags)
* @type boolean $remember_check Default: true
* @type string $n Default: "\n" (the new line character if breaks are not stripped (see $strip_breaks))
* @type string $t Default: "\t" (the line indent character if breaks are not stripped (see $strip_breaks))
* @type string $redirect_to Default: (the $redirect_to argument passed to the function)
* @type boolean $login_form_action Default: true (if true, adds the WP login_form action)
* }
* @param string $action The action being performed by the form. login|pwdreset|pwdchange|getusername.
*/
$args = apply_filters( 'wpmem_login_form_args', $defaults, $action );
// Merge $args with defaults.
$args = wp_parse_args( $args, $defaults );
// Build the input rows.
foreach ( $arr['inputs'] as $input ) {
$label = '<label for="' . esc_attr( $input['tag'] ) . '">' . $input['name'] . '</label>';
$field = wpmem_form_field( array(
'name' => $input['tag'],
'type' => $input['type'],
'class' => $input['class'],
'required' => true,
) );
$field_before = ( $args['wrap_inputs'] ) ? '<div class="' . wpmem_sanitize_class( $input['div'] ) . '">' : '';
$field_after = ( $args['wrap_inputs'] ) ? '</div>' : '';
$rows[] = array(
'row_before' => $args['row_before'],
'label' => $label,
'field_before' => $field_before,
'field' => $field,
'field_after' => $field_after,
'row_after' => $args['row_after'],
);
}
/**
* Filter the array of form rows.
*
* This filter receives an array of the main rows in the form, each array element being
* an array of that particular row's pieces. This allows making changes to individual
* parts of a row without needing to parse through a string of HTML.
*
* @since 2.9.0
* @since 3.2.6 Added $arr parameter so all settings are passed.
*
* @param array $rows An array containing the form rows.
* @param string $action The action being performed by the form. login|pwdreset|pwdchange|getusername.
* @param array $arr An array containing all of the form settings.
*/
$rows = apply_filters( 'wpmem_login_form_rows', $rows, $action, $arr );
// Put the rows from the array into $form.
$form = '';
foreach ( $rows as $row_item ) {
$row = ( $row_item['row_before'] != '' ) ? $row_item['row_before'] . $args['n'] . $row_item['label'] . $args['n'] : $row_item['label'] . $args['n'];
$row .= ( $row_item['field_before'] != '' ) ? $row_item['field_before'] . $args['n'] . $args['t'] . $row_item['field'] . $args['n'] . $row_item['field_after'] . $args['n'] : $row_item['field'] . $args['n'];
$row .= ( $row_item['row_after'] != '' ) ? $row_item['row_after'] . $args['n'] : '';
$form.= $row;
}
// Handle outside elements added to the login form (currently ONLY for login).
if ( 'login' == $action && $args['login_form_action'] ) {
ob_start();
/** This action is documented in wp-login.php */
do_action( 'login_form' );
$add_to_form = ob_get_contents();
ob_end_clean();
$form.= $add_to_form;
}
// Build hidden fields, filter, and add to the form.
if ( 'set_password_from_key' == wpmem_get( 'a', false, 'request' ) && 'login' != $action ) {
$hidden['action'] = wpmem_form_field( array( 'name' => 'a', 'type' => 'hidden', 'value' => 'set_password_from_key' ) );
$hidden['key'] = wpmem_form_field( array( 'name' => 'key', 'type' => 'hidden', 'value' => sanitize_text_field( wpmem_get( 'key', null, 'request' ) ) ) );
$hidden['login'] = wpmem_form_field( array( 'name' => 'login', 'type' => 'hidden', 'value' => sanitize_user( wpmem_get( 'login', null, 'request' ) ) ) );
} else {
$hidden['action'] = wpmem_form_field( array( 'name' => 'a', 'type' => 'hidden', 'value' => $action ) );
$hidden['redirect_to'] = wpmem_form_field( array( 'name' => 'redirect_to', 'type' => 'hidden', 'value' => esc_url( $args['redirect_to'] ) ) );
}
if ( $action != 'login' ) {
$hidden['formsubmit'] = wpmem_form_field( array( 'name' => 'formsubmit', 'type' => 'hidden', 'value' => '1' ) );
}
/**
* Filter hidden fields array.
*
* @since 3.4.0
*
* @param array $hidden
* @param string $action The action being performed by the form. login|pwdreset|pwdchange|getusername.
*/
$hidden = apply_filters( 'wpmem_login_hidden_field_rows', $hidden, $action );
$hidden_field_string = '';
foreach ( $hidden as $field ) {
$hidden_field_string .= $field . $args['n'];
}
/**
* Filter the hidden field HTML.
*
* @since 2.9.0
*
* @param string $hidden The generated HTML of hidden fields.
* @param string $action The action being performed by the form. login|pwdreset|pwdchange|getusername.
*/
$form = $form . apply_filters( 'wpmem_login_hidden_fields', $hidden_field_string, $action );
// Build the buttons, filter, and add to the form.
if ( $action == 'login' ) {
$buttons[] = ( $args['remember_check'] ) ? $args['t'] . wpmem_form_field( array( 'name' => 'rememberme', 'type' => 'checkbox', 'value' => 'forever' ) ) . '&nbsp;' . '<label for="rememberme">' . wpmem_get_text( 'remember_me' ) . '</label>&nbsp;&nbsp;' . $args['n'] : '';
$buttons[] = $args['t'] . '<input type="submit" name="Submit" value="' . esc_attr( $arr['button_text'] ) . '" class="' . wpmem_sanitize_class( $args['button_class'] ) . '" />' . $args['n'];
} else {
$buttons[] = '<input type="submit" name="Submit" value="' . esc_attr( $arr['button_text'] ) . '" class="' . wpmem_sanitize_class( $args['button_class'] ) . '" />' . $args['n'];
}
/**
* Filter the button parts.
*
* @since 3.4.5
*
* @param array $rows
* @param string $action
*/
$buttons = apply_filters( 'wpmem_login_form_button_rows', $buttons, $action );
// HTML assembly for buttons.
$button_html = '';
foreach ( $buttons as $button_row ) {
$button_html .= $button_row;
}
/**
* Filter the HTML for form buttons.
*
* The string includes the buttons, as well as the before/after wrapper elements.
*
* @since 2.9.0
*
* @param string $buttons The generated HTML of the form buttons.
* @param string $action The action being performed by the form. login|pwdreset|pwdchange|getusername.
*/
$form = $form . apply_filters( 'wpmem_login_form_buttons', $args['buttons_before'] . $args['n'] . $button_html . $args['buttons_after'] . $args['n'], $action );
$links_array = array(
'forgot' => array(
'tag' => 'forgot',
'link' => wpmem_pwd_reset_url(),
'page' => 'profile',
'action' => 'login',
),
'register' => array(
'tag' => 'reg',
'link' => wpmem_register_url(),
'page' => 'register',
'action' => 'login',
),
'username' => array(
'tag' => 'username',
'link' => wpmem_forgot_username_url(),
'page' => 'profile',
'action' => 'pwdreset',
),
'reconfirm' => array(
'tag' => 'reconfirm',
'link' => wpmem_reconfirm_url(),
'page' => 'profile',
'action' => 'pwdreset',
),
);
foreach ( $links_array as $key => $value ) {
$tag = $value['tag'];
if ( ( $wpmem->user_pages[ $value['page'] ] || 'profile' == $page ) && $value['action'] == $action ) {
/**
* Filters register, forgot password, and forgot username links.
*
* @since 2.8.0
* @since 3.1.7 Combined all to a single process.
* @since 3.2.5 Added $tag parameter.
*
* @param string The raw link.
* @param string $tag forgot|reg|pwdreset|username.
*/
$link = apply_filters( "wpmem_{$tag}_link", $value['link'], $tag );
$str = wpmem_get_text( "{$key}_link_before" ) . '<a href="' . esc_url( $link ) . '">' . wpmem_get_text( "{$key}_link" ) . '</a>';
$link_str = $args['link_before'];
$link_str.= ( '' != $args['link_span_before'] ) ? sprintf( $args['link_span_before'], $key ) : '';
/**
* Filters the register, forgot password, and forgot username links HTML.
*
* @since 2.9.0
* @since 3.0.9 Added $link parameter.
* @since 3.1.7 Combined all to a single process.
* @since 3.2.5 Added $tag parameter.
*
* @param string $str The link HTML.
* @param string $link The link.
* @param string $tag forgot|reg|pwdreset.
*/
$link_str.= apply_filters( "wpmem_{$tag}_link_str", $str, $link, $tag );
$link_str.= ( '' != $args['link_span_after'] ) ? $args['link_span_after'] : '';
$link_str.= $args['link_after'] . $args['n'];
/*
* If this is the register link, and the current post type is set to
* display the register form, and the current page is not the login
* page, then do not add the register link, otherwise add the link.
*/
if ( 'register' == $key ) {
if ( ! isset( $wpmem->user_pages['register'] ) || '' == $wpmem->user_pages['register'] ) {
$form = $form;
} else {
if ( isset( $wpmem->user_pages['login'] ) && '' != $wpmem->user_pages['login'] ) {
$form = ( 1 == $wpmem->show_reg[ get_post_type( get_the_ID() ) ] && wpmem_current_url( true, false ) != wpmem_login_url() ) ? $form : $form . $link_str;
} else {
global $post;
if ( has_shortcode( $post->post_content, 'wpmem_profile' ) ) {
$form = $form;
} else {
$form = ( 1 == $wpmem->show_reg[ get_post_type( get_the_ID() ) ] && ! has_shortcode( $post->post_content, 'wpmem_form' ) ) ? $form : $form . $link_str;
}
}
}
} else {
$form = $form . $link_str;
}
}
}
$novalidate = ( $args['novalidate'] ) ? 'novalidate' : '';
// Apply the heading.
$form = $args['heading_before'] . $arr['heading'] . $args['heading_after'] . $args['n'] . $form;
// Apply fieldset wrapper.
$form = $args['fieldset_before'] . $args['n'] . $form . $args['fieldset_after'] . $args['n'];
// Apply nonce.
$form = wp_nonce_field( 'wpmem_shortform_nonce', '_wpmem_' . $action . '_nonce', true, false ) . $args['n'] . $form;
// Apply form wrapper.
$form = '<form action="' . esc_url( get_permalink() ) . '" method="POST" id="' . wpmem_sanitize_class( $args['form_id'] ) . '" class="' . wpmem_sanitize_class( $args['form_class'] ) . '"' . $novalidate . '>' . $args['n'] . $form . '</form>';
// Apply anchor.
$form = '<a id="' . esc_attr( $action ) . '"></a>' . $args['n'] . $form;
// Apply main wrapper.
$form = $args['main_div_before'] . $args['n'] . $form . $args['n'] . $args['main_div_after'];
// Remove line breaks.
$form = ( $args['strip_breaks'] ) ? str_replace( array( "\n", "\r", "\t" ), array( '','','' ), $form ) : $form;
/**
* Filter the generated HTML of the entire form.
*
* @since 2.7.4
* @since 2.9.1 Added $action argument
*
* @param string $form The HTML of the final generated form.
* @param string $action The action being performed by the form. login|pwdreset|pwdchange|getusername.
*/
$form = apply_filters( 'wpmem_login_form', $form, $action );
/**
* Filter before the form.
*
* This rarely used filter allows you to stick any string onto the front of
* the generated form.
*
* @since 2.7.4
*
* @param string $str The HTML to add before the form. Default null.
* @param string $action The action being performed by the form. login|pwdreset|pwdchange|getusername.
*/
$form = apply_filters( 'wpmem_login_form_before', '', $action ) . $form;
return $form;
} // End login_form.
/**
* Registration Form Builder.
*
* Outputs the form for new user registration and existing user edits.
*
* @since 2.5.1
* @since 3.1.7 Moved to forms object class as register_form().
* @since 3.2.5 use_nonce now obsolete (nonce is added automatically).
* @since 3.3.0 $heading argument obsolete.
* @since 3.3.3 Image field type now shows the preview image when "choose file" is clicked.
* @since 3.4.6 Added $user object as a filterable arg.
*
* @global object $wpmem The WP_Members object.
* @param mixed $mixed (optional) String toggles between new registration ('new') and user profile edit ('edit'), or array containing settings arguments.
* @return string $form The HTML for the entire form as a string.
*/
function register_form( $mixed = 'new', $redirect_to = null ) {
/*
* Removes the action to load form elements for the WP registration
* form. Otherwise, when the register_form action is fired in this
* form, we'd get a duplication of all custom fields.
*/
remove_action( 'register_form', 'wpmem_wp_register_form' );
// Handle legacy use.
if ( is_array( $mixed ) ) {
$id = ( isset( $mixed['id'] ) ) ? $mixed['id'] : '';
$tag = ( isset( $mixed['tag'] ) ) ? $mixed['tag'] : 'new';
$heading = ( isset( $mixed['heading'] ) ) ? $mixed['heading'] : '';
$redirect_to = ( isset( $mixed['redirect_to'] ) ) ? $mixed['redirect_to'] : '';
$fields = ( isset( $mixed['fields'] ) ) ? $mixed['fields'] : false;
} else {
$id = 'default';
$tag = $mixed;
}
global $wpmem;
// If editing, the user object of the user being edit.
$user = ( 'edit' == $tag ) ? get_user_by( 'ID', get_current_user_id() ) : false;
/**
* Set up default wrappers.
*
* DO NOT EDIT THESE! If you need to customize, use the filter hook
* documented below to set up a proper, external filter function.
*
* @see wpmem_register_form_args
* @link https://rocketgeek.com/plugins/wp-members/docs/filter-hooks/wpmem_register_form_args/
*/
$defaults = array(
// Wrappers.
'heading_before' => '<legend>',
'heading_after' => '</legend>',
'fieldset_before' => '<fieldset>',
'fieldset_after' => '</fieldset>',
'main_div_before' => '<div id="wpmem_reg">',
'main_div_after' => '</div>',
'row_before' => '',
'row_after' => '',
'buttons_before' => '<div class="button_div">',
'buttons_after' => '</div>',
// Classes & ids.
'form_id' => ( 'new' == $tag ) ? 'wpmem_register_form' : 'wpmem_profile_form',
'form_class' => 'form',
'button_id' => '',
'button_class' => 'buttons',
// Required field tags and text.
'req_mark' => wpmem_get_text( 'register_req_mark' ),
'req_label' => wpmem_get_text( 'register_required' ),
'req_label_before' => '<div class="req-text">',
'req_label_after' => '</div>',
// Buttons.
'show_clear_form' => false,
'clear_form' => wpmem_get_text( 'register_clear' ),
'submit_register' => wpmem_get_text( 'register_submit' ),
'submit_update' => wpmem_get_text( 'profile_submit' ),
// Other.
'post_to' => get_permalink(),
'strip_breaks' => true,
'wrap_inputs' => true,
'n' => "\n",
't' => "\t",
'register_form_action' => true,
'user' => $user,
'novalidate' => false,
);
/**
* Filter the default form arguments.
*
* This filter accepts an array of various elements to replace the form defaults. This
* includes default tags, labels, text, and small items including various booleans.
*
* @since 2.9.0
* @since 3.2.5 Added $id
* @since 3.3.0 Passes $defaults as an argument.
* @since 3.4.6 Added $user as an argument.
*
* @param array An array of arguments to merge with defaults. Default null.
* @param string $tag Toggle new registration or profile update. new|edit.
* @param string $id An id for the form (optional).
*/
$args = apply_filters( 'wpmem_register_form_args', $defaults, $tag, $id );
// Merge $args with defaults.
$args = wp_parse_args( $args, $defaults );
// User ID based on filtered value.
$user = $args['user'];
// Get fields.
$wpmem_fields = wpmem_fields( $tag );
// Fields to skip for user profile update.
if ( 'edit' == $tag ) {
$pass_arr = array( 'username', 'password', 'confirm_password', 'password_confirm' );
// Skips tos on user edit page, unless they haven't got a value for tos.
$user_tos_val = ( is_object( $user ) ) ? get_user_meta( $user->ID, 'tos', true ) : false;
if ( isset( $wpmem_fields['tos'] ) && ( $wpmem_fields['tos']['checked_value'] == $user_tos_val ) ) {
$pass_arr[] = 'tos';
}
foreach ( $pass_arr as $pass ) {
unset( $wpmem_fields[ $pass ] );
}
}
/**
* Filter the array of form fields.
*
* The form fields are stored in the WP options table as wpmembers_fields. This
* filter can filter that array after the option is retreived before the fields
* are parsed. This allows you to change the fields that may be used in the form
* on the fly.
*
* @since 2.9.0
* @deprecated 3.1.7 Use wpmem_fields instead.
*
* @param array The array of form fields.
* @param string $tag Toggle new registration or profile update. new|edit.
*/
$wpmem_fields = apply_filters_deprecated( 'wpmem_register_fields_arr', array( $wpmem_fields, $tag ), '3.1.7', 'wpmem_fields' );
$hidden_rows = array();
$form_has_file = false;
// Loop through the remaining fields.
foreach ( $wpmem_fields as $meta_key => $field ) {
// Start with a clean row.
$val = ''; $label = ''; $input = ''; $field_before = ''; $field_after = '';
// If the field is set to display and we aren't skipping, construct the row.
// Handle hidden fields
if ( 'hidden' == $field['type'] ) {
$do_row = false;
$hidden_rows[ $meta_key ] = wpmem_form_field( array(
'name' => $meta_key,
'type' => $field['type'],
'value' => $field['value'],
'compare' => $valtochk,
'required' => $field['required'],
) );
}
// Label for all but TOS and hidden fields.
if ( 'tos' != $meta_key && 'hidden' != $field['type'] ) {
$class = ( $field['type'] == 'password' || $field['type'] == 'email' || $field['type'] == 'url' ) ? 'text' : $field['type'];
$label = wpmem_form_label( array(
'meta_key' => $meta_key, //( 'username' == $meta_key ) ? 'user_login' : $meta_key,
'label' => __( $field['label'], 'wp-members' ),
'type' => $field['type'],
'class' => $class,
'required' => $field['required'],
'req_mark' => $args['req_mark']
) );
}
// Gets the field value for edit profile.
if ( ( 'edit' == $tag ) && ( '' == wpmem_get_form_state() ) ) {
switch ( $meta_key ) {
case( 'description' ):
case( 'textarea' == $field['type'] ):
$val = ( is_object( $user ) ) ? get_user_meta( $user->ID, $meta_key, 'true' ) : ''; // esc_textarea() is run when field is created.
break;
case 'user_email':
case 'confirm_email':
$val = ( is_object( $user ) ) ? sanitize_email( $user->user_email ) : '';
break;
case 'user_url':
$val = ( is_object( $user ) ) ? $user->user_url : ''; // esc_url() is run when the field is created.
break;
case 'display_name':
$val = ( is_object( $user ) ) ? sanitize_text_field( $user->display_name ) : '';
break;
default:
$val = ( is_object( $user ) ) ? sanitize_text_field( get_user_meta( $user->ID, $meta_key, 'true' ) ) : '';
break;
}
} else {
if ( 'file' == $field['type'] ) {
$val = ( isset( $_FILES[ $meta_key ]['name'] ) ) ? sanitize_file_name( $_FILES[ $meta_key ]['name'] ) : '' ;
} else {
$val = wpmem_get_sanitized( $meta_key, '', 'post', $field['type'] ); // ( isset( $_POST[ $meta_key ] ) ) ? wpmem_sanitize_field( $_POST[ $meta_key ], $field['type'] ) : '';
}
if ( '' != $field['value'] ) {
$val = $field['value'];
}
}
// Does the tos field.
if ( 'tos' == $meta_key ) {
// $val = sanitize_text_field( wpmem_get( $meta_key, '' ) );
// Should be checked by default? and only if form hasn't been submitted.
$val = ( ! $_POST && $field['checked_default'] ) ? $field['checked_value'] : $val;
$input = wpmem_form_field( array(
'name' => $meta_key,
'type' => $field['type'],
'value' => $field['checked_value'],
'compare' => $val,
'required' => $field['required'],
) );
$input .= ' ' . $this->get_tos_link( $field, $tag );
$input = ( $field['required'] ) ? $input . $args['req_mark'] : $input;
// In previous versions, the div class would end up being the same as the row before.
$field_before = ( $args['wrap_inputs'] ) ? '<div class="div_text">' : '';
$field_after = ( $args['wrap_inputs'] ) ? '</div>' : '';
} elseif ( 'hidden' != $field['type'] ) {
// For checkboxes.
if ( 'checkbox' == $field['type'] ) {
$valtochk = $val;
$val = $field['checked_value'];
// if it should it be checked by default (& only if form not submitted), then override above...
if ( $field['checked_default'] && ( ! $_POST && $tag != 'edit' ) ) {
$val = $valtochk = $field['checked_value'];
}
}
// For dropdown select.
if ( 'select' == $field['type'] || 'radio' == $field['type'] || 'multiselect' == $field['type'] || 'multicheckbox' == $field['type'] || 'membership' == $field['type'] ) {
$valtochk = $val;
$val = $field['values'];
}
if ( ! isset( $valtochk ) ) {
$valtochk = '';
}
if ( ( 'file' == $field['type'] || 'image' == $field['type'] ) ) {
$form_has_file = true;
// Handle files differently for multisite vs. single install.
// @see: https://core.trac.wordpress.org/ticket/32145
if ( is_multisite() ) {
$attachment = get_post( $val );
$attachment_url = $attachment->guid;
} else {
$attachment_url = wp_get_attachment_url( $val );
}
$empty_file = '<span class="description">' . __( 'None' ) . '</span>';
if ( 'edit' == $tag ) {
if ( 'file' == $field['type'] ) {
$input = ( $attachment_url ) ? '<a href="' . esc_url( $attachment_url ) . '" id="' . $meta_key . '_file">' . get_the_title( $val ) . '</a>' : $empty_file;
} else {
$input = ( $attachment_url ) ? '<img src="' . esc_url( $attachment_url ) . '" id="' . $meta_key . '_img" />' : $empty_file;
}
$input.= '<br />' . wpmem_get_text( 'profile_upload' ) . '<br />';
} else {
if ( 'image' == $field['type'] ) {
$input = '<img src="" id="' . $meta_key . '_img" />';
}
}
$input.= wpmem_form_field( array(
'name' => $meta_key,
'type' => $field['type'],
'value' => $val,
'compare' => $valtochk,
'file_types' => $field['file_types'],
) );
} else {
// For all other input types.
$formfield_args = array(
'name' => $meta_key, // ( 'username' == $meta_key ) ? 'user_login' : $meta_key,
'type' => $field['type'],
'value' => $val,
'compare' => $valtochk,
//'class' => ( $class ) ? $class : 'textbox',
'required' => $field['required'],
'placeholder' => ( isset( $field['placeholder'] ) ) ? $field['placeholder'] : '',
'pattern' => ( isset( $field['pattern'] ) ) ? $field['pattern'] : false,
'title' => ( isset( $field['title'] ) ) ? $field['title'] : false,
'min' => ( isset( $field['min'] ) ) ? $field['min'] : false,
'max' => ( isset( $field['max'] ) ) ? $field['max'] : false,
'rows' => ( isset( $field['rows'] ) ) ? $field['rows'] : false,
'cols' => ( isset( $field['cols'] ) ) ? $field['cols'] : false,
'file_types' => ( isset( $field['file_types'] ) ) ? $field['file_types'] : false,
);
if ( 'multicheckbox' == $field['type'] || 'multiselect' == $field['type'] ) {
$formfield_args['delimiter'] = $field['delimiter'];
}
// Add timestamp support.
if ( 'timestamp' == $field['type'] ) {
$formfield_args['timestamp_display'] = $field['timestamp_display'];
}
$input = wpmem_form_field( $formfield_args );
// If checkbox label option is enabled.
// @todo "checkbox_label" should be set already, check why it isn't.
if ( 'checkbox' == $field['type'] && isset( $field['checkbox_label'] ) && 1 == $field['checkbox_label'] ) {
$input = $input . ' <label for="' . $meta_key . '">' . $label . '</label>';
$fields[ $meta_key ]['label'] = $field['label'] = $label = '';
}
}
// Determine input wrappers.
$field_before = ( $args['wrap_inputs'] ) ? '<div class="div_' . $class . '">' : '';
$field_after = ( $args['wrap_inputs'] ) ? '</div>' : '';
}
// If the row is set to display, add the row to the form array.
if ( 'hidden' != $field['type'] ) {
$values = '';
if ( 'multicheckbox' == $field['type'] || 'select' == $field['type'] || 'multiselect' == $field['type'] || 'radio' == $field['type'] ) {
$values = $val;
$val = $valtochk;
}
$rows[ $meta_key ] = array(
'meta' => $meta_key,
'type' => $field['type'],
'value' => $val,
'values' => $values,
'label_text' => __( $field['label'], 'wp-members' ),
'row_before' => $args['row_before'],
'label' => $label,
'field_before' => $field_before,
'field' => $input,
'field_after' => $field_after,
'row_after' => $args['row_after'],
);
}
}
// If captcha is Really Simple CAPTCHA.
if ( 2 == $wpmem->captcha && 'edit' != $tag ) {
// Build the captcha.
$row = WP_Members_Captcha::rs_captcha( 'array' );
$rows['captcha'] = array(
'meta' => '',
'type' => 'text',
'value' => '',
'values' => '',
'label_text' => $row['label_text'],
'row_before' => $args['row_before'],
'label' => $row['label'],
'field_before' => ( $args['wrap_inputs'] ) ? '<div class="div_text">' : '',
'field' => $row['img'] . $row['hidden'] . $row['field'],
'field_after' => ( $args['wrap_inputs'] ) ? '</div>' : '',
'row_after' => $args['row_after'],
);
}
/**
* Filter the array of form rows.
*
* This filter receives an array of the main rows in the form, each array element being
* an array of that particular row's pieces. This allows making changes to individual
* parts of a row without needing to parse through a string of HTML.
*
* @since 2.9.0
* @since 3.0.9 Added $rows['label_text'].
* @since 3.1.0 Added $rows['key'].
* @since 3.1.6 Deprecated $rows['order'].
*
* @param array $rows {
* An array containing the form rows.
*
* @type string order Field display order. (deprecated as of 3.1.6)
* @type string meta Field meta tag (not used for display).
* @type string type Input field type (not used for display).
* @type string value Input field value (not used for display).
* @type string values Possible field values (dropdown, multiple select/check, radio).
* @type string label_text Raw text for the label (not used for display).
* @type string row_before Opening wrapper tag around the row.
* @type string label Label tag.
* @type string field_before Opening wrapper tag before the input tag.
* @type string field The field input tag.
* @type string field_after Closing wrapper tag around the input tag.
* @type string row_after Closing wrapper tag around the row.
* }
* @param string $tag Toggle new registration or profile update. new|edit.
*/
$rows = apply_filters( 'wpmem_register_form_rows', $rows, $tag );
// Put the rows from the array into $form.
$form = ''; $enctype = '';
foreach ( $rows as $meta_key => $row_item ) {
// Make sure all keys are set just in case someone didn't return a proper array through the filter.
foreach ( $this->get_reg_row_keys() as $check_key ) {
if ( ! isset( $rows[ $meta_key ][ $check_key ] ) ) {
$rows[ $meta_key ][ $check_key ] = '';
$row_item[ $check_key ] = '';
}
}
// Check form to see if we need multipart enctype.
$enctype = ( $row_item['type'] == 'file' || $row_item['type'] == 'image' ) ? "multipart/form-data" : $enctype;
// Assemble row pieces.
$row = ( $row_item['row_before'] != '' ) ? $row_item['row_before'] . $args['n'] . $row_item['label'] . $args['n'] : $row_item['label'] . $args['n'];
$row .= ( $row_item['field_before'] != '' ) ? $row_item['field_before'] . $args['n'] . $args['t'] . $row_item['field'] . $args['n'] . $row_item['field_after'] . $args['n'] : $row_item['field'] . $args['n'];
$row .= ( $row_item['row_after'] != '' ) ? $row_item['row_after'] . $args['n'] : '';
$form.= $row;
}
// Handle outside elements added to the register form with register_form.
if ( 'new' == $tag && $args['register_form_action'] ) {
ob_start();
/** This action is documented in wp-login.php */
do_action( 'register_form' );
$add_to_form = ob_get_contents();
ob_end_clean();
$form.= $add_to_form;
}
// Do recaptcha if enabled.
if ( ( 1 == $wpmem->captcha || 3 == $wpmem->captcha || 4 == $wpmem->captcha ) && $tag != 'edit' ) { // don't show on edit page!
$row = WP_Members_Captcha::recaptcha();
if ( 4 != $wpmem->captcha ) {
$row = '<div class="clear"></div><div class="captcha">' . $row . '</div>';
}
// Add the captcha row to the form.
/**
* Filter the HTML for the CAPTCHA row.
*
* @since 2.9.0
*
* @param string The HTML for the entire row (includes HTML tags plus reCAPTCHA).
* @param string $tag Toggle new registration or profile update. new|edit.
*/
$form.= apply_filters( 'wpmem_register_captcha_row', $args['row_before'] . $row . $args['row_after'], $tag );
}
if ( 5 == $wpmem->captcha && 'edit' != $tag ) {
$row = WP_Members_Captcha::hcaptcha();
/** This filter is documented in /includes/class-wp-members-forms.php */
$form.= apply_filters( 'wpmem_register_captcha_row', $args['row_before'] . $row . $args['row_after'], $tag );
}
// Create hidden fields.
$var = ( $tag == 'edit' ) ? 'update' : 'register';
$redirect_to = ( isset( $_REQUEST['redirect_to'] ) ) ? $_REQUEST['redirect_to'] : ( ( $redirect_to ) ? $redirect_to : get_permalink() );
$hidden_rows['_wpmem_a'] = '<input name="a" type="hidden" value="' . esc_attr( $var ) . '" />';
$hidden_rows['_wpmem_reg_page'] = '<input name="wpmem_reg_page" type="hidden" value="' . esc_url( get_permalink() ) . '" />';
if ( $redirect_to != get_permalink() ) {
$hidden_rows['_wpmem_redirect_to'] = '<input name="redirect_to" type="hidden" value="' . esc_url( $redirect_to ) . '" />';
}
/**
* Filter the hidden form rows.
*
* @since 3.2.0
*
* @param array $hidden_rows
* @param string $tag
*/
$hidden_rows = apply_filters( 'wpmem_register_hidden_rows', $hidden_rows, $tag );
// Assemble hidden fields HTML.
$hidden = '';
foreach ( $hidden_rows as $hidden_row ) {
$hidden .= $hidden_row . $args['n'];
}
/**
* Filter the hidden field HTML.
*
* @since 2.9.0
*
* @param string $hidden The generated HTML of hidden fields.
* @param string $tag Toggle new registration or profile update. new|edit.
*/
$hidden = apply_filters( 'wpmem_register_hidden_fields', $hidden, $tag );
// Add the hidden fields to the form.
$form.= $hidden;
// Create buttons and wrapper.
$button_text = ( $tag == 'edit' ) ? $args['submit_update'] : $args['submit_register'];
$button_html = array(
'reset' => ( $args['show_clear_form'] ) ? '<input name="reset" type="reset" value="' . esc_attr( $args['clear_form'] ) . '" class="' . wpmem_sanitize_class( $args['button_class'] ) . '" /> ' : '',
'submit' => '<input name="submit" type="submit" value="' . esc_attr( $button_text ) . '" class="' . wpmem_sanitize_class( $args['button_class'] ) . '" />',
);
$buttons = $button_html['reset'] . $args['n'] . $button_html['submit'] . $args['n'];
/**
* Filter the HTML for form buttons.
*
* The string passed through the filter includes the buttons, as well as the HTML wrapper elements.
*
* @since 2.9.0
* @since 3.2.6 Added $button_html parameter
*
* @param string $buttons The generated HTML of the form buttons.
* @param string $tag Toggle new registration or profile update. new|edit.
* @param array $button_html The individual button html.
*/
$buttons = apply_filters( 'wpmem_register_form_buttons', $buttons, $tag, $button_html );
// Add the buttons to the form.
$form.= $args['buttons_before'] . $args['n'] . $buttons . $args['buttons_after'] . $args['n'];
// Add the required field notation to the bottom of the form.
$form.= $args['req_label_before'] . $args['req_label'] . $args['req_label_after'];
// Apply the heading.
if ( 'edit' == $tag ) {
/**
* Filter the default heading in User Profile edit mode.
*
* @since 2.7.5
* @since 3.3.0 Moved into main registration function (from profile shortcode).
*
* @param string The default edit mode heading.
*/
$heading = ( isset( $heading ) && '' != $heading ) ? $heading : apply_filters( 'wpmem_user_edit_heading', wpmem_get_text( 'profile_heading' ) );
} else {
/**
* Filter the registration form heading.
*
* @since 2.8.2
*
* @param string $str
* @param string $tag Toggle new registration or profile update. new|edit.
*/
$heading = ( isset( $heading ) && '' != $heading ) ? $heading : apply_filters( 'wpmem_register_heading', wpmem_get_text( 'register_heading' ), $tag );
}
$form = $args['heading_before'] . $heading . $args['heading_after'] . $args['n'] . $form;
// Apply fieldset wrapper.
$form = $args['fieldset_before'] . $args['n'] . $form . $args['n'] . $args['fieldset_after'];
// Apply attribution if enabled.
$form = $form . $this->attribution();
// Apply nonce. Nonce uses $tag value of the form processor, NOT the form builder.
$nonce = ( $tag == 'edit' ) ? 'update' : 'register';
$form = wp_nonce_field( 'wpmem_longform_nonce', '_wpmem_' . $nonce . '_nonce', true, false ) . $args['n'] . $form;
// Apply form wrapper.
$novalidate = ( $args['novalidate'] ) ? 'novalidate' : '';
$enctype = ( $enctype == 'multipart/form-data' ) ? ' enctype="multipart/form-data"' : '';
$form = '<form name="form" method="post"' . $enctype . ' action="' . esc_attr( $args['post_to'] ) . '" id="' . wpmem_sanitize_class( $args['form_id'] ) . '" class="' . wpmem_sanitize_class( $args['form_class'] ) . '"' . $novalidate . '>' . $args['n'] . $form . $args['n'] . '</form>';
// Apply anchor.
$form = '<a id="register"></a>' . $args['n'] . $form;
// Apply main div wrapper.
$form = $args['main_div_before'] . $args['n'] . $form . $args['n'] . $args['main_div_after'] . $args['n'];
// Remove line breaks if enabled for easier filtering later.
$form = ( $args['strip_breaks'] ) ? $this->strip_breaks( $form, $rows ) : $form; //str_replace( array( "\n", "\r", "\t" ), array( '','','' ), $form ) : $form;
// If there is an image input type, include the following script.
$form = ( $form_has_file ) ? $form . '
<script>
var loadFile = function(event, clicked_id) {
var reader = new FileReader();
var the_id = clicked_id + "_img";
reader.onload = function() {
var output = document.getElementById(the_id);
output.src = reader.result;
};
reader.readAsDataURL(event.target.files[0]);
};
</script>' : $form;
/**
* Filter the generated HTML of the entire form.
*
* @since 2.7.4
*
* @param string $form The HTML of the final generated form.
* @param string $tag Toggle new registration or profile update. new|edit.
* @param array $rows {
* An array containing the form rows.
*
* @type string order Field display order.
* @type string meta Field meta tag (not used for display).
* @type string type Input field type (not used for display).
* @type string value Input field value (not used for display).
* @type string values The possible values for the field (dropdown, multiple select/checkbox, radio group).
* @type string label_text Raw text for the label (not used for display).
* @type string row_before Opening wrapper tag around the row.
* @type string label Label tag.
* @type string field_before Opening wrapper tag before the input tag.
* @type string field The field input tag.
* @type string field_after Closing wrapper tag around the input tag.
* @type string row_after Closing wrapper tag around the row.
* }
* @param string $hidden The HTML string of hidden fields
*/
$form = apply_filters( 'wpmem_register_form', $form, $tag, $rows, $hidden );
/**
* Filter before the form.
*
* This rarely used filter allows you to stick any string onto the front of
* the generated form.
*
* @since 2.7.4
*
* @param string $str The HTML to add before the form. Default null.
* @param string $tag Toggle new registration or profile update. new|edit.
*/
$form = apply_filters( 'wpmem_register_form_before', '', $tag ) . $form;
$wpmem->forms->set_reg_form_showing( true );
// Return the generated form.
return $form;
} // End register_form().
/**
* Strip line breaks from form.
*
* Function removes line breaks and tabs. Checks for textarea fields
* before stripping line breaks.
*
* @since 3.1.8
*
* @param string $form
* @param array $rows
* @return string $form
*/
private function strip_breaks( $form, $rows ) {
foreach( $rows as $key => $row ) {
if ( 'textarea' == $row['type'] ) {
$textareas[ $key ] = $row['field'];
}
}
$form = str_replace( array( "\n", "\r", "\t" ), array( '','','' ), $form );
if ( ! empty ( $textareas ) ) {
foreach ( $textareas as $textarea ) {
$stripped = str_replace( array( "\n", "\r", "\t" ), array( '','','' ), $textarea );
$form = str_replace( $stripped, $textarea, $form );
}
}
return $form;
}
/**
* Appends WP-Members registration fields to wp-login.php registration form.
*
* @since 2.8.7
* @since 3.1.1 Updated to support new (3.1.0) field types.
* @since 3.1.6 Updated to support new fields array. Added WC classes.
* @since 3.1.8 Added $process parameter.
* @since 3.3.0 Ported from wpmem_do_wp_register_form() in wp-registration.php.
*
* @global stdClass $wpmem
* @param string $process
*/
function wp_register_form( $process = 'wp' ) {
global $wpmem;
$wpmem_fields = wpmem_fields( $process );
// Check if this is WooCommerce account page.
$is_woo = false;
if ( 'woo' == $process ) {
$is_woo = true;
} else {
if ( function_exists( 'is_account_page' ) ) {
$is_woo = ( is_account_page() ) ? true : $is_woo;
}
}
if ( isset( $wpmem_fields ) && is_array( $wpmem_fields ) ) {
unset( $wpmem_fields['username'] );
if ( $is_woo ) {
// Woo has its own setting for password fields.
unset( $wpmem_fields['password'] );
unset( $wpmem_fields['confirm_password'] );
}
foreach ( $wpmem_fields as $meta_key => $field ) {
$req = ( $field['required'] ) ? ( ( $is_woo ) ? ' <span class="required">*</span>' : ' <span class="req">' . wpmem_get_text( 'wp_form_required' ) . '</span>' ) : '';
// File fields not yet supported for this form.
if ( $field['register'] && $meta_key != 'user_email' && $field['type'] != 'file' && $field['type'] != 'image' ) {
if ( 'checkbox' == $field['type'] ) {
if ( 'tos' == $meta_key ) {
$tos_link_text = $this->get_tos_link( $field, 'woo' );
}
$label = ( 'tos' == $meta_key ) ? $tos_link_text : __( $field['label'], 'wp-members' );
$val = esc_attr( wpmem_get( $meta_key, '' ) ); // ( isset( $_POST[ $meta_key ] ) ) ? esc_attr( $_POST[ $meta_key ] ) : '';
$val = ( ! $_POST && $field['checked_default'] ) ? $field['checked_value'] : $val;
$row_before = '<p class="wpmem-checkbox">';
$label = '<label for="' . $meta_key . '">' . $label . $req . '</label>';
$input = wpmem_form_field( $meta_key, $field['type'], $field['checked_value'], $val );
$row_after = '</p>';
} elseif ( 'hidden' == $field['type'] ) {
// Handle hidden fields
$row_before = '';
$label = '';
$input = wpmem_form_field( array(
'name' => $meta_key,
'type' => $field['type'],
'value' => $field['value'],
'compare' => $valtochk,
'required' => $field['required'],
) );
$row_after = '';
} else {
$row_before = ( $is_woo ) ? '<p class="woocommerce-FormRow woocommerce-FormRow--wide form-row form-row-wide">' : '<p>';
$label = '<label for="' . $meta_key . '">' . __( $field['label'], 'wp-members' ) . $req . '</label>';
$label .= ( 'multicheckbox' == $field['type'] ) ? '<br />' : '';
// determine the field type and generate accordingly...
switch ( $field['type'] ) {
case( 'textarea' ):
$input = '<textarea name="' . $meta_key . '" id="' . $meta_key . '" class="textarea">';
$input.= esc_textarea( wpmem_get( $meta_key, '' ) ); // ( isset( $_POST[ $meta_key ] ) ) ? esc_textarea( $_POST[ $meta_key ] ) : '';
$input.= '</textarea>';
break;
case( 'select' ):
case( 'multiselect' ):
case( 'multicheckbox' ):
case( 'radio' ):
case( 'membership' ):
$row_before = ( $is_woo && ( 'select' == $field['type'] || 'multiselect' == $field['type'] || 'membership' == $field['type'] ) ) ? $row_before : '<p class="' . $field['type'] . '">';
$valtochk = sanitize_text_field( wpmem_get( $meta_key, '' ) ); // ( isset( $_POST[ $meta_key ] ) ) ? sanitize_text_field( $_POST[ $meta_key ] ) : '';
$formfield_args = array(
'name' => $meta_key,
'type' => $field['type'],
'value' => $field['values'],
'compare' => $valtochk,
'required' => $field['required'],
'class' => ( $is_woo && ( 'select' == $field['type'] || 'multiselect' == $field['type'] || 'membership' == $field['type'] ) ) ? 'woocommerce-Input woocommerce-Input--text input-text' : $field['type'],
);
if ( 'multicheckbox' == $field['type'] || 'multiselect' == $field['type'] ) {
$formfield_args['delimiter'] = $field['delimiter'];
}
$input = wpmem_form_field( $formfield_args );
break;
case( 'file' ):
case( 'image' ):
// Field type not supported for this yet.
break;
default:
$class = ( $is_woo ) ? 'woocommerce-Input woocommerce-Input--text input-text' : 'input';
//$input = '<input type="' . $field['type'] . '" name="' . $meta_key . '" id="' . $meta_key . '" class="' . $class . '" value="';
$formfield_args = array(
'name' => $meta_key,
'type' => $field['type'],
'value' => wpmem_sanitize_field( wpmem_get( $meta_key, '' ), $field['type'] ),
'compare' => ( isset( $field['compare'] ) ) ? $field['compare'] : '',
'required' => $field['required'],
'class' => $class,
'placeholder' => ( isset( $field['placeholder'] ) ) ? $field['placeholder'] : '',
'pattern' => ( isset( $field['pattern'] ) ) ? $field['pattern'] : false,
'title' => ( isset( $field['title'] ) ) ? $field['title'] : false,
'min' => ( isset( $field['min'] ) ) ? $field['min'] : false,
'max' => ( isset( $field['max'] ) ) ? $field['max'] : false,
'rows' => ( isset( $field['rows'] ) ) ? $field['rows'] : false,
'cols' => ( isset( $field['cols'] ) ) ? $field['cols'] : false,
);
// Add timestamp support.
if ( 'timestamp' == $field['type'] ) {
$formfield_args['timestamp_display'] = $field['timestamp_display'];
}
$input = wpmem_form_field( $formfield_args );
//$input.= ( isset( $_POST[ $meta_key ] ) ) ? esc_attr( $_POST[ $meta_key ] ) : '';
//$input.= '" size="25" />';
break;
}
$row_after = '</p>';
}
// if the row is set to display, add the row to the form array
$rows[ $meta_key ] = array(
'type' => $field['type'],
'row_before' => $row_before,
'label' => $label,
'field' => $input,
'row_after' => $row_after,
);
}
}
// Do recaptcha if enabled.
if ( ! $is_woo && isset( $wpmem->captcha ) && $wpmem->captcha != 0 ) {
$row_before = '<p>';
$row_after = '</p>';
$label = '';
$captcha = '';
if ( in_array( $wpmem->captcha, array( 1, 3, 4 ) ) ) {
$captcha = WP_Members_Captcha::recaptcha();
} elseif ( 5 == $wpmem->captcha ) {
$captcha = WP_Members_Captcha::hcaptcha();
} elseif ( 2 == $wpmem->captcha ) {
$row = WP_Members_Captcha::rs_captcha( 'array' );
$label = $row['label']; //$row['label_text'];
$captcha = $row['img'] . $row['hidden'] . $row['field'];
}
if ( 4 == $wpmem->captcha ) {
$row_before = '';
$row_after = '';
}
$rows['captcha'] = array(
'type' => '',
'row_before' => $row_before,
'row_after' => $row_after,
'label' => $label,
'field' => $captcha,
);
}
if ( isset( $rows ) && is_array( $rows ) ) {
/**
* Filter the native registration form rows.
*
* @since 2.9.3.
*
* @param array $rows The custom rows added to the form.
*/
$rows = apply_filters( 'wpmem_native_form_rows', $rows );
foreach ( $rows as $row_item ) {
if ( $row_item['type'] == 'checkbox' ) {
echo $row_item['row_before'] . $row_item['field'] . $row_item['label'] . $row_item['row_after'];
} else {
echo $row_item['row_before'] . $row_item['label'] . $row_item['field'] . $row_item['row_after'];
}
}
}
}
}
/**
* Appends WP-Members registration fields to Users > Add New User screen.
*
* @since 2.9.0
* @since 3.1.1 Updated to support new (3.1.0) field types and user activation.
* @since 3.1.6 Updated to support new fields array.
* @since 3.3.0 Ported from wpmem_do_wp_newuser_form() in wp-registration.php.
*
* @global stdClass $wpmem
*/
function wp_newuser_form() {
global $wpmem;
echo '<table class="form-table"><tbody>';
$wpmem_fields = wpmem_fields(); // @todo For now in 3.5+, load all fields. Perhaps at some point we go to wpmem_fields( 'add_new' );
$exclude = wpmem_get_excluded_meta( 'wp-register' );
foreach ( $wpmem_fields as $meta_key => $field ) {
if ( ! $field['native'] && ! in_array( $meta_key, $exclude ) ) {
$req = ( $field['required'] ) ? ' <span class="description">' . wpmem_get_text( 'wp_form_required' ) . '</span>' : '';
$class = ( 'radio' == $field['type']
|| 'checkbox' == $field['type']
|| 'date' == $field['type'] ) ? '' : ' class="form-field" ';
echo '<tr' . $class . '>
<th scope="row">
<label for="' . $meta_key . '">' . __( $field['label'], 'wp-members' ) . $req . '</label>
</th>
<td>';
// determine the field type and generate accordingly.
// All fields use the following:
$args['name'] = $meta_key;
$args['type'] = $field['type'];
$args['required'] = $field['required'];
$args['placeholder'] = ( isset( $field['placeholder'] ) ) ? $field['placeholder'] : '';
$args['pattern'] = ( isset( $field['pattern'] ) ) ? $field['pattern'] : '';
$args['title'] = ( isset( $field['title'] ) ) ? $field['title'] : '';
$posted_meta = wpmem_get( $meta_key, '' );
switch ( $field['type'] ) {
case( 'select' ):
$val = sanitize_text_field( $posted_meta ); // ( isset( $_POST[ $meta_key ] ) ) ? sanitize_text_field( $_POST[ $meta_key ] ) : '';
$args['value'] = $field['values'];
$args['compare'] = $val;
echo wpmem_form_field( $args );
break;
case( 'textarea' ):
$args['value'] = esc_textarea( $posted_meta ); // ( isset( $_POST[ $meta_key ] ) ) ? esc_textarea( $_POST[ $meta_key ] ) : '';
echo wpmem_form_field( $args );
break;
case( 'checkbox' ):
$val = sanitize_text_field( $posted_meta ); // ( isset( $_POST[ $meta_key ] ) ) ? sanitize_text_field( $_POST[ $meta_key ] ) : '';
$val = ( ! $_POST && $field['checked_default'] ) ? $field['checked_value'] : $val;
$args['value'] = $field['checked_value'];
$args['compare'] = $val;
echo wpmem_form_field( $args );
break;
case( 'multiselect' ):
case( 'multicheckbox' ):
case( 'radio' ):
case( 'membership' );
$args['value'] = $field['values'];
$args['compare'] = sanitize_text_field( $posted_meta ); // ( isset( $_POST[ $meta_key ] ) ) ? sanitize_text_field( $_POST[ $meta_key ] ) : '';
if ( 'multicheckbox' == $field['type'] || 'multiselect' == $field['type'] ) {
$args['delimiter'] = $field['delimiter'];
}
echo wpmem_form_field( $args );
break;
case( 'file' ):
case( 'image' ):
echo 'Not currently supported for this form';
break;
default:
$args['value'] = esc_attr( $posted_meta ); // ( isset( $_POST[ $meta_key ] ) ) ? esc_attr( $_POST[ $meta_key ] ) : '';
echo wpmem_form_field( $args );
break;
}
echo '</td>
</tr>';
}
}
// If moderated registration is enabled, add checkbox to set user as active.
if ( 1 == $wpmem->mod_reg ) {
echo '<tr>
<th scope="row">
<label for="activate_user">' . wpmem_get_text( 'wp_form_activate' ) . '</label>
</th>
<td>' . wpmem_form_field( array( 'name' => 'activate_user', 'type' => 'checkbox', 'value' => 1, 'compare' => '' ) ) . '</td>
</tr>';
}
echo '</tbody></table>';
}
/**
* Create an attribution link in the form.
*
* @since 2.6.0
* @since 3.1.1 Updated to use new object setting.
* @since 3.3.0 Ported from wpmem_inc_attribution() in forms.php.
*
* @global object $wpmem
* @return string $str
*/
function attribution() {
global $wpmem;
$str = '
<div align="center">
<small>Powered by <a href="https://rocketgeek.com" target="_blank">WP-Members</a></small>
</div>';
return ( 1 == $wpmem->attrib ) ? $str : '';
}
/**
* Settings for building Short Form (login).
*
* Replaces individual legacy functions and filters for
* the short forms, combined into a single method.
*
* @since 3.3.0
* @since 3.4.0 Change inputs.
*
* @global stdClass $post
* @global stdClass $wpmem
*
* @param string $form login|changepassword|resetpassword|forgotusername
* @param array $args
* @return string $form
*/
function do_shortform( $form, $args = array() ) {
$input_arrays = array(
'login' => array(
array(
'name' => wpmem_get_text( 'login_username' ),
'type' => 'text',
'tag' => 'log',
'class' => 'username',
'div' => 'div_text',
),
array(
'name' => wpmem_get_text( 'login_password' ),
'type' => 'password',
'tag' => 'pwd',
'class' => 'password',
'div' => 'div_text',
),
),
'changepassword' => array(
array(
'name' => wpmem_get_text( 'pwdchg_password1' ),
'type' => 'password',
'tag' => 'pass1',
'class' => 'password',
'div' => 'div_text',
),
array(
'name' => wpmem_get_text( 'pwdchg_password2' ),
'type' => 'password',
'tag' => 'pass2',
'class' => 'password',
'div' => 'div_text',
),
),
'resetpassword' => array(
array(
'name' => wpmem_get_text( 'login_username' ),
'type' => 'text',
'tag' => 'user',
'class' => 'username',
'div' => 'div_text',
),
),
'forgotusername' => array(
array(
'name' => wpmem_get_text( 'username_email' ),
'type' => 'text',
'tag' => 'user_email',
'class' => 'username',
'div' => 'div_text',
),
),
'reconfirm' => array(
array(
'name' => wpmem_get_text( 'login_username' ),
'type' => 'text',
'tag' => 'user',
'class' => 'username',
'div' => 'div_text',
),
)
);
/**
* Filter the array of change password form fields.
*
* @since 2.9.0
* @deprecated 3.3.0 Use wpmem_{$form}_form_defaults instead.
*
* @param array $default_inputs An array matching the elements used by default.
*/
$default_inputs = apply_filters_deprecated( 'wpmem_inc_' . $form . '_inputs', array( $input_arrays[ $form ] ), '3.3.0', 'wpmem_' . $form . '_form_defaults' );
$form_arrays = array(
'login' => array(
'heading' => wpmem_get_text( 'login_heading' ),
'action' => 'login',
'button_text' => wpmem_get_text( 'login_button' ),
'inputs' => $default_inputs,
'redirect_to' => ( isset( $args['redirect_to'] ) ) ? $args['redirect_to'] : get_permalink(),
),
'changepassword' => array(
'heading' => wpmem_get_text( 'pwdchg_heading' ),
'action' => 'pwdchange',
'button_text' => wpmem_get_text( 'pwdchg_button' ),
'inputs' => $default_inputs,
),
'resetpassword' => array(
'heading' => wpmem_get_text( 'pwdreset_heading' ),
'action' => 'pwdreset',
'button_text' => wpmem_get_text( 'pwdreset_button' ),
'inputs' => $default_inputs,
),
'forgotusername' => array(
'heading' => wpmem_get_text( 'username_heading' ),
'action' => 'getusername',
'button_text' => wpmem_get_text( 'username_button' ),
'inputs' => $default_inputs,
),
'reconfirm' => array(
'heading' => wpmem_get_text( 'reconfirm_heading' ),
'action' => 'reconfirm',
'button_text' => wpmem_get_text( 'reconfirm_button' ),
'inputs' => $default_inputs,
),
);
/**
* Filter the arguments to override form defaults.
*
* @since 2.9.0
* @deprecated 3.3.0 Use wpmem_{$form}_form_defaults instead.
*
* @param array $args An array of arguments to use. Default null. (login|changepassword|resetpassword|forgotusername)
*/
$args = apply_filters_deprecated( 'wpmem_inc_' . $form . '_args', array(''), '3.3.0', 'wpmem_' . $form . '_form_defaults' );
$arr = wp_parse_args( $args, $form_arrays[ $form ] );
/**
* Filter the arguments to override change password form defaults.
*
* @since 3.3.0
* @since 3.4.6 Added $form of the filter being used.
*
* @param array $args An array of arguments to use.
* @param string $form Tag of the form being used (login|changepassword|resetpassword|forgotusername)
*/
$arr = apply_filters( 'wpmem_' . $form . '_form_defaults', $arr, $form );
return $this->login_form( '', $arr );
}
/**
* Applies the post restricted message above the short form.
*
* @since 3.3.0
*
* @global stdClass $wpmem
*
* @return string $str The generated message.
*/
public function add_restricted_msg() {
$str = '';
if ( "success" != wpmem_get_form_state() ) {
$dialogs = get_option( 'wpmembers_dialogs' );
// The message shown above blocked content.
$msg = wpmem_get_text( 'restricted_msg' );
/**
* Filter the message args.
*
* @since 3.5.0
*
* @todo Eliminate <p> tag from before/after. Use CSS to adjust the div size instead.
* @todo Rework localization of custom strings into dialogs class.
*
* @param array $args {
* The various parts of the restricted dialog.
*
* @type string $msg The actual message.
* @type string $before The opening HTML tags.
* @type string $after The closing HTML tags (no need to change this if you're not changing the opening tag type).
* }
*/
$args = apply_filters( 'wpmem_restricted_msg_args', array(
'msg' => ( $dialogs['restricted_msg'] == $msg ) ? $msg : __( stripslashes( $dialogs['restricted_msg'] ), 'wp-members' ),
'before' => '<div id="wpmem_restricted_msg"><p>',
'after' => '</p></div>',
));
$full_html = $args['before'] . $args['msg'] . $args['after'];
/**
* Filter the post restricted message.
*
* @since 2.7.3
* @since 3.2.0 Added raw message string and HTML as separate params.
*
* @param string $full_html The post restricted message with HTML.
* @param string $message The raw message string.
* @param string $before The 'before' HTML wrapper.
* @param string $after The 'after' HTML wrapper.
*/
$str = apply_filters( 'wpmem_restricted_msg', $full_html, $args['msg'], $args['before'], $args['after'] );
}
return $str;
}
/**
* Alias for handing the default WP login form.
*
* @since 3.3.2
*/
function wp_login_form( $args ) {
return wp_login_form( $args );
}
/**
* Generate TOS field with link.
*
* @since 3.3.5
*
* @param array $field
* @param string $tag
* @return string
*/
function get_tos_link( $field, $tag = 'new' ) {
global $wpmem;
// Determine if TOS is a WP page or not.
$tos_content = stripslashes( get_option( 'wpmembers_tos' ) );
if ( has_shortcode( $tos_content, 'wpmem_tos' ) || has_shortcode( $tos_content, 'wp-members' ) ) {
$tos_link_url = do_shortcode( $tos_content );
$tos_link_tag = '<a href="' . esc_url( $tos_link_url ) . '" target="_blank">';
} else {
$tos_link_url = esc_url( add_query_arg( 'tos', 'display' ) );
$tos_link_tag = "<a href=\"#\" onClick=\"window.open('" . esc_url( $tos_link_url ) . "','tos');\">";
}
/**
* Filter the TOS link.
*
* @since 3.2.6
*
* @param string $tos_link_tag
* @param string $tos_link_url
*/
$tos_link_tag = apply_filters( 'wpmem_tos_link_tag', $tos_link_tag, $tos_link_url );
/**
* Filter the TOS link text.
*
* @since 2.7.5
*
* @param string The link text.
* @param string $tag Toggle new registration or profile update. new|edit.
*/
$tos_link_text = apply_filters( 'wpmem_tos_link_txt', wpmem_get_text( 'register_tos' ), $tag );
// If filtered value is not the default label, use that, otherwise use label.
// @note: if default changes, this check must change.
if ( __( 'Please indicate that you agree to the %s Terms of Service %s', 'wp-members' ) == $tos_link_text ) {
if ( __( 'TOS', 'wp-members' ) != $field['label'] && __( 'Terms of Service', 'wp-members' ) != $field['label'] ) {
$tos_link_text = $field['label'];
}
}
// If tos string does not contain link identifiers (%s), wrap the whole string.
if ( ! strpos( $tos_link_text, '%s' ) ) {
$tos_link_text = '%s' . $tos_link_text . '%s';
}
return sprintf( $tos_link_text, $tos_link_tag, '</a>' );
}
function get_reg_row_keys() {
return array( 'meta', 'type', 'value', 'values', 'label_text', 'row_before', 'label', 'field_before', 'field', 'field_after', 'row_after' );
}
function is_reg_form_showing() {
return $this->reg_form_showing;
}
function set_reg_form_showing( $value ) {
$this->reg_form_showing = $value;
}
} // End of WP_Members_Forms class.
<?php
/**
Replaces wp-members/includes/admin/tabs/class-wp-members-pwd-reset.php
Patches included:
* addresses potential issues in escaping for password reset link in 3.5.0.
trims potential whitespace for the three query args, runs rawurlencode on the values,
checks permalink structure and applies trailing slash if not default permalink but not
if it is default permalin, uses esc_url_raw() on resulting link (after filtering) rather
than esc_url().
*/
/**
* An object class for WP-Members Password Reset.
*
* @since 3.3.5
* @since 3.3.8 Rebuild processing to utilize WP native functions and user_activation_key.
*/
class WP_Members_Pwd_Reset {
/**
* Message containers.
*
* @since 3.3.5
*/
public $invalid_key;
public $invalid_user;
public $key_is_expired;
public $request_new_key;
private $reset_key;
public $content = false;
/**
* Meta containers
*
* @since 3.3.5
*/
public $action = 'set_password_from_key';
/**
* Initialize the class.
*
* @since 3.3.5
*/
function __construct() {
// Password reset key is generated in add_reset_to_email() using WP's get_password_reset_key()
add_action( 'init', array( $this, 'init' ) );
add_filter( 'wpmem_email_filter', array( $this, 'add_reset_key_to_email' ), 10, 3 );
add_action( 'template_redirect', array( $this, 'handle_reset' ), 20 );
//add_filter( 'the_content', array( $this, 'display_content' ), 100 );
}
function init() {
$defaults = array(
'invalid_key' => wpmem_get_text( 'pwd_reset_invalid_key' ), // "Invalid key."
'invalid_user' => wpmem_get_text( 'pwd_reset_invalid_user' ), // "Invalid user."
'key_is_expired' => wpmem_get_text( 'pwd_reset_key_is_expired' ), // "Sorry, the password reset key is expired."
'request_new_key' => wpmem_get_text( 'pwd_reset_request_new_key' ), // "Request a new reset key."
);
/**
* Filter default dialogs.
*
* @since 3.3.8
*
* @param array $defaults {
* @type string $invalid_key
* @type string $invalid_user
* @type string $key_is_expired
* @type string $request_new_key
* }
*/
$defaults = apply_filters( 'wpmem_pwd_reset_default_dialogs', $defaults );
foreach ( $defaults as $key => $value ) {
$this->{$key} = $value;
}
}
function handle_reset() {
// User has to be not logged in and action needs to be 'set_password_from_key'
if ( ! is_user_logged_in() && $this->action == wpmem_get( 'a', false, 'request' ) && ! is_admin() ) {
$key = sanitize_text_field( wpmem_get( 'key', false, 'request' ) );
$login = sanitize_text_field( wpmem_get( 'login', false, 'request' ) );
$pass1 = wpmem_get( 'pass1', false );
$form_submitted = ( 1 == wpmem_get( 'formsubmit' ) && $this->action == wpmem_get( 'a', false ) ) ? true : false;
// Set an error container.
$errors = new WP_Error();
// Check the user. get_user_by() will return false if user_login does not exist.
$is_user = get_user_by( 'login', $login );
if ( false == $is_user ) {
$errors->add( 'invalid_user', $this->error_msg( 'invalid_user', $this->invalid_user ) );
}
/**
* Validate the key.
*
* WP_Error will be invalid_key or expired_key. Process triggers password_reset_expiration filter
* filtering DAY_IN_SECONDS default. Filter password_reset_key_expired is also triggered filtering
* the return value (which can be used to override the expired/invalid check based on user_id).
*
* WP filter/actions triggered:
* - password_reset_expiration
* - password_reset_key_expired
*
* @see https://developer.wordpress.org/reference/functions/check_password_reset_key/
* @param string Hash to validate sending user's password.
* @param string The user login.
* @return WP_User|WP_Error WP_User object on success, WP_Error object for invalid or expired keys (invalid_key|expired_key).
*/
$user = check_password_reset_key( $key, $login );
if ( $user->has_errors() ) {
$errors->add( 'invalid_key', $this->error_msg( 'invalid_key', $this->invalid_key ) );
}
// If the password change form was submitted, validate the result.
if ( $form_submitted ) {
// Verify nonce.
if ( ! wp_verify_nonce( $_REQUEST['_wpmem_pwdchange_nonce'], 'wpmem_shortform_nonce' ) ) {
$errors->add( 'reg_generic', $this->error_msg( 'reg_generic', wpmem_get_text( 'reg_generic' ) ) );
}
// Can't have an empty pass1.
if ( '' == $pass1 || false == $pass1 ) {
$errors->add( 'password_empty', $this->error_msg( 'password_empty', wpmem_get_text( 'pwdchangempty' ) ) );
}
// Make sure submitted passwords match.
if ( $pass1 != wpmem_get( 'pass2', false ) ) {
$errors->add( 'password_reset_mismatch', $this->error_msg( 'password_reset_mismatch', wpmem_get_text( 'pwdchangerr' ) ) );
}
/** This action is documented in wp-login.php */
// do_action( 'validate_password_reset', $errors, $user );
}
/**
* Filter validation result.
*
* @since 3.4.7
*
* @param stdClass $errors
* @param stdClass $user
* @param boolean $form_submitted
*/
$errors = apply_filters( 'wpmem_validate_password_reset', $errors, $user, $form_submitted );
// If form was submitted.
if ( $form_submitted ) {
if ( ! $errors->has_errors() ) {
reset_password( $user, $pass1 );
$this->content = wpmem_get_display_message( 'pwdchangesuccess', $this->error_msg( 'pwdchangesuccess' ) ) . wpmem_login_form( 'pwdreset' );
} else {
$this->content = $errors->get_error_message() . wpmem_change_password_form();
}
} else {
// Password change form has not been submitted yet.
if ( ! $errors->has_errors() ) {
$this->content = wpmem_change_password_form();
} else {
$this->content = $errors->get_error_message();
}
}
}
}
/**
* Add reset key to the email.
*
* @since 3.3.5
*
* @param array $arr
* @param array $wpmem_fields
* @param array $field_data
* @return array $arr
*/
function add_reset_key_to_email( $arr, $wpmem_fields, $field_data ) {
if ( $arr['toggle'] == 'repass' ) {
$user = get_user_by( 'ID', $arr['user_id'] );
// Get the stored key.
$key = get_password_reset_key( $user );
if ( is_wp_error( $key ) ) {
$error_string = $key->get_error_message();
$link = "The following error occured generating the password reset key:
" . $error_string;
} else {
$query_args = array(
'a' => trim( $this->action ),
'key' => trim( $key ),
'login' => trim( $user->user_login ),
);
// urlencode, primarily for user_login with a space.
$query_args = array_map( 'rawurlencode', $query_args );
// Generate reset link.
$link = ( ! get_option( 'permalink_structure' ) ) ? wpmem_profile_url() : trailingslashit( wpmem_profile_url() );
$link = add_query_arg( $query_args, $link );
/**
* Filter the password reset URL in the email.
*
* @since 3.4.5
*
* @param string $link
* @param array $query_args
* @param object $user
*/
$link = apply_filters( 'wpmem_pwd_reset_email_link', $link, $query_args, $user );
}
$sanitized_link = esc_url_raw( $link );
// Does email body have the [reset_link] shortcode?
if ( strpos( $arr['body'], '[reset_link]' ) ) {
$arr['body'] = str_replace( '[reset_link]', $sanitized_link, $arr['body'] );
} else {
// Add text and link to the email body.
$arr['body'] = $arr['body'] . "\r\n"
. $sanitized_link;
}
}
return $arr;
}
/**
* Display page content to user.
*
* @since 3.3.5
*
* @param string $content
* @return string $content
*/
function display_content( $content ) {
return ( false != $this->content ) ? $this->content : $content;
}
function error_msg( $code, $message = false ) {
if ( $message ) {
$error = wpmem_get_display_message( $code, $message . '<br /><a href="' . esc_url( wpmem_profile_url( 'pwdreset' ) ) . '">' . $this->request_new_key . '</a>' );
} else {
$error = wpmem_get_display_message( $code );
}
/**
* Filters the password reset error message.
*
* @since 3.4.4
*
* @param string $error The generated HTML error message.
* @param string $code The error code generated.
* @param string $message The plain text error message.
*/
return apply_filters( 'wpmem_pwd_reset_error_msg', $error, $code, $message );
}
}
<?php
/**
Replaces wp-members/includes/class-wp-members.php
Patches included:
* Corrects the filename of the WP_CLI wpmem command's db tools file. The include is originally listed as
"class-db-tools.php" and should be "class-wp-members-cli-db-tools.php". Possible fixes are to just
rename the file or to change the include path/filename. This patch file changes the include filename
(which is ultimately what the fix will be in the next update).
*/
/**
* The WP_Members Class.
*
* This is the main WP_Members object class. This class contains functions
* for loading settings, shortcodes, hooks to WP, plugin dropins, constants,
* and registration fields. It also manages whether content should be blocked.
*
* @package WP-Members
* @subpackage WP_Members Object Class
* @since 3.0.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit();
}
class WP_Members {
/**
* The state of plugin install/upgrade.
*
* @since 3.5.0
*/
public $install_state;
/**
* Plugin version.
*
* @since 3.0.0
* @access public
* @var string
*/
public $version = WPMEM_VERSION;
/**
* Database version
*
* @since 3.2.2
* @access public
* @var string
*/
public $db_version = WPMEM_DB_VERSION;
/**
* Plugin path.
*
* @since 3.3.0
* @access public
* @var string
*/
public $path;
/**
* Plugin __FILE__.
*
* @since 3.3.0
* @access public
* @var string
*/
public $name;
/**
* Plugin slug.
*
* @since 3.3.0
* @access public
* @var string
*/
public $slug;
/**
* Plugin URL.
*
* @since 3.3.0
* @access public
* @var string
*/
public $url;
/**
* Content block settings.
*
* @since 3.0.0
* @access public
* @var array
*/
public $block;
/**
* Excerpt settings.
*
* @since 3.0.0
* @access public
* @var array
*/
public $show_excerpt;
/**
* Show login form settings.
*
* @since 3.0.0
* @access public
* @var array
*/
public $show_login;
/**
* Show registration form settings.
*
* @since 3.0.0
* @access public
* @var array
*/
public $show_reg;
/**
* Auto-excerpt settings.
*
* @since 3.0.0
* @access public
* @var array
*/
public $autoex;
/**
* Notify admin settings.
*
* @since 3.0.0
* @access public
* @var string
*/
public $notify;
/**
* Moderated registration settings.
*
* @since 3.0.0
* @access public
* @var string
*/
public $mod_reg;
/**
* Captcha settings.
*
* @since 3.0.0
* @access public
* @var array
*/
public $captcha;
/**
* Enable expiration extension settings.
*
* @since 3.0.0
* @access public
* @var string
*/
public $use_exp;
/**
* Expiration extension enable trial period.
*
* @since 3.0.0
* @access public
* @var string
*/
public $use_trial;
/**
*
*
* @since 3.0.0
* @access public
* @var array
*/
public $warnings;
/**
* Enable drop-ins setting.
*
* @since 3.1.9
* @access public
* @var string
*/
public $dropins = 0;
/**
* Container for enabled dropins.
*
* @since 3.1.9
* @access public
* @var array
*/
public $dropins_enabled = array();
/**
* Current plugin action container.
*
* @since 3.0.0
* @access public
* @var string
*/
public $action;
/**
* Regchk container.
*
* @since 3.0.0
* @access public
* @var string
*/
public $regchk;
/**
* User page settings.
*
* @since 3.0.0
* @access public
* @var array
*/
public $user_pages;
/**
* Custom Post Type settings.
*
* @since 3.0.0
* @access public
* @var array
*/
public $post_types;
/**
* Setting for applying texturization.
*
* @since 3.1.7
* @access public
* @var boolean
*/
public $texturize;
/**
* Enable product creation.
*
* @since 3.2.0
* @access public
* @var boolean
*/
public $enable_products;
/**
* Enable logged-in menu clones.
*
* @since 3.2.0
* @access public
* @var string
*/
public $clone_menus;
/**
* Container for error messages.
*
* @since 3.2.0
* @access public
* @var stdClass
*/
public $error;
/**
* Container for admin notices.
*
* @since 3.3.0
* @access public
* @var array
*/
public $admin_notices;
/**
* Container for stylesheet setting.
*
* @since 3.2.7
* @access public
* @var string
*/
public $select_style;
/**
* Container for the CSS URL.
*
* @since Unknown
* @access public
* @var string
*/
public $cssurl;
/**
* The attribution setting.
*
* @since Unknown
* @access public
* @var string
*/
public $attrib;
/**
* Container for form tags.
*
* @since Unknown
* @access public
* @var array
* @todo verify @var
*/
public $form_tags;
/**
* Container for dropin folder location.
*
* @since 3.3.0
* @access public
* @var string
*/
public $dropin_dir;
/**
* REST conditional.
*
* @since 3.3.2
* @access public
* @var boolean
*/
public $is_rest = false;
/**
* Temporary setting for activation link.
*
* @todo Will default to 0 until 3.4.0, then 1 until 3.5.0 at which point we'll remove the old process.
*
* @since 3.3.5
* @access public
* @var string
*/
public $act_link = 0;
/**
* Default file upload directory.
*
* @since 3.3.8
* @access public
* @var string
*/
public $upload_base = 'wpmembers';
/**
* Opt in to update and security notifications.
*
* @since 3.4.2
*/
public $optin;
/**
* Container for WooCommerce-specific settings.
*
* @since Unknown
* @access public
* @var array
*/
public $woo;
/**
* The forms object.
*
* @since Unknown
* @access public
* @var object
*/
public $forms;
/**
* The fields object.
*
* @since Unknown
* @access public
* @var object
*/
public $fields;
/**
* The API object.
*
* @since Unknown
* @access public
* @var object
*/
public $api;
/**
* The shortcodes object.
*
* @since Unknown
* @access public
* @var object
*/
public $shortcodes;
/**
* The membership object.
*
* @since Unknown
* @access public
* @var object
*/
public $membership;
/**
* The email object.
*
* @since Unknown
* @access public
* @var object
*/
public $email;
/**
* The user object.
*
* @since Unknown
* @access public
* @var object
*/
public $user;
/**
* The menus object.
*
* @since Unknown
* @access public
* @var object
*/
public $menus;
/**
* The dialogs object.
*
* @since Unknown
* @access public
* @var object
*/
public $dialogs;
/**
* The clone menus object.
*
* @since Unknown
* @access public
* @var object
*/
public $menus_clone;
/**
* The password reset object.
*
* @since Unknown
* @access public
* @var object
*/
public $pwd_reset;
/**
* The new account email activation object.
*
* @since Unknown
* @access public
* @var object
*/
public $act_newreg;
/**
* The admin object class.
*
* @since Unknown
* @access public
* @var object
*/
public $admin;
/**
* Objects for premium extensions.
*
* @access public
* @var object
*/
public $advanced;
public $downloads;
public $editor;
public $invite_codes;
public $mailchimp;
public $salesforce;
public $security;
public $stop_spam;
public $usertrack;
public $user_list;
public $woo_connector;
public $excluded_meta;
// @deprecated
public $pwd_link;
public $login_error;
public $style; // @todo verify if this is deprecated.
/**
* Plugin initialization function.
*
* @since 3.0.0
* @since 3.1.6 Dependencies now loaded by object.
*/
function __construct() {
// Constants.
$this->slug = 'wp-members.php';
$this->path = plugin_dir_path( __DIR__ );
$this->name = trailingslashit( $this->path ) . $this->slug;
$this->url = plugin_dir_url ( __DIR__ );
$settings = get_option( 'wpmembers_settings' );
// Validate that v3 settings are loaded.
if ( ! isset( $settings['version'] )
|| $settings['version'] != $this->version
|| ! isset( $settings['db_version'] )
|| $settings['db_version'] != $this->db_version ) {
// Load installation routine and update settings.
require_once $this->path . 'includes/install.php';
$settings = wpmem_do_install();
}
/**
* Filter the options before they are loaded into constants.
*
* @since 2.9.0
* @since 3.0.0 Moved to the WP_Members class.
*
* @param array $this->settings An array of the WP-Members settings.
*/
$settings = apply_filters( 'wpmem_settings', $settings );
// Assemble settings.
foreach ( $settings as $key => $val ) {
// @todo Leaving error message and password reset settings values in for now for rollback backwards compatibility.
// Later, we'll remove those values in the upgrade, so this can be cleaned up.
if ( 'pwd_link' != $key || 'login_error' != $key || 'shortcodes' != $key ) {
$this->{$key} = $val;
}
}
// Load dependent files.
$this->load_dependencies();
// @todo Until I think of a better place to put this.
$this->optin = get_option( 'wpmembers_optin' );
// Load user pages (login, register, user profile).
$this->load_user_pages();
// Set the stylesheet.
$this->cssurl = ( 'use_custom' == $settings['select_style'] ) ? $this->cssurl : $this->url . 'assets/css/forms/generic-no-float' . wpmem_get_suffix() . '.css';
$this->forms = new WP_Members_Forms; // Load forms.
$this->api = new WP_Members_API; // Load api.
$this->shortcodes = new WP_Members_Shortcodes( $settings ); // Load shortcodes.
$this->membership = new WP_Members_Products(); // Load membership plans
$this->email = new WP_Members_Email; // Load email functions
$this->user = new WP_Members_User( $this ); // Load user functions.
$this->menus = new WP_Members_Menus();
$this->dialogs = new WP_Members_Dialogs();
$this->pwd_reset = new WP_Members_Pwd_Reset;
// @deprecated Clone menus are technically deprecated, but kept in the plugin for legacy users.
if ( $this->clone_menus ) {
$this->menus_clone = new WP_Members_Clone_Menus(); // Load clone menus.
}
// @todo Is this a temporary fix?
$this->email->load_from();
/**
* Fires after main settings are loaded.
*
* @since 3.0
* @deprecated 3.2.0 Use wpmem_after_init instead.
*/
do_action_deprecated( 'wpmem_settings_loaded', array(), '3.2.0', 'wpmem_after_init' );
// Preload the expiration module, if available.
$exp_active = ( function_exists( 'wpmem_exp_init' ) || function_exists( 'wpmem_set_exp' ) ) ? true : false;
define( 'WPMEM_EXP_MODULE', $exp_active );
// Load actions and filters.
$this->load_hooks();
// Load contants.
$this->load_constants();
// Load dropins.
if ( $this->dropins ) {
$this->load_dropins();
}
// Check for anything that we should stop execution for (currently just the default tos).
if ( 'display' == wpmem_get( 'tos', false, 'get' ) ) {
// If themes are not loaded, we don't need them.
$user_themes = ( ! defined( 'WP_USE_THEMES' ) ) ? define( 'WP_USE_THEMES', false ) : '';
$this->load_default_tos();
die();
}
}
/**
* Plugin initialization function to load hooks.
*
* @since 3.0.0
*/
function load_hooks() {
/**
* Fires before action and filter hooks load.
*
* @since 3.0.0
* @since 3.1.6 Fires before hooks load.
*/
do_action( 'wpmem_load_hooks' );
// Add actions.
add_action( 'init', array( $this, 'load_textdomain' ) );
add_action( 'init', array( $this->membership, 'add_cpt' ), 0 ); // Adds membership plans custom post type.
add_action( 'init', array( $this, 'load_dependent_classes' ) );
add_action( 'widgets_init', array( $this, 'widget_init' ) ); // initializes the widget
add_action( 'rest_api_init', array( $this, 'rest_init' ) );
add_action( 'pre_get_posts', array( $this, 'do_hide_posts' ), 20 );
add_action( 'template_redirect', array( $this, 'get_action' ) );
add_action( 'login_enqueue_scripts', array( $this, 'enqueue_style_wp_login' ) ); // styles the native registration
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_style' ) ); // Enqueues the stylesheet.
add_action( 'wp_enqueue_scripts', array( $this, 'loginout_script' ) );
add_action( 'customize_register', array( $this, 'customizer_settings' ) );
add_action( 'wp_footer', array( $this, 'invisible_captcha' ) );
add_action( 'wpmem_after_init', array( $this, 'after_wpmem_loaded' ) );
if ( is_admin() ) {
add_action( 'init', array( $this, 'load_admin' ) ); // @todo Check user role to load correct dashboard
}
if ( is_user_logged_in() ) {
add_action( 'wpmem_pwd_change', array( $this->user, 'set_password' ), 9, 2 );
add_action( 'wpmem_pwd_change', array( $this->user, 'set_as_logged_in' ), 10 );
}
add_action( 'register_form', 'wpmem_wp_register_form' ); // Adds fields to the default wp registration
// Add filters.
add_filter( 'the_content', array( $this, 'do_securify' ), 99 );
add_filter( 'comments_open', array( $this, 'do_securify_comments' ), 99, 2 ); // securifies the comments
add_filter( 'wpmem_securify', array( $this, 'reg_securify' ) ); // adds success message on login form if redirected
add_filter( 'rest_prepare_post', array( $this, 'do_securify_rest' ), 10, 3 );
add_filter( 'rest_prepare_page', array( $this, 'do_securify_rest' ), 10, 3 );
foreach( $this->post_types as $post_type ) {
add_filter( "rest_prepare_{$post_type}", array( $this, 'do_securify_rest' ), 10, 3 );
}
//add_filter( 'query_vars', array( $this, 'add_query_vars' ), 10, 2 ); // adds custom query vars
add_filter( 'get_pages', array( $this, 'filter_get_pages' ) );
add_filter( 'wp_get_nav_menu_items', array( $this, 'filter_nav_menu_items' ), null, 3 );
add_filter( 'get_previous_post_where', array( $this, 'filter_get_adjacent_post_where' ) );
add_filter( 'get_next_post_where', array( $this, 'filter_get_adjacent_post_where' ) );
add_filter( 'allow_password_reset', array( $this->user, 'no_reset' ) ); // no password reset for non-activated users
// If registration is moderated, check for activation (blocks backend login by non-activated users).
if ( 1 == $this->mod_reg ) {
add_filter( 'authenticate', array( $this->user, 'check_activated' ), 99, 3 );
}
// Replace login error object, if profile page is set, AND it is not the wp-login.php page.
if ( isset( $this->user_pages['profile'] )
&& '' != $this->user_pages['profile']
&& 'wp-login.php' !== $GLOBALS['pagenow']
&& ! wpmem_is_woo_active() ) {
add_filter( 'lostpassword_url', array( $this, 'lost_pwd_url' ), 10, 2 );
}
if ( function_exists( 'wpmem_custom_translation_strings' ) ) {
add_filter( 'wpmem_fields', array( $this->forms, 'localize_fields' ), 9 );
}
/**
* Fires after action and filter hooks load.
*
* @since 3.0.0
* @since 3.1.6 Was wpmem_load_hooks, now wpmem_hooks_loaded.
*/
do_action( 'wpmem_hooks_loaded' );
}
/**
* Load drop-ins.
*
* @since 3.0.0
*
* @todo This is experimental. The function and its operation is subject to change.
*/
function load_dropins() {
/**
* Fires before dropins load (for adding additional drop-ins).
*
* @since 3.0.0
* @since 3.1.6 Fires before dropins.
*/
do_action( 'wpmem_load_dropins' );
/**
* Filters the drop-in file directory.
*
* @since 3.0.0
* @since 3.3.0 Filter previously unpublished, changed hook name.
*
* @param string $wpmem->dropin_dir The drop-in file directory.
*/
$dir = apply_filters( 'wpmem_dropin_dir', $this->dropin_dir );
// Load any drop-ins.
$settings = get_option( 'wpmembers_dropins' );
$this->dropins_enabled = ( $settings ) ? $settings : array();
if ( ! empty( $this->dropins_enabled ) ) {
foreach ( $this->dropins_enabled as $filename ) {
$dropin = $dir . $filename;
if ( file_exists( $dropin ) ) {
include_once $dropin;
}
}
}
/**
* Fires before dropins load (for adding additional drop-ins).
*
* @since 3.0.0
* @since 3.1.6 Was wpmem_load_dropins, now wpmem_dropins_loaded.
*/
do_action( 'wpmem_dropins_loaded' );
}
/**
* Loads pre-3.0 constants (included primarily for add-on compatibility).
*
* @since 3.0.0
* @since 3.3.0 Deprecated all but exp and trl constants.
*
* @todo Can WPMEM_MOD_REG be deprecated?
*/
function load_constants() {
( ! defined( 'WPMEM_MOD_REG' ) ) ? define( 'WPMEM_MOD_REG', $this->mod_reg ) : '';
( ! defined( 'WPMEM_USE_EXP' ) ) ? define( 'WPMEM_USE_EXP', $this->use_exp ) : '';
( ! defined( 'WPMEM_USE_TRL' ) ) ? define( 'WPMEM_USE_TRL', $this->use_trial ) : '';
}
/**
* Load dependent files.
*
* @since 3.1.6
*/
function load_dependencies() {
/**
* Filter the location and name of the pluggable file.
*
* @since 2.9.0
* @since 3.1.6 Moved in load order to come before dependencies.
*
* @param string The path to WP-Members plugin functions file.
*/
$wpmem_pluggable = apply_filters( 'wpmem_plugins_file', WP_PLUGIN_DIR . '/wp-members-pluggable.php' );
// Preload any custom functions, if available.
if ( file_exists( $wpmem_pluggable ) ) {
include( $wpmem_pluggable );
}
require_once $this->path . 'includes/vendor/rocketgeek-utilities/loader.php';
require_once $this->path . 'includes/class-wp-members-api.php';
require_once $this->path . 'includes/class-wp-members-clone-menus.php';
require_once $this->path . 'includes/class-wp-members-captcha.php';
require_once $this->path . 'includes/class-wp-members-dialogs.php';
require_once $this->path . 'includes/class-wp-members-email.php';
require_once $this->path . 'includes/class-wp-members-forms.php';
require_once $this->path . 'includes/class-wp-members-menus.php';
require_once $this->path . 'includes/class-wp-members-products.php';
require_once $this->path . 'includes/class-wp-members-pwd-reset.php';
require_once $this->path . 'includes/class-wp-members-shortcodes.php';
require_once $this->path . 'includes/class-wp-members-user.php';
require_once $this->path . 'includes/class-wp-members-user-profile.php';
require_once $this->path . 'includes/class-wp-members-validation-link.php';
require_once $this->path . 'includes/class-wp-members-widget.php';
require_once $this->path . 'includes/class-wp-members-woocommerce-integration.php';
require_once $this->path . 'includes/api/api.php';
require_once $this->path . 'includes/api/api-email.php';
require_once $this->path . 'includes/api/api-forms.php';
require_once $this->path . 'includes/api/api-products.php';
require_once $this->path . 'includes/api/api-settings.php';
require_once $this->path . 'includes/api/api-users.php';
require_once $this->path . 'includes/api/api-utilities.php';
//require_once $this->path . 'includes/blocks/class-wp-members-blocks.php';
if ( defined( 'WP_CLI' ) && WP_CLI ) {
require_once $this->path . 'includes/cli/class-wp-members-cli.php';
require_once $this->path . 'includes/cli/class-wp-members-cli-user.php';
require_once $this->path . 'includes/cli/class-wp-members-cli-settings.php';
require_once $this->path . 'includes/cli/class-wp-members-cli-db-tools.php';
}
require_once $this->path . 'includes/deprecated.php';
require_once $this->path . 'includes/legacy/dialogs.php'; // File is totally deprecated at this point; eval for removal.
}
/**
* Load classes that depend on the $wpmem object class to be fully loaded.
*
* @since 3.4.7
*/
public function load_dependent_classes() {
if ( wpmem_is_woo_active() ) {
$this->woo = new WP_Members_WooCommerce_Integration( $this );
}
}
/**
* Load admin API and dependencies.
*
* Determines which scripts to load and actions to use based on the
* current users capabilities.
*
* @since 2.5.2
* @since 3.1.0 Added admin api object.
* @since 3.1.7 Moved from main plugin file as wpmem_chk_admin() to main object.
*/
function load_admin() {
/**
* Fires before initialization of admin options.
*
* @since 2.9.0
*/
do_action( 'wpmem_pre_admin_init' );
/**
* Load the admin api class.
*
* @since 3.1.0
*/
require_once $this->path . 'includes/admin/class-wp-members-admin-api.php';
$this->admin = new WP_Members_Admin_API;
/**
* Fires after initialization of admin options.
*
* @since 2.9.0
*/
do_action( 'wpmem_after_admin_init' );
}
/**
* Gets the requested action.
*
* @since 3.0.0
*
* @global string $wpmem_a The WP-Members action variable.
*/
function get_action() {
// Get the action being done (if any).
$this->action = sanitize_text_field( wpmem_get( 'a', '', 'request' ) );
// For backward compatibility with processes that check $wpmem_a.
global $wpmem_a;
$wpmem_a = $this->action;
/**
* Fires when the wpmem action is retrieved.
*
* @since 3.1.7
* @since 3.4.2 Added action as a param.
*/
do_action( 'wpmem_get_action', $this->action );
// Get the regchk value (if any).
$this->regchk = $this->get_regchk( $this->action );
}
/**
* Gets the regchk value.
*
* regchk is a legacy variable that contains information about the current
* action being performed. Login, logout, password, registration, profile
* update functions all return a specific value that is stored in regchk.
* This value and information about the current action can then be used to
* determine what content is to be displayed by the securify function.
*
* @since 3.0.0
*
* @global string $wpmem_a The WP-Members action variable.
*
* @param string $action The current action.
* @return string The regchk value.
*/
function get_regchk( $action ) {
switch ( $action ) {
case 'login':
$regchk = $this->user->login();
break;
case 'logout':
$regchk = $this->user->logout();
break;
case 'pwdchange':
case 'set_password_from_key':
$regchk = $this->user->password_update( 'change' );
break;
case 'pwdreset':
global $wpmem;
$regchk = $this->user->password_update( 'link' );
break;
case 'getusername':
$regchk = $this->user->retrieve_username();
break;
case 'reconfirm':
$regchk = $this->user->resend_confirm();
break;
case 'register':
case 'update':
$regchk = wpmem_user_register( $action );
break;
default:
$regchk = ( isset( $regchk ) ) ? $regchk : '';
break;
}
/**
* Filter wpmem_regchk.
*
* The value of regchk is determined by functions that may be run in the get_regchk function.
* This value determines what happens in the wpmem_securify() function.
*
* @since 2.9.0
* @since 3.0.0 Moved to get_regchk() in WP_Members object.
*
* @param string $this->regchk The value of wpmem_regchk.
* @param string $this->action The $wpmem_a action.
*/
$regchk = apply_filters( 'wpmem_regchk', $regchk, $action );
// Legacy global variable for use with older extensions.
global $wpmem_regchk;
$wpmem_regchk = $regchk;
return $regchk;
}
/**
* Determines if content should be blocked.
*
* This function was originally stand alone in the core file and
* was moved to the WP_Members class in 3.0.
*
* @since 3.0.0
* @since 3.3.0 Added $post_id
* @since 3.4.0 Added $is_post_check to allow for individual post checking.
*
* @global object $post The WordPress Post object.
*
* @param int $post_id
* @return bool $block true|false
*/
function is_blocked( $post_id = false ) {
global $post;
$is_post_check = ( false == $post_id ) ? false : true;
if ( $post || $post_id ) {
$the_post = ( false == $post_id ) ? $post : get_post( $post_id );
$meta = wpmem_get_block_setting( $the_post->ID );
// Backward compatibility for old block/unblock meta.
if ( ! $meta ) {
// Check for old meta.
$old_block = get_post_meta( $the_post->ID, 'block', true );
$old_unblock = get_post_meta( $the_post->ID, 'unblock', true );
$meta = ( $old_block ) ? 1 : ( ( $old_unblock ) ? 0 : $meta );
}
// Setup defaults.
$defaults = array(
'post_id' => $the_post->ID,
'post_type' => $the_post->post_type,
'block' => ( isset( $this->block[ $the_post->post_type ] ) && $this->block[ $the_post->post_type ] == 1 ) ? true : false,
'block_meta' => $meta,
'block_type' => ( isset( $this->block[ $the_post->post_type ] ) ) ? $this->block[ $the_post->post_type ] : 0,
);
/**
* Filter the block arguments.
*
* @since 2.9.8
* @since 3.0.0 Moved to is_blocked() in WP_Members object.
* @since 3.3.0 Passes $defaults, second argument deprecated.
*
* @param array $args $defaults.
* @param array $defaults Deprecated 3.3.0. @todo Obsolete in 3.5.0
*/
$args = apply_filters( 'wpmem_block_args', $defaults, $defaults );
// Merge $args with defaults.
$args = ( wp_parse_args( $args, $defaults ) );
if ( $is_post_check || is_single() || is_page() || wpmem_is_rest() ) {
switch( $args['block_type'] ) {
case 1: // If content is blocked by default.
$args['block'] = ( $args['block_meta'] == '0' ) ? false : $args['block'];
break;
case 0 : // If content is unblocked by default.
$args['block'] = ( $args['block_meta'] == '1' ) ? true : $args['block'];
break;
}
} else {
$args['block'] = false;
}
} else {
$args = array( 'block' => false );
}
// Don't block user pages.
$args['block'] = ( in_array( get_permalink(), $this->user_pages ) ) ? false : $args['block'];
/**
* Filter the block boolean.
*
* @since 2.7.5
*
* @param bool $args['block']
* @param array $args {
* An array of arguments used in the function.
*
* @type string $post_id
* @type string $post_type
* @type string $block
* @type string $block_meta
* @tyep string $block_type
* }
*/
return apply_filters( 'wpmem_block', $args['block'], $args );
}
/**
* The Securify Content Filter.
*
* This is the primary function that picks up where get_action() leaves off.
* Determines whether content is shown or hidden for both post and pages. This
* is a filter function for the_content.
*
* @link https://developer.wordpress.org/reference/functions/the_content/
* @link https://developer.wordpress.org/reference/hooks/the_content/
*
* @since 3.0.0
*
* @global object $post The WordPress Post object.
* @global string $wpmem_themsg Contains messages to be output.
* @param string $content
* @return string $content
*/
function do_securify( $content = null ) {
global $post, $wpmem_themsg;
$orig_content = $content;
$content = ( is_single() || is_page() ) ? $content : wpmem_do_excerpt( $content );
if ( $this->regchk == "captcha" ) {
global $wpmem_captcha_err;
$wpmem_themsg = wpmem_get_text( 'reg_captcha_err' ) . '<br /><br />' . $wpmem_captcha_err;
}
// Block/unblock Posts.
if ( ! is_user_logged_in() && true == $this->is_blocked() ) {
// If there is a regchk action, show the login and/or registration forms.
if ( $this->regchk ) {
$content = wpmem_get_display_message( $this->regchk, $wpmem_themsg );
$content .= ( 'loginfailed' == $this->regchk || 'success' == $this->regchk ) ? wpmem_login_form() : wpmem_register_form();
} else {
// Toggle shows excerpt above login/reg on posts/pages.
global $wp_query;
if ( isset( $wp_query->query_vars['page'] ) && $wp_query->query_vars['page'] > 1 ) {
// Shuts down excerpts on multipage posts if not on first page.
$content = '';
} elseif ( isset( $this->show_excerpt[ $post->post_type ] ) && 1 == $this->show_excerpt[ $post->post_type ] ) {
// @todo Can this be condensed or eliminated?
$len = strpos( $content, '<span id="more' );
if ( false === $len ) {
$content = wpmem_do_excerpt( $content );
} else {
$content = substr( $content, 0, $len );
}
} else {
// Empty all content.
$content = '';
}
// Build up default view based on settings.
$content = $content . wpmem_restricted_message();
$content = ( isset( $this->show_login[ $post->post_type ] ) && 1 == $this->show_login[ $post->post_type ] ) ? $content . wpmem_login_form() : $content;
$content = ( isset( $this->show_reg[ $post->post_type ] ) && 1 == $this->show_reg[ $post->post_type ] ) ? $content . wpmem_register_form() : $content;
}
// Protects comments if expiration module is used and user is expired.
} elseif ( is_user_logged_in() && true == $this->is_blocked() ) {
// Allows for a view of the forms in the Customizer.
if ( is_customize_preview() ) {
if ( get_theme_mod( 'wpmem_show_logged_out_state', false ) ) {
$content = '';
if ( get_theme_mod( 'wpmem_show_form_message_dialog', false ) ) {
$content = $this->dialogs->login_failed();
} else {
$content = wpmem_restricted_message();
}
$content = ( isset( $this->show_login[ $post->post_type ] ) && 1 == $this->show_login[ $post->post_type ] ) ? $content . wpmem_login_form() : $content;
$content = ( isset( $this->show_reg[ $post->post_type ] ) && 1 == $this->show_reg[ $post->post_type ] ) ? $content . wpmem_register_form() : $content;
}
} else {
// @todo Test with expired membership.
if ( 1 == $this->use_exp && function_exists( 'wpmem_do_expmessage' ) ) {
/**
* Filters the user expired message used by the PayPal extension.
*
* @since 3.2.0
*
* @param string $message
* @param string $content
*/
$content = apply_filters( 'wpmem_do_expmessage', wpmem_do_expmessage( $content ), $content );
}
}
}
/**
* Filter the value of $content after wpmem_securify has run.
*
* @since 2.7.7
* @since 3.0.0 Moved to new method in WP_Members Class.
* @since 3.4.0 Added $orig_content param.
*
* @param string $content The content after securify has run.
*/
$content = apply_filters( 'wpmem_securify', $content, $orig_content );
return $content;
}
/**
* Securifies the comments.
*
* If the user is not logged in and the content is blocked
* (i.e. $wpmem->is_blocked() returns true), function loads a
* dummy/empty comments template.
*
* @since 2.9.9
* @since 3.2.0 Moved wpmem_securify_comments() to main class, renamed.
* @since 3.3.2 Added $post_id.
*
* @param bool $open Whether the current post is open for comments.
* @param int $post_id The post ID.
* @return bool $open True if current post is open for comments, otherwise false.
*/
function do_securify_comments( $open, $post_id ) {
$open = ( ! is_user_logged_in() && wpmem_is_blocked( $post_id ) ) ? false : $open;
/**
* Filters whether comments are open or not.
*
* @since 3.0.0
* @since 3.2.0 Moved to main class.
* @since 3.3.2 Added $post_id.
*
* @param bool $open true if current post is open for comments, otherwise false.
*/
$open = apply_filters( 'wpmem_securify_comments', $open, $post_id );
if ( ! $open ) {
/** This filter is documented in wp-includes/comment-template.php */
add_filter( 'comments_array', array( $this, 'do_securify_comments_array' ), 10, 2 );
}
return $open;
}
/**
* Empties the comments array if content is blocked.
*
* @since 3.0.1
* @since 3.2.0 Moved wpmem_securify_comments_array() to main class, renamed.
*
* @param array $comments
* @param int $post_id
* @return array $comments The comments array.
*/
function do_securify_comments_array( $comments , $post_id ) {
// @todo This logic is checked in do_securify_comments() before the filter is added. Is it needed here?
$comments = ( ! is_user_logged_in() && wpmem_is_blocked( $post_id ) ) ? array() : $comments;
return $comments;
}
/**
* Handles REST request.
*
* @since 3.3.2
*
* @param WP_REST_Response $response The response object.
* @param WP_Post $post Post object.
* @param WP_REST_Request $request Request object.
* @return
*/
function do_securify_rest( $response, $post, $request ) {
// Only run if $response contains "id", otherwise we can't check it as blocked (since it would not contain a post ID).
if ( isset( $response->data['id'] ) ) {
if ( ! is_user_logged_in() ) { // @todo This needs to be changed to check for whether the user has access (for internal requests).
// Response for restricted content
$block_value = wpmem_is_blocked( $response->data['id'] );
if ( $block_value ) {
/**
*
*
* @since 3.4.7
*
* @param
* @param WP_REST_Response $response The response object.
* @param WP_Post $post Post object.
* @param WP_REST_Request $request Request object.
*/
$drop = apply_filters( "wpmem_securify_rest_{$post->post_type}_drop_response_data", array(), $response, $post, $request );
foreach ( $drop as $dropped_key ) {
$response->data[ $dropped_key ] = array();
}
if ( isset( $response->data['content']['rendered'] ) ) {
/**
* Filters restricted content message.
*
* @since 3.3.2
* @since 3.3.4 Added $response, $post, and $request
*
* @param string $message
*/
$response->data['content']['rendered'] = apply_filters( "wpmem_securify_rest_{$post->post_type}_content", wpmem_get_text( 'rest_content_rendered' ), $response, $post, $request );
}
if ( isset( $response->data['excerpt']['rendered'] ) ) {
/**
* Filters restricted excerpt message.
*
* @since 3.3.2
* @since 3.3.4 Added $response, $post, and $request
*
* @param string $message
*/
$response->data['excerpt']['rendered'] = apply_filters( "wpmem_securify_rest_{$post->post_type}_excerpt", wpmem_get_text( 'rest_excerpt_rendered' ), $response, $post, $request );
}
}
// Response for hidden content. @todo This needs to be changed to check for whether the user has access (for internal requests).
if ( ! is_admin() && in_array( $post->ID, $this->hidden_posts() ) ) {
return new WP_REST_Response( wpmem_get_text( 'rest_404' ), 404 );
}
}
}
return $response;
}
/**
* Adds the successful registration message on the login page if reg_nonce validates.
*
* @since 3.1.7
* @since 3.2.0 Moved to wpmem object, renamed reg_securify()
*
* @param string $content
* @return string $content
*/
function reg_securify( $content ) {
global $wpmem, $wpmem_themsg;
$nonce = wpmem_get( 'reg_nonce', false, 'get' );
if ( $nonce && wp_verify_nonce( $nonce, 'register_redirect' ) ) {
$content = wpmem_get_display_message( 'success', $wpmem_themsg );
$content = $content . wpmem_login_form();
}
return $content;
}
/**
* Runs if the REST API is initialized.
*
* @since 3.3.2
*/
function rest_init() {
$this->is_rest = true;
}
/**
* Gets an array of hidden post IDs.
*
* @since 3.2.0
*
* @global object $wpdb
* @return array $hidden
*/
function hidden_posts() {
global $wpdb;
$hidden = get_option( 'wpmem_hidden_posts' );
if ( false === $hidden ) {
$hidden = $this->update_hidden_posts();
}
return $hidden;
}
/**
* Updates the hidden post array transient.
*
* @since 3.2.0
* @since 3.3.3 Don't include posts from post types not set as handled by WP-Members.
*
* @global object $wpdb
* @return array $hidden
*/
function update_hidden_posts() {
global $wpdb;
$hidden = array();
$default_post_types = array( 'post'=>'Posts', 'page'=>'Page' );
$post_types = array_merge( $this->post_types, $default_post_types );
// $results = $wpdb->get_results( "SELECT post_id FROM " . $wpdb->prefix . "postmeta WHERE meta_key = '_wpmem_block' AND meta_value = 2" );
$results = $wpdb->get_results(
"SELECT
p1.id,
p1.post_type,
m1.meta_key AS _wpmem_block
FROM " . $wpdb->prefix . "posts p1
JOIN " . $wpdb->prefix . "postmeta m1 ON (m1.post_id = p1.id AND m1.meta_key = '_wpmem_block')
WHERE m1.meta_value = '2';"
);
foreach( $results as $result ) {
if ( array_key_exists( $result->post_type, $post_types ) ) {
$hidden[] = $result->id;
}
}
update_option( 'wpmem_hidden_posts', $hidden );
return $hidden;
}
/**
* Gets an array of hidden post IDs.
*
* @since 3.2.0
*
* @global stdClass $wpdb
* @return array $hidden
*/
function get_hidden_posts() {
$hidden = array();
// Return empty array if this is the admin and user can edit posts.
if ( is_admin() && current_user_can( 'edit_posts' ) ) {
return $hidden;
}
// If the user is not logged in, return all hidden posts.
if ( ! is_user_logged_in() ) {
$hidden = $this->hidden_posts();
} else {
// If the user is logged in.
if ( wpmem_is_enabled( 'enable_products' ) ) {
// Get user product access.
$hidden = $this->hidden_posts();
$hidden = ( is_array( $hidden ) ) ? $hidden : array();
// Remove posts with a product the user has access to.
foreach ( wpmem_get_memberships() as $key => $value ) {
if ( wpmem_user_has_access( $key ) ) {
foreach ( $hidden as $post_id ) {
if ( 1 == get_post_meta( $post_id, wpmem_get_membership_meta( $key ), true ) ) {
$hidden_key = array_search( $post_id, $hidden );
unset( $hidden[ $hidden_key ] );
}
}
}
}
// Remove posts that don't have a product assignment (general login).
foreach( $hidden as $hidden_key ) {
$unattached = get_post_meta( $hidden_key, '_wpmem_products', true );
if ( false == $unattached ) {
$hidden_key = array_search( $hidden_key, $hidden );
unset( $hidden[ $hidden_key ] );
}
}
}
}
/**
* Filter the hidden posts array.
*
* @since 3.3.4
*
* @param array $hidden
*/
return apply_filters( 'wpmem_hidden_posts', $hidden );
}
/**
* Hides posts based on settings and meta.
*
* @since 3.2.0
*
* @param array $query
* @return array $query
*/
function do_hide_posts( $query ) {
$hidden_posts = $this->get_hidden_posts();
if ( ! empty( $hidden_posts ) ) {
// Add hidden posts to post__not_in while maintaining any existing exclusions.
$post__not_in = ( ! isset( $query->query_vars['post__not_in'] ) ) ? $hidden_posts : array_merge( $query->query_vars['post__not_in'], $hidden_posts );
/**
* Filter post__not_in.
*
* @since 3.3.4
*
* @param array $post__not_in
*/
$post__not_in = apply_filters( 'wpmem_post__not_in', $post__not_in );
$query->set( 'post__not_in', $post__not_in );
}
return $query;
}
/**
* Filter to hide pages for get_pages().
*
* @since 3.2.0
*
* @global object $wpdb
* @param array $pages
* @return array $pages
*/
function filter_get_pages( $pages ) {
$hidden_posts = $this->get_hidden_posts();
if ( ! empty ( $hidden_posts ) ) {
$new_pages = array();
foreach ( $pages as $key => $page ) {
if ( ! in_array( $page->ID, $hidden_posts ) ) {
$new_pages[ $key ] = $page;
}
}
$pages = $new_pages;
}
return $pages;
}
/**
* Filter to hide menu items.
*
* @since 3.2.0
*
* @param array $items
* @param $menu
* @param array $args
* @return array $items
*/
function filter_nav_menu_items( $items, $menu, $args ) {
$hidden_posts = $this->get_hidden_posts();
if ( ! empty( $hidden_posts ) ) {
foreach ( $items as $key => $item ) {
if ( in_array( $item->object_id, $hidden_posts ) ) {
unset( $items[ $key ] );
}
}
}
return $items;
}
/**
* Filter to remove hidden posts from prev/next links.
*
* @since 3.2.4
*
* @global object $wpmem
* @param string $where
* @return string $where
*/
function filter_get_adjacent_post_where( $where ) {
global $wpmem;
if ( ! is_user_logged_in() ) {
$hidden_posts = $this->get_hidden_posts();
if ( ! empty( $hidden_posts ) ) {
$hidden = implode( ",", $hidden_posts );
$where = $where . " AND p.ID NOT IN ( $hidden )";
}
}
return $where;
}
/**
* Set page locations.
*
* Handles numeric page IDs while maintaining
* compatibility with old full url settings.
*
* @since 3.0.8
*/
function load_user_pages() {
foreach ( $this->user_pages as $key => $val ) {
if ( is_numeric( $val ) ) {
if ( false !== get_post_status( $val ) ) {
$this->user_pages[ $key ] = get_page_link( $val );
} else {
$notice = sprintf( __( 'You have a linked page in the WP-Members page settings that corresponds to a post ID that no longer exists. Please %s review and update the %s page settings %s.', 'wp-members' ), '<a href="' . esc_url( get_admin_url() . '/options-general.php?page=wpmem-settings&tab=options' ) . '">', $key, '</a>' );
$this->admin_notices[] = array(
'type'=>'error',
'notice'=>$notice
);
}
}
}
}
/**
* Returns a requested text string.
*
* This function manages all of the front-end facing text.
* All defaults can be filtered using wpmem_default_text_strings.
*
* @since 3.1.0
* @deprecated 3.5.0 Use wpmem_get_text() Make sure "official" extensions do not use $wpmem->get_text() before making obsolete.
*
* @global object $wpmem
*
* @param string $str
* @return string $text
*/
function get_text( $str ) {
global $wpmem;
return $wpmem->dialogs->get_text( $str );
} // End of get_text().
/**
* Initializes the WP-Members widget.
*
* @since 3.2.0 Replaces widget_wpmemwidget_init
*/
public function widget_init() {
// Register the WP-Members widget.
register_widget( 'widget_wpmemwidget' );
}
/**
* Adds WP-Members query vars to WP's public query vars.
*
* @since 3.2.0
*
* @see https://codex.wordpress.org/Plugin_API/Filter_Reference/query_vars
*
* @param array $qvars
*/
public function add_query_vars ( $qvars ) {
$qvars[] = 'a'; // The WP-Members action variable.
return $qvars;
}
/**
* Enqueues login/out script for the footer.
*
* @since 3.2.0
*/
public function loginout_script() {
if ( is_user_logged_in() ) {
wp_enqueue_script( 'jquery' );
add_action( 'wp_footer', array( $this, 'do_loginout_script' ), 50 );
}
}
/**
* Outputs login/out script for the footer.
*
* @since 3.2.0
*
* @global object $wpmem
*/
public function do_loginout_script() {
global $wpmem;
/** This filter is defined in /includes/api/api.php */
$logout = apply_filters( 'wpmem_logout_link', add_query_arg( 'a', 'logout' ) );
?><script type="text/javascript">
jQuery('.wpmem_loginout').html('<a class="login_button" href="<?php echo esc_url( $logout ); ?>"><?php echo wpmem_get_text( 'menu_logout' ); ?></a>');
</script><?php
}
/**
* Adds WP-Members controls to the Customizer
*
* @since 3.2.0
*
* @param object $wp_customize The Customizer object.
*/
function customizer_settings( $wp_customize ) {
$wp_customize->add_section( 'wp_members' , array(
'title' => 'WP-Members',
'priority' => 190,
) );
// Add settings for output description
$wp_customize->add_setting( 'wpmem_show_logged_out_state', array(
'default' => '1',
'type' => 'theme_mod', //'option'
'capability' => 'edit_theme_options',
'transport' => 'refresh',
) );
// Add settings for output description
$wp_customize->add_setting( 'wpmem_show_form_message_dialog', array(
'default' => '1',
'type' => 'theme_mod', //'option'
'capability' => 'edit_theme_options',
'transport' => 'refresh',
) );
// Add control and output for select field
$wp_customize->add_control( 'wpmem_show_form_logged_out', array(
'label' => __( 'Show forms as logged out', 'wp-members' ),
'section' => 'wp_members',
'settings' => 'wpmem_show_logged_out_state',
'type' => 'checkbox',
'std' => '1'
) );
// Add control for showing dialog
$wp_customize->add_control( 'wpmem_show_form_dialog', array(
'label' => __( 'Show form message dialog', 'wp-members' ),
'section' => 'wp_members',
'settings' => 'wpmem_show_form_message_dialog',
'type' => 'checkbox',
'std' => '0'
) );
}
/**
* Loads the stylesheet for tableless forms.
*
* @since 2.6
* @since 3.2.3 Moved to WP_Members class.
*
* @global object $wpmem The WP_Members object.
*/
function enqueue_style() {
global $wpmem;
wp_enqueue_style ( 'wp-members', wpmem_force_ssl( $wpmem->cssurl ), false, $wpmem->version );
}
/**
* Loads the wp-login.php stylesheet.
*
* @since 3.3.0
*
* @global stdClass $wpmem
*/
function enqueue_style_wp_login() {
global $wpmem;
wp_enqueue_style( 'wp-members', $wpmem->url . 'assets/css/wp-login' . wpmem_get_suffix() . '.css', false, $wpmem->version );
}
/**
* Creates an excerpt on the fly if there is no 'more' tag.
*
* @since 2.6
* @since 3.2.3 Moved to WP_Members class.
* @since 3.2.5 Check if post object exists.
*
* @global object $post The post object.
* @global object $wpmem The WP_Members object.
*
* @param string $content
* @return string $content
*/
function do_excerpt( $content ) {
global $post, $more, $wpmem;
if ( is_object( $post ) ) {
$post_id = $post->ID;
$post_type = $post->post_type;
$autoex = ( isset( $wpmem->autoex[ $post->post_type ] ) && 1 == $wpmem->autoex[ $post->post_type ]['enabled'] ) ? $wpmem->autoex[ $post->post_type ] : false;
// Is there already a 'more' link in the content?
$has_more_link = ( stristr( $content, 'class="more-link"' ) ) ? true : false;
// If auto_ex is on.
if ( $autoex ) {
// Build an excerpt if one does not exist.
if ( ! $has_more_link ) {
$is_singular = ( is_singular( $post->post_type ) ) ? true : false;
if ( $is_singular ) {
// If it's a single post, we don't need the 'more' link.
$more_link_text = '';
$more_link = '';
} else {
// The default $more_link_text.
if ( isset( $wpmem->autoex[ $post->post_type ]['text'] ) && '' != $wpmem->autoex[ $post->post_type ]['text'] ) {
$more_link_text = __( $wpmem->autoex[ $post->post_type ]['text'], 'wp-members' );
} else {
$more_link_text = __( '(more&hellip;)' );
}
// The default $more_link.
$more_link = ' <a href="'. esc_url( get_permalink( $post->ID ) ) . '" class="more-link">' . esc_attr( $more_link_text ) . '</a>';
}
// Apply the_content_more_link filter if one exists (will match up all 'more' link text).
/** This filter is documented in /wp-includes/post-template.php */
$more_link = apply_filters( 'the_content_more_link', $more_link, $more_link_text );
$defaults = array(
'length' => $autoex['length'],
'more_link' => $more_link,
'blocked_only' => false,
);
/**
* Filter auto excerpt defaults.
*
* @since 3.0.9
* @since 3.1.5 Deprecated add_ellipsis, strip_tags, close_tags, parse_shortcodes, strip_shortcodes.
*
* @param array {
* An array of settings to override the function defaults.
*
* @type int $length The default length of the excerpt.
* @type string $more_link The more link HTML.
* @type boolean $blocked_only Run autoexcerpt only on blocked content. default: false.
* }
* @param string $post->ID The post ID.
* @param string $post->post_type The content's post type.
*/
$args = apply_filters( 'wpmem_auto_excerpt_args', $defaults, $post->ID, $post->post_type );
// Merge settings.
$args = wp_parse_args( $args, $defaults );
// Are we only excerpting blocked content?
if ( $args['blocked_only'] ) {
$post_meta = get_post_meta( $post->ID, '_wpmem_block', true );
if ( 1 == $wpmem->block[ $post->post_type ] ) {
// Post type is blocked, if post meta unblocks it, don't do excerpt.
$do_excerpt = ( "0" == $post_meta ) ? false : true;
} else {
// Post type is unblocked, if post meta blocks it, do excerpt.
$do_excerpt = ( "1" == $post_meta ) ? true : false;
}
} else {
$do_excerpt = true;
}
if ( true === $do_excerpt ) {
$content = ( $args['length'] > 0 ) ? wp_trim_words( $content, $args['length'], $args['more_link'] ) : '';
// Check if the more link was added (note: singular has no more_link):
if ( ! $is_singular && ! strpos( $content, $args['more_link'] ) ) {
$content = $content . $args['more_link'];
}
}
}
}
} else {
$post_id = false;
$post_type = false;
}
/**
* Filter the auto excerpt.
*
* @since 2.8.1
* @since 3.0.9 Added post ID and post type parameters.
* @since 3.2.5 Post ID and post type may be false if there is no post object.
*
* @param string $content The content excerpt.
* @param string $post_id The post ID.
* @param string $post_type The content's post type.
*/
$content = apply_filters( 'wpmem_auto_excerpt', $content, $post_id, $post_type );
// Return the excerpt.
return $content;
}
/**
* Convert form tag.
*
* @todo This is temporary to handle form tag conversion.
*
* @since 3.1.7
* @since 3.2.3 Moved to WP_Members class.
* @since 3.3.0 Removed unnecessary tags.
*
* @param string $tag
* @return string $tag
*/
function convert_tag( $tag ) {
switch ( $tag ) {
case 'new':
return 'register';
break;
case 'edit':
case 'update':
return 'profile';
break;
default:
return $tag;
break;
}
return $tag;
}
/**
* Loads translation files.
*
* @since 3.0.0
* @since 3.2.5 Moved to main object, dropped wpmem_ stem.
*/
function load_textdomain() {
// Plugin textdomain.
$domain = 'wp-members';
// Wordpress locale.
/** This filter is documented in wp-includes/l10n.php */
$locale = apply_filters( 'plugin_locale', get_locale(), $domain );
/**
* Filter translation file.
*
* If the translate.wordpress.org language pack is available, it will
* be /wp-content/languages/plugins/wp-members-{locale}.mo by default.
* You can filter this if you want to load a language pack from a
* different location (or different file name).
*
* @since 3.0.0
* @since 3.2.0 Added locale as a parameter.
*
* @param string $file The translation file to load.
* @param string $locale The current locale.
*/
$file = apply_filters( 'wpmem_localization_file', trailingslashit( WP_LANG_DIR ) . 'plugins/' . $domain . '-' . $locale . '.mo', $locale );
$loaded = load_textdomain( $domain, $file );
if ( true == $loaded ) {
return $loaded;
} else {
/**
* Filter translation directory.
*
* @since 3.0.3
* @since 3.2.0 Added locale as a parameter.
*
* @param string $dir The translation directory.
* @param string $locale The current locale.
*/
$dir = apply_filters( 'wpmem_localization_dir', basename( $this->path ) . '/i18n/languages/', $locale );
load_plugin_textdomain( $domain, FALSE, $dir );
}
return;
}
/**
* Load default tos template.
*
* @since 3.2.8
*/
function load_default_tos() {
// Check for custom template or load default.
$custom_template = get_stylesheet_directory() . '/wp-members/templates/tos.php';
if ( file_exists( $custom_template ) ) {
require_once $custom_template;
} else {
require_once $this->path . 'templates/tos.php';
}
}
/**
* Builds defaults for login/out links/buttons.
*
* @since 3.3.5
*
* @param array $args
* @return string $html
*/
function loginout_args( $args = array() ) {
$defaults = array(
'format' => ( isset( $args['format'] ) ) ? $args['format'] : 'link',
'login_redirect_to' => ( isset( $args['login_redirect_to'] ) ) ? $args['login_redirect_to'] : wpmem_current_url(),
'logout_redirect_to' => ( isset( $args['logout_redirect_to'] ) ) ? $args['logout_redirect_to'] : wpmem_current_url(), // @todo - This is not currently active.
'login_text' => ( isset( $args['login_text'] ) ) ? $args['login_text'] : wpmem_get_text( 'loginout_login_text' ),
'logout_text' => ( isset( $args['logout_text'] ) ) ? $args['logout_text'] : wpmem_get_text( 'loginout_logout_text' ),
'class' => ( isset( $args['class'] ) ) ? $args['class'] : 'wpmem_loginout_link',
'id' => ( isset( $args['id'] ) ) ? $args['id'] : 'wpmem_loginout_link',
);
$args = wp_parse_args( $args, $defaults );
$redirect = ( is_user_logged_in() ) ? $args['logout_redirect_to'] : $args['login_redirect_to'];
$text = ( is_user_logged_in() ) ? $args['logout_text'] : $args['login_text'];
if ( is_user_logged_in() ) {
/** This filter is defined in /includes/api/api.php */
$link = apply_filters( 'wpmem_logout_link', add_query_arg( 'a', 'logout' ) );
} else {
$link = wpmem_login_url( $redirect );
}
if ( 'button' == $args['format'] ) {
$html = '<form action="' . esc_url( $link ) . '" id="' . esc_attr( $args['id'] ) . '" class="' . esc_attr( $args['class'] ) . '">';
$html.= ( is_user_logged_in() ) ? '<input type="hidden" name="a" value="logout" />' : '';
$html.= '<input type="submit" value="' . esc_attr( $text ) . '" /></form>';
} else {
$html = sprintf( '<a href="%s" id="%s" class="%s">%s</a>', esc_url( $link ), esc_attr( $args['id'] ), esc_attr( $args['class'] ), esc_attr( $text ) );
}
return $html;
}
/**
* Filters the password URL to point to the WP-Members process.
*
* @since 3.3.5
*/
function lost_pwd_url( $lostpwd_url, $redirect ) {
return wpmem_profile_url( 'pwdreset' );
}
/**
* Google recaptcha v3 (invisible) gives more accurate user scores
* if it is loaded on all pages.
*
* @since 3.4.0
*/
function invisible_captcha() {
if ( 4 == $this->captcha && true !== wpmem_is_reg_form_showing() ) {
echo WP_Members_Captcha::show();
}
}
/**
* Check for errors.
*
* @since 3.4.6
* @since 3.4.8 Check as WP_Error (use is_wp_error()).
*/
public function has_errors() {
return ( is_wp_error( $this->error ) && $this->error->has_errors() ) ? true : false;
}
public function after_wpmem_loaded() {
if ( wpmem_is_enabled( 'act_link' ) ) {
$this->act_newreg = new WP_Members_Validation_Link;
}
}
} // End of WP_Members class.
@edtorrey
Copy link

2025-01-29 12:07EST Resolves display of the Multi-Select selection values input box.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment