slug. * @return array */ public static function query_vars( $vars ) { if ( is_array( $vars ) ) { $vars[ self::endpoint_key() ] = Settings::get( 'account_endpoint' ); } return $vars; } /** * Add "Returns" to the My Account menu (before "Logout"). * * @param array $items Menu items. * @return array */ public static function menu( $items ) { if ( ! is_array( $items ) || ! ( Eligibility::enabled( 'return' ) || Eligibility::enabled( 'withdrawal' ) ) ) { return $items; } $out = array(); foreach ( $items as $key => $label ) { if ( 'customer-logout' === $key ) { $out[ self::endpoint_key() ] = __( 'Returns', 'returnkit' ); } $out[ $key ] = $label; } if ( ! isset( $out[ self::endpoint_key() ] ) ) { $out[ self::endpoint_key() ] = __( 'Returns', 'returnkit' ); } return $out; } /** * Endpoint title. * * @param string $title Title. * @param string $endpoint Endpoint. * @return string */ public static function title( $title, $endpoint = '' ) { unset( $endpoint ); global $wp; $value = isset( $wp->query_vars[ Settings::get( 'account_endpoint' ) ] ) ? $wp->query_vars[ Settings::get( 'account_endpoint' ) ] : ''; if ( '' !== (string) $value && absint( $value ) ) { $request = Requests::get( absint( $value ) ); if ( $request && Access::can_view_request( $request ) ) { /* translators: %s: request number. */ return sprintf( __( 'Request %s', 'returnkit' ), $request->number() ); } } // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( isset( $_GET['rtkt_order'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended return isset( $_GET['rtkt_type'] ) && 'withdrawal' === $_GET['rtkt_type'] ? Settings::text( 'withdrawal_label' ) : __( 'Return items', 'returnkit' ); } return __( 'Returns', 'returnkit' ); } /** * Render the endpoint: a request, the form for an order, or the list. * * @param string $value Endpoint value. * @return void */ public static function render( $value = '' ) { Access::no_cache(); Assets::enqueue(); $user_id = get_current_user_id(); if ( '' !== (string) $value && absint( $value ) ) { $request = Requests::get( absint( $value ) ); if ( ! Access::can_view_request( $request ) ) { echo wp_kses( Template::render( 'portal/not-found.php' ), Template::allowed_html() ); return; } echo wp_kses( Portal::request_view( $request ), Template::allowed_html() ); return; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended $order_id = isset( $_GET['rtkt_order'] ) ? absint( $_GET['rtkt_order'] ) : 0; if ( $order_id ) { $order = wc_get_order( $order_id ); if ( ! Access::can_use_order( $order ) ) { echo wp_kses( Template::render( 'portal/not-found.php' ), Template::allowed_html() ); return; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended $type = isset( $_GET['rtkt_type'] ) && 'withdrawal' === $_GET['rtkt_type'] ? 'withdrawal' : 'return'; echo wp_kses( 'withdrawal' === $type ? Withdrawal::order_flow( $order, '' ) : Portal::return_form( $order, '' ), Template::allowed_html() ); return; } $html = Template::render( 'myaccount/returns.php', array( 'notices' => Template::notices(), // Only requests made with this account: guest requests are never // merged in by email, since account emails aren't verified. 'requests' => Requests::query( array( 'customer_id' => $user_id ), 50 ), 'returnable' => Eligibility::customer_orders( $user_id, 'return', 20 ), 'withdrawable' => Settings::get( 'withdrawal_in_account' ) ? Eligibility::customer_orders( $user_id, 'withdrawal', 20 ) : array(), ) ); echo wp_kses( $html, Template::allowed_html() ); } /** * Set while the My Account orders table loads its orders. * * @var bool */ private static $orders_table = false; /** * The My Account orders table is about to load its orders. * * @param array $args Query args. * @return array */ public static function mark_orders_query( $args ) { self::$orders_table = true; return $args; } /** * When the orders table's orders arrive, look up all their returns in * one query instead of one per row. WooCommerce runs other order queries * on the same page, so only the table's own query (this customer, * paginated) is used. * * @param array|object $results Orders, or a paginated result object. * @param array $args Query args. * @return array|object */ public static function prime_orders_table( $results, $args = array() ) { if ( ! self::$orders_table || empty( $args['paginate'] ) || (int) ( $args['customer'] ?? 0 ) !== get_current_user_id() ) { return $results; } self::$orders_table = false; $orders = is_object( $results ) && isset( $results->orders ) ? $results->orders : $results; if ( is_array( $orders ) ) { Requests::prime( array_map( static function ( $o ) { return $o instanceof \WC_Order ? $o->get_id() : (int) $o; }, $orders ) ); } return $results; } /** * "Return items" / withdrawal buttons in the My Account orders table. * * @param array $actions Actions. * @param \WC_Order $order Order. * @return array */ public static function order_actions( $actions, $order ) { if ( ! is_array( $actions ) || ! $order instanceof \WC_Order ) { return $actions; } if ( Eligibility::check( $order, 'return' )['ok'] ) { $actions['rtkt-return'] = array( 'url' => Access::return_url( $order ), 'name' => __( 'Return items', 'returnkit' ), ); } if ( Settings::get( 'withdrawal_in_account' ) && Eligibility::check( $order, 'withdrawal' )['ok'] ) { $actions['rtkt-withdraw'] = array( 'url' => Access::withdrawal_url( $order ), 'name' => Settings::text( 'withdrawal_label' ), ); } return $actions; } /** * On the order page: existing requests and the buttons. * * @param \WC_Order $order Order. * @return void */ public static function order_panel( $order ) { if ( ! $order instanceof \WC_Order || ! Access::can_use_order( $order, self::query_key() ) ) { return; } $requests = Requests::query( array( 'order_id' => $order->get_id() ), 20 ); $return = Eligibility::check( $order, 'return' ); $withdraw = Settings::get( 'withdrawal_in_account' ) ? Eligibility::check( $order, 'withdrawal' ) : array( 'ok' => false ); if ( ! $requests && ! $return['ok'] && ! $withdraw['ok'] ) { return; } Assets::enqueue(); $guest = '' !== self::query_key(); $html = Template::render( 'myaccount/order-panel.php', array( 'order' => $order, 'requests' => $requests, 'return_url' => $return['ok'] ? Access::return_url( $order, $guest ) : '', 'return_until' => $return['ok'] ? $return['deadline'] : null, 'withdraw_url' => $withdraw['ok'] ? Access::withdrawal_url( $order, $guest ) : '', 'guest' => $guest, ) ); echo wp_kses( $html, Template::allowed_html() ); } /** * The order key on the order-received page (guests). * * @return string */ private static function query_key() { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- compared with hash_equals by Access. return isset( $_GET['key'] ) ? sanitize_text_field( wp_unslash( $_GET['key'] ) ) : ''; } /** * Return and withdrawal links in customer order emails. * * @param \WC_Order $order Order. * @param bool $sent_to_admin Admin email. * @param bool $plain_text Plain text. * @param \WC_Email $email Email. * @return void */ public static function email_links( $order, $sent_to_admin = false, $plain_text = false, $email = null ) { if ( $sent_to_admin || ! $order instanceof \WC_Order || ! Settings::get( 'withdrawal_in_emails' ) ) { return; } $id = $email && isset( $email->id ) ? $email->id : ''; if ( ! in_array( $id, array( 'customer_processing_order', 'customer_completed_order', 'customer_on_hold_order', 'customer_invoice' ), true ) ) { return; } $links = array(); if ( Eligibility::check( $order, 'withdrawal' )['ok'] ) { $links[] = array( Settings::text( 'withdrawal_label' ), Access::withdrawal_url( $order, true ) ); } if ( 'customer_completed_order' === $id && Eligibility::guest_allowed( $order ) && Eligibility::check( $order, 'return' )['ok'] ) { $exchanges = Gate::can( 'exchanges' ) && Settings::get( 'exchanges_enabled' ); $links[] = array( $exchanges ? __( 'Return or exchange items', 'returnkit' ) : __( 'Return items', 'returnkit' ), Access::return_url( $order, true ) ); } if ( ! $links ) { return; } if ( $plain_text ) { foreach ( $links as $link ) { echo "\n" . esc_html( $link[0] ) . ': ' . esc_url( $link[1] ) . "\n"; } return; } echo '

'; foreach ( $links as $i => $link ) { echo ( $i ? '  ยท  ' : '' ) . '' . esc_html( $link[0] ) . ''; } echo '

'; } }