settings = $settings; } /** * The posts carrying the form. * * @return \WP_Post[] */ private function pages() { if ( null === $this->pages ) { $this->pages = Setup_Link::form_pages(); } return $this->pages; } /** * The published page the link should lead to: the first, or null. * * @return \WP_Post|null */ private function target() { $published = Setup_Link::published( $this->pages() ); return $published ? $published[0] : null; } /** * Where a link to any published page with the form was found. * * @return string[] */ private function found() { if ( null === $this->found ) { $this->found = array(); foreach ( Setup_Link::published( $this->pages() ) as $page ) { $this->found = array_merge( $this->found, Setup_Link::find( $page ) ); } $this->found = array_values( array_unique( $this->found ) ); } return $this->found; } /** * True when a link to the form is known to be there: found, or the shop * said so. * * @return bool */ private function link_done() { return null !== $this->target() && ( (int) $this->settings->get( 'link_added_at', 0 ) > 0 || array() !== $this->found() ); } /** * The readiness list, key => label, state (done, todo or info), tag * (required or recommended) and the markup after the label (escaped). * WooCommerce's own form is listed only where WooCommerce has it. * * @param string|null $woo_state Woo_Withdrawal_Form::state(); read when null. * @return array */ public function readiness( $woo_state = null ) { $s = $this->settings; $settings = admin_url( 'admin.php?page=careback-settings' ); $on = Routes::withdrawal_offered( $s ); $woo_state = null === $woo_state ? Woo_Withdrawal_Form::state( $s ) : (string) $woo_state; $policy = (int) $s->get( 'returns_policy_page', 0 ); $item = static function ( $label, $done, $tag, $detail = '' ) { return array( 'label' => $label, 'state' => $done ? 'done' : 'todo', 'tag' => $tag, 'detail' => $done ? '' : $detail, ); }; $link = static function ( $url, $text ) { return '' . esc_html( $text ) . ''; }; $items = array( 'woocommerce' => $item( __( 'WooCommerce is active', 'careback' ), class_exists( 'WooCommerce' ), 'required' ), 'portal' => $item( __( 'The form is switched on', 'careback' ), (bool) $s->get( 'portal_enabled' ), 'required', ' — ' . esc_html__( 'step 4', 'careback' ) . '' ), 'placed' => $item( __( 'The form is on a published page', 'careback' ), null !== $this->target(), 'required', ' — ' . esc_html__( 'step 2', 'careback' ) . '' ), 'link' => $item( __( 'A link to the form in your footer or menu', 'careback' ), $this->link_done(), $on ? 'required' : 'recommended', ' — ' . esc_html__( 'step 3', 'careback' ) . '' ), 'fallback' => $item( __( 'A contact line for customers is set', 'careback' ), '' !== trim( (string) $s->get( 'fallback_contact', '' ) ), 'recommended', ' — ' . $link( $settings . '#careback-fallback', __( 'Set it', 'careback' ) ) ), ); if ( $policy > 0 && 'publish' === get_post_status( $policy ) ) { $items['policy'] = $item( __( 'Your returns policy page is linked in the form', 'careback' ), true, 'recommended' ); } elseif ( $policy > 0 && get_post( $policy ) ) { $items['policy'] = $item( __( 'Your returns policy page is linked in the form', 'careback' ), false, 'recommended', /* translators: %s: title of the returns policy page. */ ' — ' . esc_html( sprintf( __( 'the page “%s” is not published.', 'careback' ), get_the_title( $policy ) ) ) . ' ' . $link( (string) get_edit_post_link( $policy, 'url' ), __( 'Edit page', 'careback' ) ) ); } else { $items['policy'] = $item( __( 'Your returns policy page is linked in the form', 'careback' ), false, 'recommended', ' — ' . esc_html__( 'no page chosen.', 'careback' ) . ' ' . $link( $settings . '#careback-policy-page', __( 'Choose one', 'careback' ) ) ); } $items['recipients'] = $item( __( 'New requests are emailed to your team\'s address', 'careback' ), array() !== array_filter( array_map( 'trim', explode( ',', (string) $s->get( 'admin_recipients', '' ) ) ), 'is_email' ), 'recommended', ' — ' . esc_html__( 'now they go to the site\'s admin address.', 'careback' ) . ' ' . $link( $settings . '#careback-admin-recipients', __( 'Set your team\'s address', 'careback' ) ) ); // The harmonised notice on the legal guarantee (N-115): the shop places // it where customers read before they buy; done once a published page, // template or widget carries its shortcode. Gone while statutory // withdrawal is off. if ( Legal_Guarantee::offered( $s ) ) { $items['legal_guarantee'] = $item( __( 'Show the official legal guarantee notice', 'careback' ), Legal_Guarantee::placed(), 'recommended', ' — ' . esc_html__( 'paste this shortcode into the pages customers read before they buy: product, checkout or terms pages, or your footer.', 'careback' ) ); } // The tracking page maps order statuses to its own steps: while it shows // "Delivered" for another status than the one the periods start from // (N-76), the customer reads one day there and the periods count from // another. if ( $s->get( 'track_enabled' ) && ! $this->tracking_agrees() ) { $items['tracking_delivered'] = $item( __( 'Your tracking page shows a different step for “Delivered”.', 'careback' ), false, 'recommended', ' ' . $link( add_query_arg( 'desk', 'track', $settings ) . '#careback-sec-track-statuses', __( 'Check Tracking settings', 'careback' ) ) ); } if ( 'kept' === $woo_state ) { $items['woo_form'] = array( 'label' => __( 'WooCommerce\'s own withdrawal form is on — you chose to keep both.', 'careback' ), 'state' => 'info', 'tag' => 'recommended', 'detail' => ' ', ); } elseif ( 'none' !== $woo_state ) { $items['woo_form'] = $item( __( 'WooCommerce\'s own withdrawal form is off', 'careback' ), 'off' === $woo_state, 'recommended', ' — ' . esc_html__( 'see above', 'careback' ) . '' ); } return $items; } /** * True when the tracking page shows "Delivered" for the status the periods * start from (N-76), and for no other. * * @return bool */ private function tracking_agrees() { $delivered = array_keys( Track_Stage_Policy::order_map( $this->settings ), 'order_delivered', true ); return array( Periods::delivered_status( $this->settings ) ) === array_values( $delivered ); } /** * What WooCommerce's buttons did, and its card while its form is on. * * @return void */ public function render_top() { Woo_Withdrawal_Form::result_notice(); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- the result of the redirect; nothing is changed. if ( isset( $_GET['careback_link'] ) && 'saved' === sanitize_key( wp_unslash( $_GET['careback_link'] ) ) ) { printf( '

%s

', esc_html__( 'Saved.', 'careback' ) ); } if ( 'on' === Woo_Withdrawal_Form::state( $this->settings ) ) { Woo_Withdrawal_Form::render_card( $this->settings ); } } /** * The head of one step's card: its number (or a tick), its title, its tag * and where it stands. * * @param int $n Number of the step. * @param string $title Its title, with its number. * @param string $state done, todo, on or off. * @param string $tag required, recommended or ''. * @return void */ private function step_head( $n, $title, $state, $tag ) { $words = array( 'done' => __( 'Done', 'careback' ), 'todo' => __( 'To do', 'careback' ), 'on' => __( 'On', 'careback' ), 'off' => __( 'Off', 'careback' ), ); $done = in_array( $state, array( 'done', 'on' ), true ); ?>

array( 'class' => true ) ) ); ?>
settings ); $placed = null !== $this->target(); $portal_on = (bool) $this->settings->get( 'portal_enabled' ); ?>

step_head( 1, __( '1. Check statutory withdrawal', 'careback' ), $on ? 'on' : 'off', '' ); ?> render_withdrawal_step( $on ); ?>
step_head( 2, __( '2. Place the form on a page', 'careback' ), $placed ? 'done' : 'todo', 'required' ); ?> render_place_step( $shortcode ); ?>
step_head( 4, __( '4. Switch the form on', 'careback' ), $portal_on ? 'done' : 'todo', 'required' ); ?>

' . esc_html__( 'Change in Settings', 'careback' ) . ''; if ( $on ) { $days = (int) $this->settings->get( 'statutory_window_days', 14 ); ?>

array( 'href' => true ) ) ); ?>

array( 'href' => true ) ) ); ?>

settings ); ?>

array( 'href' => true ) ) ); ?>

/>
pages(); $published = Setup_Link::published( $pages ); ?>

copy_field( 'careback-shortcode', '', $shortcode, __( 'Shortcode of the returns form', 'careback' ), 'regular-text code careback-shortcode' ); ?>

—

1 ) : ?>

post_status ) ); ?>

target(); ?>

' . esc_html__( 'Place the form on a page first (step 2). The address appears here then.', 'careback' ) . '

'; return; } $text = $on ? Texts::get( 'withdraw_link', $this->settings ) : Texts::get( 'link_returns', $this->settings ); $text = '' !== trim( $text ) ? $text : ( $on ? __( 'Withdraw from contract here', 'careback' ) : __( 'Returns', 'careback' ) ); $url = (string) get_permalink( $target ); $path = (string) wp_parse_url( $url, PHP_URL_PATH ); $this->copy_field( 'careback-link-text', __( 'Link text', 'careback' ), $text ); $this->copy_field( 'careback-link-address', __( 'Address', 'careback' ), $url ); $published = Setup_Link::published( $this->pages() ); if ( count( $published ) > 1 ) : ?>

render_how_to(); $this->render_link_found( $path ); } /** * How this theme adds a link, and the other ways. * * @return void */ private function render_how_to() { if ( function_exists( 'wp_is_block_theme' ) && wp_is_block_theme() ) { $footer = function_exists( 'get_block_template' ) ? get_block_template( get_stylesheet() . '//footer', 'wp_template_part' ) : null; $open = $footer ? admin_url( 'site-editor.php?postType=wp_template_part&postId=' . rawurlencode( $footer->id ) . '&canvas=edit' ) : admin_url( 'site-editor.php?postType=wp_template_part' ); ?>

found(); $added = (int) $this->settings->get( 'link_added_at', 0 ); $code = '' . esc_html( '' !== $path ? $path : '/' ) . ''; ?>

array() ) ); ?>

array() ) ); ?>

array( 'is-ok', __( 'Done', 'careback' ), '✔' ), 'todo' => array( 'is-no', __( 'To do', 'careback' ), '✗' ), 'info' => array( 'is-info', __( 'Note', 'careback' ), 'i' ), ); $items = $this->readiness(); ?>

copy_field( 'careback-legal-guarantee-shortcode', '', '[' . Legal_Guarantee::SHORTCODE . ']', __( 'Shortcode of the legal guarantee notice', 'careback' ), 'regular-text code careback-shortcode' ); ?>
array( 'href' => true ), 'button' => array( 'type' => true, 'form' => true, 'name' => true, 'value' => true, 'class' => true, ), ); } /** * The support report (N-125): what it is for, the report, Copy report. * * @return void */ public function render_report() { $report = Support_Report::text( $this->settings, new Requests_Repository(), new Events_Repository() ); ?>