__('General', 'wp-multisite-waas'), 'desc' => __('General', 'wp-multisite-waas'), 'type' => 'header', ]; $fields['show_change_password'] = [ 'type' => 'toggle', 'title' => __('Show Change Password', 'wp-multisite-waas'), 'desc' => __('Toggle to show/hide the password link.', 'wp-multisite-waas'), 'tooltip' => '', 'value' => 1, ]; $fields['show_change_default_site'] = [ 'type' => 'toggle', 'title' => __('Show Change Default Site', 'wp-multisite-waas'), 'desc' => __('Toggle to show/hide the change default site link.', 'wp-multisite-waas'), 'tooltip' => '', 'value' => 1, ]; $fields['show_change_payment_method'] = [ 'type' => 'toggle', 'title' => __('Show Change Payment Method', 'wp-multisite-waas'), 'desc' => __('Toggle to show/hide the option to cancel the current payment method.', 'wp-multisite-waas'), 'tooltip' => '', 'value' => 1, ]; $pages = get_pages( [ 'exclude' => [get_the_ID()], ] ); $pages = $pages ?: []; $pages_list = [0 => __('Default', 'wp-multisite-waas')]; foreach ($pages as $page) { $pages_list[ $page->ID ] = $page->post_title; } $fields['redirect_after_delete'] = [ 'type' => 'select', 'title' => __('Redirect After Delete', 'wp-multisite-waas'), 'value' => 0, 'desc' => __('The page to redirect user after delete current site.', 'wp-multisite-waas'), 'tooltip' => '', 'options' => $pages_list, ]; return $fields; } /** * The list of keywords for this element. * * Return an array of strings with keywords describing this * element. Gutenberg uses this to help customers find blocks. * * e.g.: * return array( * 'WP Multisite WaaS', * 'Actions', * 'Form', * 'Cart', * ); * * @since 2.0.0 * @return array */ public function keywords() { return [ 'WP Ultimo', 'WP Multisite WaaS', 'Actions', 'Form', 'Cart', ]; } /** * List of default parameters for the element. * * If you are planning to add controls using the fields, * it might be a good idea to use this method to set defaults * for the parameters you are expecting. * * These defaults will be used inside a 'wp_parse_args' call * before passing the parameters down to the block render * function and the shortcode render function. * * @since 2.0.0 * @return array */ public function defaults() { return [ 'show_change_password' => 1, 'show_change_default_site' => 1, 'show_change_payment_method' => 1, 'redirect_after_delete' => 0, ]; } /** * Runs early on the request lifecycle as soon as we detect the shortcode is present. * * @since 2.0.0 * @return void */ public function setup(): void { $this->site = WP_Ultimo()->currents->get_site(); if ( ! $this->site || ! $this->site->is_customer_allowed()) { $this->site = false; } $this->membership = WP_Ultimo()->currents->get_membership(); if ( ! $this->membership) { $this->set_display(false); return; } } /** * Allows the setup in the context of previews. * * @since 2.0.0 * @return void */ public function setup_preview(): void { $this->site = wu_mock_site(); $this->membership = wu_mock_membership(); } /** * Overload the init to add site-related forms. * * @since 2.0.21 * @return void */ public function init(): void { parent::init(); $this->register_forms(); } /** * Register forms * * @since 2.0.21 * @return void */ public function register_forms(): void { wu_register_form( 'change_password', [ 'render' => [$this, 'render_change_password'], 'handler' => [$this, 'handle_change_password'], 'capability' => 'exist', ] ); wu_register_form( 'delete_site', [ 'render' => [$this, 'render_delete_site'], 'handler' => [$this, 'handle_delete_site'], 'capability' => 'exist', ] ); wu_register_form( 'change_default_site', [ 'render' => [$this, 'render_change_default_site'], 'handler' => [$this, 'handle_change_default_site'], 'capability' => 'exist', ] ); wu_register_form( 'cancel_payment_method', [ 'render' => [$this, 'render_cancel_payment_method'], 'handler' => [$this, 'handle_cancel_payment_method'], 'capability' => 'exist', ] ); wu_register_form( 'cancel_membership', [ 'render' => [$this, 'render_cancel_membership'], 'handler' => [$this, 'handle_cancel_membership'], 'capability' => 'exist', ] ); } /** * Returns the actions for the element. These can be filtered. * * @since 2.0.0 * @param array $atts Parameters of the block/shortcode. * @return array */ public function get_actions($atts) { $actions = []; $all_blogs = get_blogs_of_user(get_current_user_id()); $is_template_switching_enabled = wu_get_setting('allow_template_switching', true); if ($is_template_switching_enabled && $this->site) { $actions['template_switching'] = [ 'label' => __('Change Site Template', 'wp-multisite-waas'), 'icon_classes' => 'dashicons-wu-edit wu-align-middle', 'href' => add_query_arg( [ 'page' => 'wu-template-switching', ], get_admin_url($this->site->get_id()) ), ]; } if (count($all_blogs) > 1 && wu_get_isset($atts, 'show_change_default_site')) { $actions['default_site'] = [ 'label' => __('Change Default Site', 'wp-multisite-waas'), 'icon_classes' => 'dashicons-wu-edit wu-align-middle', 'classes' => 'wubox', 'href' => wu_get_form_url('change_default_site'), ]; } if (wu_get_isset($atts, 'show_change_password')) { $actions['change_password'] = [ 'label' => __('Change Password', 'wp-multisite-waas'), 'icon_classes' => 'dashicons-wu-edit wu-align-middle', 'classes' => 'wubox', 'href' => wu_get_form_url('change_password'), ]; } $payment_gateway = $this->membership ? $this->membership->get_gateway() : false; if (wu_get_isset($atts, 'show_change_payment_method') && $payment_gateway) { $actions['cancel_payment_method'] = [ 'label' => __('Cancel Current Payment Method', 'wp-multisite-waas'), 'icon_classes' => 'dashicons-wu-edit wu-align-middle', 'classes' => 'wubox', 'href' => wu_get_form_url( 'cancel_payment_method', [ 'membership' => $this->membership->get_hash(), 'redirect_url' => wu_get_current_url(), ] ), ]; } return apply_filters('wu_element_get_site_actions', $actions, $atts, $this->site, $this->membership); } /** * Returns the danger actions actions for the element. These can be filtered. * * @since 2.0.21 * @param array $atts Parameters of the block/shortcode. * @return array */ public function get_danger_zone_actions($atts) { $actions = []; if ($this->site) { $actions = array_merge( [ 'delete_site' => [ 'label' => __('Delete Site', 'wp-multisite-waas'), 'icon_classes' => 'dashicons-wu-edit wu-align-middle', 'classes' => 'wubox wu-text-red-500', 'href' => wu_get_form_url( 'delete_site', [ 'site' => $this->site->get_hash(), 'redirect_url' => ! $atts['redirect_after_delete'] ? false : get_page_link($atts['redirect_after_delete']), ] ), ], ], $actions ); } if ($this->membership && $this->membership->is_recurring() && $this->membership->get_status() !== Membership_Status::CANCELLED) { $actions = array_merge( [ 'cancel_membership' => [ 'label' => __('Cancel Membership', 'wp-multisite-waas'), 'icon_classes' => 'dashicons-wu-edit wu-align-middle', 'classes' => 'wubox wu-text-red-500', 'href' => wu_get_form_url( 'cancel_membership', [ 'membership' => $this->membership->get_hash(), 'redirect_url' => wu_get_current_url(), ] ), ], ], $actions ); } return apply_filters('wu_element_get_danger_zone_site_actions', $actions); } /** * Renders the delete site modal. * * @since 2.0.21 * @return void */ public function render_delete_site(): void { $site = wu_get_site_by_hash(wu_request('site')); $error = ''; if ( ! $site) { $error = __('Site not selected.', 'wp-multisite-waas'); } $customer = wu_get_current_customer(); if ( ! $customer || $customer->get_id() !== $site->get_customer_id()) { $error = __('You are not allowed to do this.', 'wp-multisite-waas'); } if ( ! empty($error)) { $error_field = [ 'error_message' => [ 'type' => 'note', 'desc' => $error, ], ]; $form = new \WP_Ultimo\UI\Form( 'change_password', $error_field, [ 'views' => 'admin-pages/fields', 'classes' => 'wu-modal-form wu-widget-list wu-striped wu-m-0 wu-mt-0', 'field_wrapper_classes' => 'wu-w-full wu-box-border wu-items-center wu-flex wu-justify-between wu-p-4 wu-m-0 wu-border-t wu-border-l-0 wu-border-r-0 wu-border-b-0 wu-border-gray-300 wu-border-solid', ] ); $form->render(); return; } $fields = [ 'site' => [ 'type' => 'hidden', 'value' => wu_request('site'), ], 'redirect_url' => [ 'type' => 'hidden', 'value' => wu_request('redirect_url'), ], 'confirm' => [ 'type' => 'toggle', 'title' => __('Confirm Site Deletion', 'wp-multisite-waas'), 'desc' => __('This action can not be undone.', 'wp-multisite-waas'), 'html_attr' => [ 'v-model' => 'confirmed', ], ], 'submit_button' => [ 'type' => 'submit', 'title' => __('Delete Site', 'wp-multisite-waas'), 'placeholder' => __('Delete Site', 'wp-multisite-waas'), 'value' => 'save', 'classes' => 'button button-primary wu-w-full', 'wrapper_classes' => 'wu-items-end', 'html_attr' => [ 'v-bind:disabled' => '!confirmed', ], ], ]; $form = new \WP_Ultimo\UI\Form( 'change_password', $fields, [ 'views' => 'admin-pages/fields', 'classes' => 'wu-modal-form wu-widget-list wu-striped wu-m-0 wu-mt-0', 'field_wrapper_classes' => 'wu-w-full wu-box-border wu-items-center wu-flex wu-justify-between wu-p-4 wu-m-0 wu-border-t wu-border-l-0 wu-border-r-0 wu-border-b-0 wu-border-gray-300 wu-border-solid', 'html_attr' => [ 'data-wu-app' => 'change_password', 'data-state' => wu_convert_to_state( [ 'confirmed' => false, ] ), ], ] ); $form->render(); } /** * Handles the delete site modal. * * @since 2.0.21 * * @return void|\WP_Error Void or WP_Error. */ public function handle_delete_site() { global $wpdb; $site = wu_get_site_by_hash(wu_request('site')); if ( ! $site || ! $site->is_customer_allowed()) { return new \WP_Error('error', __('An unexpected error happened.', 'wp-multisite-waas')); } $customer = wu_get_current_customer(); if ( ! $customer || $customer->get_id() !== $site->get_customer_id()) { return new \WP_Error('error', __('You are not allowed to do this.', 'wp-multisite-waas')); } $wpdb->query('START TRANSACTION'); // phpcs:ignore WordPress.DB.DirectDatabaseQuery try { $saved = $site->delete(); if (is_wp_error($saved)) { return $saved; } } catch (\Throwable $e) { $wpdb->query('ROLLBACK'); // phpcs:ignore WordPress.DB.DirectDatabaseQuery return new \WP_Error('exception', $e->getMessage()); } $wpdb->query('COMMIT'); // phpcs:ignore WordPress.DB.DirectDatabaseQuery $redirect_url = wu_request('redirect_url'); $redirect_url = add_query_arg( [ 'site_deleted' => true, ], wu_request('redirect_url') ?? user_admin_url() ); wp_send_json_success( [ 'redirect_url' => $redirect_url, ] ); } /** * Renders the change password modal. * * @since 2.0.21 * @return void */ public function render_change_password(): void { $fields = [ 'password' => [ 'type' => 'password', 'title' => __('Current Password', 'wp-multisite-waas'), 'placeholder' => __('******', 'wp-multisite-waas'), ], 'new_password' => [ 'type' => 'password', 'title' => __('New Password', 'wp-multisite-waas'), 'placeholder' => __('******', 'wp-multisite-waas'), 'meter' => true, ], 'new_password_conf' => [ 'type' => 'password', 'placeholder' => __('******', 'wp-multisite-waas'), 'title' => __('Confirm New Password', 'wp-multisite-waas'), ], 'submit_button' => [ 'type' => 'submit', 'title' => __('Reset Password', 'wp-multisite-waas'), 'value' => 'save', 'classes' => 'button button-primary wu-w-full', 'wrapper_classes' => 'wu-items-end', 'html_attr' => [], ], ]; $form = new \WP_Ultimo\UI\Form( 'change_password', $fields, [ 'views' => 'admin-pages/fields', 'classes' => 'wu-modal-form wu-widget-list wu-striped wu-m-0 wu-mt-0', 'field_wrapper_classes' => 'wu-w-full wu-box-border wu-items-center wu-flex wu-justify-between wu-p-4 wu-m-0 wu-border-t wu-border-l-0 wu-border-r-0 wu-border-b-0 wu-border-gray-300 wu-border-solid', 'html_attr' => [ 'data-wu-app' => 'change_password', 'data-state' => wu_convert_to_state(), ], ] ); $form->render(); } /** * Handles the password reset form. * * @since 2.0.21 * @return void */ public function handle_change_password(): void { $user = wp_get_current_user(); if ( ! $user) { $error = new \WP_Error('user-dont-exist', __('Something went wrong.', 'wp-multisite-waas')); wp_send_json_error($error); } $current_password = wu_request('password'); if ( ! wp_check_password($current_password, $user->user_pass, $user->ID)) { $error = new \WP_Error('wrong-password', __('Your current password is wrong.', 'wp-multisite-waas')); wp_send_json_error($error); } $new_password = wu_request('new_password'); $new_password_conf = wu_request('new_password_conf'); if ( ! $new_password || strlen((string) $new_password) < 6) { $error = new \WP_Error('password-min-length', __('The new password must be at least 6 characters long.', 'wp-multisite-waas')); wp_send_json_error($error); } if ($new_password !== $new_password_conf) { $error = new \WP_Error('passwords-dont-match', __('New passwords do not match.', 'wp-multisite-waas')); wp_send_json_error($error); } reset_password($user, $new_password); // Log-in again. wp_set_auth_cookie($user->ID); wp_set_current_user($user->ID); do_action('wp_login', $user->user_login, $user); // PHPCS:ignore WordPress.NamingConventions wp_send_json_success( [ 'redirect_url' => add_query_arg('updated', 1, $_SERVER['HTTP_REFERER']), // phpcs:ignore WordPress.Security.ValidatedSanitizedInput ] ); } /** * Renders the change current site modal. * * @since 2.0.21 * @return void */ public function render_change_default_site(): void { $all_blogs = get_blogs_of_user(get_current_user_id()); $option_blogs = []; foreach ($all_blogs as $key => $blog) { $option_blogs[ $blog->userblog_id ] = get_home_url($blog->userblog_id); } $primary_blog = get_user_meta(get_current_user_id(), 'primary_blog', true); $fields = [ 'new_primary_site' => [ 'type' => 'select', 'title' => __('Primary Site', 'wp-multisite-waas'), 'desc' => __('Change the primary site of your network.', 'wp-multisite-waas'), 'options' => $option_blogs, 'value' => $primary_blog, 'html_attr' => [ 'v-model' => 'new_primary_site', ], ], 'submit_button' => [ 'type' => 'submit', 'title' => __('Change Default Site', 'wp-multisite-waas'), 'value' => 'save', 'classes' => 'button button-primary wu-w-full', 'wrapper_classes' => 'wu-items-end', 'html_attr' => [ 'v-bind:disabled' => 'new_primary_site === "' . $primary_blog . '"', ], ], ]; $form = new \WP_Ultimo\UI\Form( 'change_default_site', $fields, [ 'views' => 'admin-pages/fields', 'classes' => 'wu-modal-form wu-widget-list wu-striped wu-m-0 wu-mt-0', 'field_wrapper_classes' => 'wu-w-full wu-box-border wu-items-center wu-flex wu-justify-between wu-p-4 wu-m-0 wu-border-t wu-border-l-0 wu-border-r-0 wu-border-b-0 wu-border-gray-300 wu-border-solid', 'html_attr' => [ 'data-wu-app' => 'change_default_site', 'data-state' => wu_convert_to_state( [ 'new_primary_site' => $primary_blog, ] ), ], ] ); $form->render(); } /** * Handles the change default site form. * * @since 2.0.21 * @return void */ public function handle_change_default_site(): void { $new_primary_site = wu_request('new_primary_site'); if ($new_primary_site) { update_user_meta(get_current_user_id(), 'primary_blog', $new_primary_site); wp_send_json_success( [ 'redirect_url' => add_query_arg('updated', 1, $_SERVER['HTTP_REFERER']), // phpcs:ignore WordPress.Security.ValidatedSanitizedInput ] ); } $error = new \WP_Error('no-site-selected', __('You need to select a new primary site.', 'wp-multisite-waas')); wp_send_json_error($error); } /** * Renders the cancel payment method modal. * * @since 2.1.2 * @return void */ public function render_cancel_payment_method(): void { $membership = wu_get_membership_by_hash(wu_request('membership')); $error = ''; if ( ! $membership) { $error = __('Membership not selected.', 'wp-multisite-waas'); } $customer = wu_get_current_customer(); if ( ! is_super_admin() && (! $customer || $customer->get_id() !== $membership->get_customer_id())) { $error = __('You are not allowed to do this.', 'wp-multisite-waas'); } if ( ! empty($error)) { $error_field = [ 'error_message' => [ 'type' => 'note', 'desc' => $error, ], ]; $form = new \WP_Ultimo\UI\Form( 'cancel_payment_method', $error_field, [ 'views' => 'admin-pages/fields', 'classes' => 'wu-modal-form wu-widget-list wu-striped wu-m-0 wu-mt-0', 'field_wrapper_classes' => 'wu-w-full wu-box-border wu-items-center wu-flex wu-justify-between wu-p-4 wu-m-0 wu-border-t wu-border-l-0 wu-border-r-0 wu-border-b-0 wu-border-gray-300 wu-border-solid', ] ); $form->render(); return; } $fields = [ 'membership' => [ 'type' => 'hidden', 'value' => wu_request('membership'), ], 'redirect_url' => [ 'type' => 'hidden', 'value' => wu_request('redirect_url'), ], 'confirm' => [ 'type' => 'toggle', 'title' => __('Confirm Payment Method Cancellation', 'wp-multisite-waas'), 'desc' => __('This action can not be undone.', 'wp-multisite-waas'), 'html_attr' => [ 'v-model' => 'confirmed', ], ], 'submit_button' => [ 'type' => 'submit', 'title' => __('Cancel Payment Method', 'wp-multisite-waas'), 'placeholder' => __('Cancel Payment Method', 'wp-multisite-waas'), 'value' => 'save', 'classes' => 'button button-primary wu-w-full', 'wrapper_classes' => 'wu-items-end', 'html_attr' => [ 'v-bind:disabled' => '!confirmed', ], ], ]; $form = new \WP_Ultimo\UI\Form( 'cancel_payment_method', $fields, [ 'views' => 'admin-pages/fields', 'classes' => 'wu-modal-form wu-widget-list wu-striped wu-m-0 wu-mt-0', 'field_wrapper_classes' => 'wu-w-full wu-box-border wu-items-center wu-flex wu-justify-between wu-p-4 wu-m-0 wu-border-t wu-border-l-0 wu-border-r-0 wu-border-b-0 wu-border-gray-300 wu-border-solid', 'html_attr' => [ 'data-wu-app' => 'cancel_payment_method', 'data-state' => wu_convert_to_state( [ 'confirmed' => false, ] ), ], ] ); $form->render(); } /** * Handles the payment method cancellation. * * @since 2.1.2 * @return void */ public function handle_cancel_payment_method(): void { $membership = wu_get_membership_by_hash(wu_request('membership')); if ( ! $membership) { $error = new \WP_Error('error', __('An unexpected error happened.', 'wp-multisite-waas')); wp_send_json_error($error); return; } $customer = wu_get_current_customer(); if ( ! is_super_admin() && (! $customer || $customer->get_id() !== $membership->get_customer_id())) { $error = new \WP_Error('error', __('You are not allowed to do this.', 'wp-multisite-waas')); wp_send_json_error($error); return; } $membership->set_gateway(''); $membership->set_gateway_subscription_id(''); $membership->set_gateway_customer_id(''); $membership->set_auto_renew(false); $membership->save(); $redirect_url = wu_request('redirect_url'); $redirect_url = add_query_arg( [ 'payment_gateway_cancelled' => true, ], $redirect_url ?? user_admin_url() ); wp_send_json_success( [ 'redirect_url' => $redirect_url, ] ); } /** * Renders the cancel payment method modal. * * @since 2.1.2 * @return void */ public function render_cancel_membership(): void { $membership = wu_get_membership_by_hash(wu_request('membership')); $error = ''; if ( ! $membership) { $error = __('Membership not selected.', 'wp-multisite-waas'); } $customer = wu_get_current_customer(); if ( ! is_super_admin() && (! $customer || $customer->get_id() !== $membership->get_customer_id())) { $error = __('You are not allowed to do this.', 'wp-multisite-waas'); } if ( ! empty($error)) { $error_field = [ 'error_message' => [ 'type' => 'note', 'desc' => $error, ], ]; $form = new \WP_Ultimo\UI\Form( 'cancel_membership', $error_field, [ 'views' => 'admin-pages/fields', 'classes' => 'wu-modal-form wu-widget-list wu-striped wu-m-0 wu-mt-0', 'field_wrapper_classes' => 'wu-w-full wu-box-border wu-items-center wu-flex wu-justify-between wu-p-4 wu-m-0 wu-border-t wu-border-l-0 wu-border-r-0 wu-border-b-0 wu-border-gray-300 wu-border-solid', ] ); $form->render(); return; } $fields = [ 'membership' => [ 'type' => 'hidden', 'value' => wu_request('membership'), ], 'redirect_url' => [ 'type' => 'hidden', 'value' => wu_request('redirect_url'), ], 'cancellation_reason' => [ 'type' => 'select', 'title' => __('Please tell us why you are cancelling.', 'wp-multisite-waas'), 'desc' => __('We would love your feedback.', 'wp-multisite-waas'), 'html_attr' => [ 'v-model' => 'cancellation_reason', ], 'default' => '', 'options' => [ '' => __('Select a reason', 'wp-multisite-waas'), 'unused' => __('I no longer need it', 'wp-multisite-waas'), 'too_expensive' => __('It\'s too expensive', 'wp-multisite-waas'), 'missing_features' => __('I need more features', 'wp-multisite-waas'), 'switched_service' => __('Switched to another service', 'wp-multisite-waas'), 'customer_service' => __('Customer support is less than expected', 'wp-multisite-waas'), 'too_complex' => __('Too complex', 'wp-multisite-waas'), 'other' => __('Other', 'wp-multisite-waas'), ], ], 'cancellation_explanation' => [ 'type' => 'textarea', 'title' => __('Please provide additional details.', 'wp-multisite-waas'), 'wrapper_html_attr' => [ 'v-show' => 'cancellation_reason === "other"', ], ], 'confirm' => [ 'type' => 'text', 'title' => __('Type CANCEL to confirm this membership cancellation.', 'wp-multisite-waas'), 'html_attr' => [ 'v-model' => 'confirmation', ], ], ]; $next_charge = false; if ($membership->is_recurring() && ($membership->is_active() || $membership->get_status() === Membership_Status::TRIALING)) { $next_charge = strtotime($membership->get_date_expiration()); } if ($next_charge && $next_charge > time()) { $fields['next_charge'] = [ 'type' => 'note', // translators: %s: Next charge date. 'desc' => sprintf(__('Your sites will stay working until %s.', 'wp-multisite-waas'), date_i18n(get_option('date_format'), $next_charge)), ]; } $fields['submit_button'] = [ 'type' => 'submit', 'title' => __('Cancel Membership', 'wp-multisite-waas'), 'placeholder' => __('Cancel Membership', 'wp-multisite-waas'), 'value' => 'save', 'classes' => 'button button-primary wu-w-full', 'wrapper_classes' => 'wu-items-end', 'html_attr' => [ 'v-bind:disabled' => 'confirmation !== "' . __('CANCEL', 'wp-multisite-waas') . '" || cancellation_reason === ""', ], ]; $form = new \WP_Ultimo\UI\Form( 'cancel_membership', $fields, [ 'views' => 'admin-pages/fields', 'classes' => 'wu-modal-form wu-widget-list wu-striped wu-m-0 wu-mt-0', 'field_wrapper_classes' => 'wu-w-full wu-box-border wu-items-center wu-flex wu-justify-between wu-p-4 wu-m-0 wu-border-t wu-border-l-0 wu-border-r-0 wu-border-b-0 wu-border-gray-300 wu-border-solid', 'html_attr' => [ 'data-wu-app' => 'cancel_membership', 'data-state' => wu_convert_to_state( [ 'confirmation' => '', 'cancellation_reason' => '', ] ), ], ] ); $form->render(); } /** * Handles the payment method cancellation. * * @since 2.1.2 * @return void */ public function handle_cancel_membership(): void { $membership = wu_get_membership_by_hash(wu_request('membership')); if ( ! $membership) { $error = new \WP_Error('error', __('An unexpected error happened.', 'wp-multisite-waas')); wp_send_json_error($error); return; } $customer = wu_get_current_customer(); if ( ! is_super_admin() && (! $customer || $customer->get_id() !== $membership->get_customer_id())) { $error = new \WP_Error('error', __('You are not allowed to do this.', 'wp-multisite-waas')); wp_send_json_error($error); return; } $cancellation_options = [ 'unused' => __('I no longer need it', 'wp-multisite-waas'), 'too_expensive' => __('It\'s too expensive', 'wp-multisite-waas'), 'missing_features' => __('I need more features', 'wp-multisite-waas'), 'switched_service' => __('Switched to another service', 'wp-multisite-waas'), 'customer_service' => __('Customer support is less than expected', 'wp-multisite-waas'), 'too_complex' => __('Too complex', 'wp-multisite-waas'), 'other' => wu_request('cancellation_explanation'), ]; $reason = wu_get_isset($cancellation_options, wu_request('cancellation_reason'), ''); $membership->cancel($reason); $redirect_url = wu_request('redirect_url'); $redirect_url = add_query_arg( [ 'payment_gateway_cancelled' => true, ], ! empty($redirect_url) ? $redirect_url : user_admin_url() ); wp_send_json_success( [ 'redirect_url' => $redirect_url, ] ); } /** * The content to be output on the screen. * * Should return HTML markup to be used to display the block. * This method is shared between the block render method and * the shortcode implementation. * * @since 2.0.0 * * @param array $atts Parameters of the block/shortcode. * @param string|null $content The content inside the shortcode. * @return string */ public function output($atts, $content = null) { $atts['actions'] = $this->get_actions($atts); $atts['danger_zone_actions'] = $this->get_danger_zone_actions($atts); return wu_get_template_contents('dashboard-widgets/site-actions', $atts); } }