ror( $this->check_read_permission( $file ) ) ) { continue; } $data['_file'] = $file; if ( ! $this->does_plugin_match_request( $request, $data ) ) { continue; } $plugins[] = $this->prepare_response_for_collection( $this->prepare_item_for_response( $data, $request ) ); } return new WP_REST_Response( $plugins ); } /** * Checks if a given request has access to get a specific plugin. * * @since 5.5.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise. */ public function get_item_permissions_check( $request ) { if ( ! current_user_can( 'activate_plugins' ) ) { return new WP_Error( 'rest_cannot_view_plugin', __( 'Sorry, you are not allowed to manage plugins for this site.' ), array( 'status' => rest_authorization_required_code() ) ); } $can_read = $this->check_read_permission( $request['plugin'] ); if ( is_wp_error( $can_read ) ) { return $can_read; } return true; } /** * Retrieves one plugin from the site. * * @since 5.5.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_item( $request ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; $data = $this->get_plugin_data( $request['plugin'] ); if ( is_wp_error( $data ) ) { return $data; } return $this->prepare_item_for_response( $data, $request ); } /** * Checks if the given plugin can be viewed by the current user. * * On multisite, this hides non-active network only plugins if the user does not have permission * to manage network plugins. * * @since 5.5.0 * * @param string $plugin The plugin file to check. * @return true|WP_Error True if can read, a WP_Error instance otherwise. */ protected function check_read_permission( $plugin ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; if ( ! $this->is_plugin_installed( $plugin ) ) { return new WP_Error( 'rest_plugin_not_found', __( 'Plugin not found.' ), array( 'status' => 404 ) ); } if ( ! is_multisite() ) { return true; } if ( ! is_network_only_plugin( $plugin ) || is_plugin_active( $plugin ) || current_user_can( 'manage_network_plugins' ) ) { return true; } return new WP_Error( 'rest_cannot_view_plugin', __( 'Sorry, you are not allowed to manage this plugin.' ), array( 'status' => rest_authorization_required_code() ) ); } /** * Checks if a given request has access to upload plugins. * * @since 5.5.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise. */ public function create_item_permissions_check( $request ) { if ( ! current_user_can( 'install_plugins' ) ) { return new WP_Error( 'rest_cannot_install_plugin', __( 'Sorry, you are not allowed to install plugins on this site.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( 'inactive' !== $request['status'] && ! current_user_can( 'activate_plugins' ) ) { return new WP_Error( 'rest_cannot_activate_plugin', __( 'Sorry, you are not allowed to activate plugins.' ), array( 'status' => rest_authorization_required_code(), ) ); } return true; } /** * Uploads a plugin and optionally activates it. * * @since 5.5.0 * * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function create_item( $request ) { global $wp_filesystem; require_once ABSPATH . 'wp-admin/includes/file.php'; require_once ABSPATH . 'wp-admin/includes/plugin.php'; require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; $slug = $request['slug']; // Verify filesystem is accessible first. $filesystem_available = $this->is_filesystem_available(); if ( is_wp_error( $filesystem_available ) ) { return $filesystem_available; } $api = plugins_api( 'plugin_information', array( 'slug' => $slug, 'fields' => array( 'sections' => false, 'language_packs' => true, ), ) ); if ( is_wp_error( $api ) ) { if ( str_contains( $api->get_error_message(), 'Plugin not found.' ) ) { $api->add_data( array( 'status' => 404 ) ); } else { $api->add_data( array( 'status' => 500 ) ); } return $api; } $skin = new WP_Ajax_Upgrader_Skin(); $upgrader = new Plugin_Upgrader( $skin ); $result = $upgrader->install( $api->download_link ); if ( is_wp_error( $result ) ) { $result->add_data( array( 'status' => 500 ) ); return $result; } // This should be the same as $result above. if ( is_wp_error( $skin->result ) ) { $skin->result->add_data( array( 'status' => 500 ) ); return $skin->result; } if ( $skin->get_errors()->has_errors() ) { $error = $skin->get_errors(); $error->add_data( array( 'status' => 500 ) ); return $error; } if ( is_null( $result ) ) { // Pass through the error from WP_Filesystem if one was raised. if ( $wp_filesystem instanceof WP_Filesystem_Base && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->has_errors() ) { return new WP_Error( 'unable_to_connect_to_filesystem', $wp_filesystem->errors->get_error_message(), array( 'status' => 500 ) ); } return new WP_Error( 'unable_to_connect_to_filesystem', __( 'Unable to connect to the filesystem. Please confirm your credentials.' ), array( 'status' => 500 ) ); } $file = $upgrader->plugin_info(); if ( ! $file ) { return new WP_Error( 'unable_to_determine_installed_plugin', __( 'Unable to determine what plugin was installed.' ), array( 'status' => 500 ) ); } if ( 'inactive' !== $request['status'] ) { $can_change_status = $this->plugin_status_permission_check( $file, $request['status'], 'inactive' ); if ( is_wp_error( $can_change_status ) ) { return $can_change_status; } $changed_status = $this->handle_plugin_status( $file, $request['status'], 'inactive' ); if ( is_wp_error( $changed_status ) ) { return $changed_status; } } // Install translations. $installed_locales = array_values( get_available_languages() ); /** This filter is documented in wp-includes/update.php */ $installed_locales = apply_filters( 'plugins_update_check_locales', $installed_locales ); $language_packs = array_map( static function ( $item ) { return (object) $item; }, $api->language_packs ); $language_packs = array_filter( $language_packs, static function ( $pack ) use ( $installed_locales ) { return in_array( $pack->language, $installed_locales, true ); } ); if ( $language_packs ) { $lp_upgrader = new Language_Pack_Upgrader( $skin ); // Install all applicable language packs for the plugin. $lp_upgrader->bulk_upgrade( $language_packs ); } $path = WP_PLUGIN_DIR . '/' . $file; $data = get_plugin_data( $path, false, false ); $data['_file'] = $file; $response = $this->prepare_item_for_response( $data, $request ); $response->set_status( 201 ); $response->header( 'Location', rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, substr( $file, 0, - 4 ) ) ) ); return $response; } /** * Checks if a given request has access to update a specific plugin. * * @since 5.5.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise. */ public function update_item_permissions_check( $request ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; if ( ! current_user_can( 'activate_plugins' ) ) { return new WP_Error( 'rest_cannot_manage_plugins', __( 'Sorry, you are not allowed to manage plugins for this site.' ), array( 'status' => rest_authorization_required_code() ) ); } $can_read = $this->check_read_permission( $request['plugin'] ); if ( is_wp_error( $can_read ) ) { return $can_read; } $status = $this->get_plugin_status( $request['plugin'] ); if ( $request['status'] && $status !== $request['status'] ) { $can_change_status = $this->plugin_status_permission_check( $request['plugin'], $request['status'], $status ); if ( is_wp_error( $can_change_status ) ) { return $can_change_status; } } return true; } /** * Updates one plugin. * * @since 5.5.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function update_item( $request ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; $data = $this->get_plugin_data( $request['plugin'] ); if ( is_wp_error( $data ) ) { return $data; } $status = $this->get_plugin_status( $request['plugin'] ); if ( $request['status'] && $status !== $request['status'] ) { $handled = $this->handle_plugin_status( $request['plugin'], $request['status'], $status ); if ( is_wp_error( $handled ) ) { return $handled; } } $this->update_additional_fields_for_object( $data, $request ); $request['context'] = 'edit'; return $this->prepare_item_for_response( $data, $request ); } /** * Checks if a given request has access to delete a specific plugin. * * @since 5.5.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise. */ public function delete_item_permissions_check( $request ) { if ( ! current_user_can( 'activate_plugins' ) ) { return new WP_Error( 'rest_cannot_manage_plugins', __( 'Sorry, you are not allowed to manage plugins for this site.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! current_user_can( 'delete_plugins' ) ) { return new WP_Error( 'rest_cannot_manage_plugins', __( 'Sorry, you are not allowed to delete plugins for this site.' ), array( 'status' => rest_authorization_required_code() ) ); } $can_read = $this->check_read_permission( $request['plugin'] ); if ( is_wp_error( $can_read ) ) { return $can_read; } return true; } /** * Deletes one plugin from the site. * * @since 5.5.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function delete_item( $request ) { require_once ABSPATH . 'wp-admin/includes/file.php'; require_once ABSPATH . 'wp-admin/includes/plugin.php'; $data = $this->get_plugin_data( $request['plugin'] ); if ( is_wp_error( $data ) ) { return $data; } if ( is_plugin_active( $request['plugin'] ) ) { return new WP_Error( 'rest_cannot_delete_active_plugin', __( 'Cannot delete an active plugin. Please deactivate it first.' ), array( 'status' => 400 ) ); } $filesystem_available = $this->is_filesystem_available(); if ( is_wp_error( $filesystem_available ) ) { return $filesystem_available; } $prepared = $this->prepare_item_for_response( $data, $request ); $deleted = delete_plugins( array( $request['plugin'] ) ); if ( is_wp_error( $deleted ) ) { $deleted->add_data( array( 'status' => 500 ) ); return $deleted; } return new WP_REST_Response( array( 'deleted' => true, 'previous' => $prepared->get_data(), ) ); } /** * Prepares the plugin for the REST response. * * @since 5.5.0 * * @param array $item Unmarked up and untranslated plugin data from {@see get_plugin_data()}. * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function prepare_item_for_response( $item, $request ) { $fields = $this->get_fields_for_response( $request ); $item = _get_plugin_data_markup_translate( $item['_file'], $item, false ); $marked = _get_plugin_data_markup_translate( $item['_file'], $item, true ); $data = array( 'plugin' => substr( $item['_file'], 0, - 4 ), 'status' => $this->get_plugin_status( $item['_file'] ), 'name' => $item['Name'], 'plugin_uri' => $item['PluginURI'], 'author' => $item['Author'], 'author_uri' => $item['AuthorURI'], 'description' => array( 'raw' => $item['Description'], 'rendered' => $marked['Description'], ), 'version' => $item['Version'], 'network_only' => $item['Network'], 'requires_wp' => $item['RequiresWP'], 'requires_php' => $item['RequiresPHP'], 'textdomain' => $item['TextDomain'], ); $data = $this->add_additional_fields_to_object( $data, $request ); $response = new WP_REST_Response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $item ) ); } /** * Filters plugin data for a REST API response. * * @since 5.5.0 * * @param WP_REST_Response $response The response object. * @param array $item The plugin item from {@see get_plugin_data()}. * @param WP_REST_Request $request The request object. */ return apply_filters( 'rest_prepare_plugin', $response, $item, $request ); } /** * Prepares links for the request. * * @since 5.5.0 * * @param array $item The plugin item. * @return array[] */ protected function prepare_links( $item ) { return array( 'self' => array( 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, substr( $item['_file'], 0, - 4 ) ) ), ), ); } /** * Gets the plugin header data for a plugin. * * @since 5.5.0 * * @param string $plugin The plugin file to get data for. * @return array|WP_Error The plugin data, or a WP_Error if the plugin is not installed. */ protected function get_plugin_data( $plugin ) { $plugins = get_plugins(); if ( ! isset( $plugins[ $plugin ] ) ) { return new WP_Error( 'rest_plugin_not_found', __( 'Plugin not found.' ), array( 'status' => 404 ) ); } $data = $plugins[ $plugin ]; $data['_file'] = $plugin; return $data; } /** * Get's the activation status for a plugin. * * @since 5.5.0 * * @param string $plugin The plugin file to check. * @return string Either 'network-active', 'active' or 'inactive'. */ protected function get_plugin_status( $plugin ) { if ( is_plugin_active_for_network( $plugin ) ) { return 'network-active'; } if ( is_plugin_active( $plugin ) ) { return 'active'; } return 'inactive'; } /** * Handle updating a plugin's status. * * @since 5.5.0 * * @param string $plugin The plugin file to update. * @param string $new_status The plugin's new status. * @param string $current_status The plugin's current status. * @return true|WP_Error */ protected function plugin_status_permission_check( $plugin, $new_status, $current_status ) { if ( is_multisite() && ( 'network-active' === $current_status || 'network-active' === $new_status ) && ! current_user_can( 'manage_network_plugins' ) ) { return new WP_Error( 'rest_cannot_manage_network_plugins', __( 'Sorry, you are not allowed to manage network plugins.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ( 'active' === $new_status || 'network-active' === $new_status ) && ! current_user_can( 'activate_plugin', $plugin ) ) { return new WP_Error( 'rest_cannot_activate_plugin', __( 'Sorry, you are not allowed to activate this plugin.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( 'inactive' === $new_status && ! current_user_can( 'deactivate_plugin', $plugin ) ) { return new WP_Error( 'rest_cannot_deactivate_plugin', __( 'Sorry, you are not allowed to deactivate this plugin.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Handle updating a plugin's status. * * @since 5.5.0 * * @param string $plugin The plugin file to update. * @param string $new_status The plugin's new status. * @param string $current_status The plugin's current status. * @return true|WP_Error */ protected function handle_plugin_status( $plugin, $new_status, $current_status ) { if ( 'inactive' === $new_status ) { deactivate_plugins( $plugin, false, 'network-active' === $current_status ); return true; } if ( 'active' === $new_status && 'network-active' === $current_status ) { return true; } $network_activate = 'network-active' === $new_status; if ( is_multisite() && ! $network_activate && is_network_only_plugin( $plugin ) ) { return new WP_Error( 'rest_network_only_plugin', __( 'Network only plugin must be network activated.' ), array( 'status' => 400 ) ); } $activated = activate_plugin( $plugin, '', $network_activate ); if ( is_wp_error( $activated ) ) { $activated->add_data( array( 'status' => 500 ) ); return $activated; } return true; } /** * Checks that the "plugin" parameter is a valid path. * * @since 5.5.0 * * @param string $file The plugin file parameter. * @return bool */ public function validate_plugin_param( $file ) { if ( ! is_string( $file ) || ! preg_match( '/' . self::PATTERN . '/u', $file ) ) { return false; } $validated = validate_file( plugin_basename( $file ) ); return 0 === $validated; } /** * Sanitizes the "plugin" parameter to be a proper plugin file with ".php" appended. * * @since 5.5.0 * * @param string $file The plugin file parameter. * @return string */ public function sanitize_plugin_param( $file ) { return plugin_basename( sanitize_text_field( $file . '.php' ) ); } /** * Checks if the plugin matches the requested parameters. * * @since 5.5.0 * * @param WP_REST_Request $request The request to require the plugin matches against. * @param array $item The plugin item. * @return bool */ protected function does_plugin_match_request( $request, $item ) { $search = $request['search']; if ( $search ) { $matched_search = false; foreach ( $item as $field ) { if ( is_string( $field ) && str_contains( strip_tags( $field ), $search ) ) { $matched_search = true; break; } } if ( ! $matched_search ) { return false; } } $status = $request['status']; if ( $status && ! in_array( $this->get_plugin_status( $item['_file'] ), $status, true ) ) { return false; } return true; } /** * Checks if the plugin is installed. * * @since 5.5.0 * * @param string $plugin The plugin file. * @return bool */ protected function is_plugin_installed( $plugin ) { return file_exists( WP_PLUGIN_DIR . '/' . $plugin ); } /** * Determine if the endpoints are available. * * Only the 'Direct' filesystem transport, and SSH/FTP when credentials are stored are supported at present. * * @since 5.5.0 * * @return true|WP_Error True if filesystem is available, WP_Error otherwise. */ protected function is_filesystem_available() { $filesystem_method = get_filesystem_method(); if ( 'direct' === $filesystem_method ) { return true; } ob_start(); $filesystem_credentials_are_stored = request_filesystem_credentials( self_admin_url() ); ob_end_clean(); if ( $filesystem_credentials_are_stored ) { return true; } return new WP_Error( 'fs_unavailable', __( 'The filesystem is currently unavailable for managing plugins.' ), array( 'status' => 500 ) ); } /** * Retrieves the plugin's schema, conforming to JSON Schema. * * @since 5.5.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $this->schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'plugin', 'type' => 'object', 'properties' => array( 'plugin' => array( 'description' => __( 'The plugin file.' ), 'type' => 'string', 'pattern' => self::PATTERN, 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'status' => array( 'description' => __( 'The plugin activation status.' ), 'type' => 'string', 'enum' => is_multisite() ? array( 'inactive', 'active', 'network-active' ) : array( 'inactive', 'active' ), 'context' => array( 'view', 'edit', 'embed' ), ), 'name' => array( 'description' => __( 'The plugin name.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'plugin_uri' => array( 'description' => __( 'The plugin\'s website address.' ), 'type' => 'string', 'format' => 'uri', 'readonly' => true, 'context' => array( 'view', 'edit' ), ), 'author' => array( 'description' => __( 'The plugin author.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit' ), ), 'author_uri' => array( 'description' => __( 'Plugin author\'s website address.' ), 'type' => 'string', 'format' => 'uri', 'readonly' => true, 'context' => array( 'view', 'edit' ), ), 'description' => array( 'description' => __( 'The plugin description.' ), 'type' => 'object', 'readonly' => true, 'context' => array( 'view', 'edit' ), 'properties' => array( 'raw' => array( 'description' => __( 'The raw plugin description.' ), 'type' => 'string', ), 'rendered' => array( 'description' => __( 'The plugin description formatted for display.' ), 'type' => 'string', ), ), ), 'version' => array( 'description' => __( 'The plugin version number.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit' ), ), 'network_only' => array( 'description' => __( 'Whether the plugin can only be activated network-wide.' ), 'type' => 'boolean', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'requires_wp' => array( 'description' => __( 'Minimum required version of WordPress.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'requires_php' => array( 'description' => __( 'Minimum required version of PHP.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'textdomain' => array( 'description' => __( 'The plugin\'s text domain.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit' ), ), ), ); return $this->add_additional_fields_schema( $this->schema ); } /** * Retrieves the query params for the collections. * * @since 5.5.0 * * @return array Query parameters for the collection. */ public function get_collection_params() { $query_params = parent::get_collection_params(); $query_params['context']['default'] = 'view'; $query_params['status'] = array( 'description' => __( 'Limits results to plugins with the given status.' ), 'type' => 'array', 'items' => array( 'type' => 'string', 'enum' => is_multisite() ? array( 'inactive', 'active', 'network-active' ) : array( 'inactive', 'active' ), ), ); unset( $query_params['page'], $query_params['per_page'] ); return $query_params; } } account * * @since 2.4.2 */ public function shortcode( $atts ) { //phpcs:ignore extract( shortcode_atts( [], $atts ) ); ob_start(); if ( is_user_logged_in() ) { $default_active_tab = wpuf_get_option( 'account_page_active_tab', 'wpuf_my_account', 'dashboard' ); $section = isset( $_REQUEST['section'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['section'] ) ) : $default_active_tab; $sections = wpuf_get_account_sections(); $current_section = []; foreach ( $sections as $slug => $label ) { if ( $section === $slug ) { $current_section = $slug; break; } } wpuf_load_template( 'account.php', [ 'sections' => $sections, 'current_section' => $current_section, ] ); } else { $message = wpuf_get_option( 'un_auth_msg', 'wpuf_dashboard' ); wpuf_load_template( 'unauthorized.php', [ 'message' => $message ] ); } $content = ob_get_contents(); ob_end_clean(); return $content; } /** * Display the dashboard section * * @since 2.4.2 * * @param string $current_section * * @param array $sections * * @return void */ public function dashboard_section( $sections, $current_section ) { wpuf_load_template( 'dashboard/dashboard.php', [ 'sections' => $sections, 'current_section' => $current_section, ] ); } /** * Display the posts section * * @since 2.4.2 * * @param string $current_section * * @param array $sections * * @return void */ public function posts_section( $sections, $current_section ) { wpuf_load_template( 'dashboard/posts.php', [ 'sections' => $sections, 'current_section' => $current_section, ] ); } /** * Display the subscription section * * @since 2.4.2 * * @param string $current_section * * @param array $sections * * @return void */ public function subscription_section( $sections, $current_section ) { $wpuf_user = wpuf_get_user(); $sub_id = $wpuf_user->subscription()->current_pack_id(); if ( ! $sub_id ) { echo wp_kses_post( __( '

You have not subscribed to any package yet.

', 'wp-user-frontend' ) ); return; } $user_subscription = new User_Subscription( $wpuf_user ); $user_sub = $user_subscription->current_pack(); if ( ! is_wp_error( $user_sub ) && $user_sub['status'] !== 'completed' && $user_sub['status'] !== 'Free' ) { esc_html_e( '

You may have processed your payment, but the pack is not active yet.

', 'wp-user-frontend' ); return; } $pack = wpuf()->subscription->get_subscription( $sub_id ); if ( ! $pack ) { echo wp_kses_post( sprintf( __( '%sYour subscription pack is not exists. Please contact admin.%s', 'wp-user-frontend' ), '

', '

' ) ); return; } $details_meta['payment_page'] = get_permalink( wpuf_get_option( 'payment_page', 'wpuf_payment' ) ); $details_meta['onclick'] = ''; $details_meta['symbol'] = wpuf_get_currency( 'symbol' ); $recurring_des = ''; $billing_amount = ( intval( $pack->meta_value['billing_amount'] ) > 0 ) ? $details_meta['symbol'] . $pack->meta_value['billing_amount'] : __( 'Free', 'wp-user-frontend' ); if ( $pack->meta_value['recurring_pay'] === 'yes' ) { /* translators: %s: billing cycle number, %s: billing cycle period */ $recurring_des = sprintf( __( 'For each', 'wp-user-frontend' ) . ' %s %s', $pack->meta_value['billing_cycle_number'], Subscription::get_cycle_label( $pack->meta_value['cycle_period'], $pack->meta_value['billing_cycle_number'] ), $pack->meta_value['trial_duration_type'] ); /* translators: %s: number of installments */ $recurring_des .= ! empty( $pack->meta_value['billing_limit'] ) ? sprintf( __( ', for %s installments', 'wp-user-frontend' ), $pack->meta_value['billing_limit'] ) : ''; } ob_start(); wpuf_load_template( 'dashboard/subscription.php', [ 'sections' => $sections, 'current_section' => $current_section, 'userdata' => $wpuf_user->user, 'user_sub' => $user_sub, 'pack' => $pack, 'billing_amount' => $billing_amount, 'recurring_des' => $recurring_des, ] ); ob_end_flush(); } /** * Display the edit profile section * * @since 2.4.2 * * @param string $current_section * * @param array $sections * * @return void */ public function edit_profile_section( $sections, $current_section ) { wpuf_load_template( 'dashboard/edit-profile.php', [ 'sections' => $sections, 'current_section' => $current_section, ] ); } /** * Display the billing address section * * @param array $sections * @param string $current_section * * @return void */ public function billing_address_section( $sections, $current_section ) { wpuf_load_template( 'dashboard/billing-address.php', [ 'sections' => $sections, 'current_section' => $current_section, ] ); } /** * Update profile via Ajax * * @since 2.4.2 * * @return json */ public function update_profile() { $nonce = isset( $_REQUEST['_wpnonce'] ) ? sanitize_key( wp_unslash( $_REQUEST['_wpnonce'] ) ) : ''; if ( isset( $nonce ) && ! wp_verify_nonce( $nonce, 'wpuf-account-update-profile' ) ) { wp_send_json_error( __( 'Nonce failure', 'wp-user-frontend' ) ); } global $current_user; $first_name = ! empty( $_POST['first_name'] ) ? sanitize_text_field( wp_unslash( $_POST['first_name'] ) ) : ''; $last_name = ! empty( $_POST['last_name'] ) ? sanitize_text_field( wp_unslash( $_POST['last_name'] ) ) : ''; $email = ! empty( $_POST['email'] ) ? sanitize_text_field( wp_unslash( $_POST['email'] ) ) : ''; $current_password = ! empty( $_POST['current_password'] ) ? sanitize_text_field( wp_unslash( $_POST['current_password'] ) ) : ''; $pass1 = ! empty( $_POST['pass1'] ) ? sanitize_text_field( wp_unslash( $_POST['pass1'] ) ) : ''; $pass2 = ! empty( $_POST['pass2'] ) ? sanitize_text_field( wp_unslash( $_POST['pass2'] ) ) : ''; $save_pass = true; if ( empty( $first_name ) ) { wp_send_json_error( __( 'First Name is a required field.', 'wp-user-frontend' ) ); } if ( empty( $last_name ) ) { wp_send_json_error( __( 'Last Name is a required field.', 'wp-user-frontend' ) ); } if ( empty( $email ) ) { wp_send_json_error( __( 'Email is a required field.', 'wp-user-frontend' ) ); } $user = new stdClass(); $user->ID = $current_user->ID; $user->first_name = $first_name; $user->last_name = $last_name; if ( $email ) { $email = sanitize_email( $email ); if ( ! is_email( $email ) ) { wp_send_json_error( __( 'Please provide a valid email address.', 'wp-user-frontend' ) ); } else if ( email_exists( $email ) && $email !== $current_user->user_email ) { wp_send_json_error( __( 'This email address is already registered.', 'wp-user-frontend' ) ); } $user->user_email = $email; } if ( ! empty( $current_password ) && empty( $pass1 ) && empty( $pass2 ) ) { wp_send_json_error( __( 'Please fill out all password fields.', 'wp-user-frontend' ) ); $save_pass = false; } else if ( ! empty( $pass1 ) && empty( $current_password ) ) { wp_send_json_error( __( 'Please enter your current password.', 'wp-user-frontend' ) ); $save_pass = false; } else if ( ! empty( $pass1 ) && empty( $pass2 ) ) { wp_send_json_error( __( 'Please re-enter your password.', 'wp-user-frontend' ) ); $save_pass = false; } else if ( ( ! empty( $pass1 ) || ! empty( $pass2 ) ) && $pass1 !== $pass2 ) { wp_send_json_error( __( 'New passwords do not match.', 'wp-user-frontend' ) ); $save_pass = false; } else if ( ! empty( $pass1 ) && ! wp_check_password( $current_password, $current_user->user_pass, $current_user->ID ) ) { wp_send_json_error( __( 'Your current password is incorrect.', 'wp-user-frontend' ) ); $save_pass = false; } if ( $pass1 && $save_pass ) { $user->user_pass = $pass1; } $result = wp_update_user( $user ); if ( is_wp_error( $result ) ) { wp_send_json_error( __( 'Your current password is incorrect.', 'wp-user-frontend' ) ); } wp_send_json_success(); } /** * Get CPT for shwoing in dashboard area * * @return mixed|string */ public function get_allowed_cpt() { return wpuf_get_option( 'cp_on_acc_page', 'wpuf_my_account', [ 'post' ] ); } /** * Check if the user is the post author and give permission for previewing * * @since 3.5.27 * * @return void */ public function process_user_for_previewing_post( $query ) { if ( current_user_can( 'edit_posts' ) ) { return; } if ( ! $query->is_main_query() && ! $query->is_preview && ! $query->get( 'p' ) ) { return; } $current_user_id = get_current_user_id(); $current_post_id = absint( $query->get( 'p' ) ); if ( $current_user_id === absint( get_post_field( 'post_author', $current_post_id ) ) ) { add_filter( 'user_has_cap', [ $this, 'add_temporary_capability' ], 10, 3 ); } } /** * Add a temporary edit_posts capability to the current user * for previewing post * * @since 3.5.27 * * @param $all_caps * * @return array */ public function add_temporary_capability( $all_caps ) { $all_caps['edit_posts'] = true; return $all_caps; } }
Fatal error: Uncaught Error: Class "WeDevs\Wpuf\Frontend\Frontend_Account" not found in /htdocs/wp-content/plugins/wp-user-frontend/includes/Frontend.php:20 Stack trace: #0 /htdocs/wp-content/plugins/wp-user-frontend/wpuf.php(181): WeDevs\Wpuf\Frontend->__construct() #1 /htdocs/wp-includes/class-wp-hook.php(324): WP_User_Frontend->instantiate('') #2 /htdocs/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters(NULL, Array) #3 /htdocs/wp-includes/plugin.php(517): WP_Hook->do_action(Array) #4 /htdocs/wp-settings.php(559): do_action('plugins_loaded') #5 /htdocs/wp-config.php(98): require_once('/htdocs/wp-sett...') #6 /htdocs/wp-load.php(50): require_once('/htdocs/wp-conf...') #7 /htdocs/wp-blog-header.php(13): require_once('/htdocs/wp-load...') #8 /htdocs/index.php(17): require('/htdocs/wp-blog...') #9 {main} thrown in /htdocs/wp-content/plugins/wp-user-frontend/includes/Frontend.php on line 20