get_order_key(), (string) $key ) ) { return true; } $customer = (int) $order->get_customer_id(); return $customer && is_user_logged_in() && get_current_user_id() === $customer; } /** * Can the current visitor see this request? * * @param Request|null $request Request. * @param string $token Token from the link (guests). * @return bool */ public static function can_view_request( $request, $token = '' ) { if ( ! $request instanceof Request ) { return false; } if ( $request->customer_id() && is_user_logged_in() && get_current_user_id() === $request->customer_id() ) { return true; } return '' !== (string) $token && hash_equals( $request->access_token(), (string) $token ); } /** * The order from the current query (rtkt_order + rtkt_key), if allowed. * * @return \WC_Order|null */ public static function order_from_query() { // phpcs:disable WordPress.Security.NonceVerification.Recommended -- read-only, authorized by the order key. $id = isset( $_GET['rtkt_order'] ) ? absint( $_GET['rtkt_order'] ) : 0; $key = isset( $_GET['rtkt_key'] ) ? sanitize_text_field( wp_unslash( $_GET['rtkt_key'] ) ) : ''; // phpcs:enable if ( ! $id ) { return null; } $order = wc_get_order( $id ); return self::can_use_order( $order, $key ) ? $order : null; } /** * My Account returns endpoint URL. * * @param string $value Endpoint value (request ID, or ''). * @return string */ public static function account_url( $value = '' ) { return wc_get_endpoint_url( Account::endpoint_key(), (string) $value, wc_get_page_permalink( 'myaccount' ) ); } /** * Portal page URL (falls back to My Account when no page is set up). * * @return string */ public static function portal_base() { $page = (int) Settings::get( 'portal_page' ); if ( $page && 'publish' === get_post_status( $page ) ) { return get_permalink( $page ); } return self::account_url(); } /** * Withdrawal page URL ('' when not set up). * * @return string */ public static function withdrawal_base() { $page = (int) Settings::get( 'withdrawal_page' ); if ( $page && 'publish' === get_post_status( $page ) ) { return get_permalink( $page ); } return ''; } /** * Link to start a return for an order (account or guest, as fits). * * @param \WC_Order $order Order. * @param bool $guest Force the guest (order key) link, e.g. for emails. * @return string */ public static function return_url( \WC_Order $order, $guest = false ) { if ( ! $guest && $order->get_customer_id() && is_user_logged_in() && get_current_user_id() === (int) $order->get_customer_id() ) { return add_query_arg( 'rtkt_order', $order->get_id(), self::account_url() ); } return add_query_arg( array( 'rtkt_order' => $order->get_id(), 'rtkt_key' => $order->get_order_key(), ), self::portal_base() ); } /** * Link to withdraw from an order. * * @param \WC_Order|null $order Order (null: the general form). * @param bool $guest Force the order key link, e.g. for emails. * @return string */ public static function withdrawal_url( $order = null, $guest = false ) { $base = self::withdrawal_base(); if ( '' === $base ) { $base = self::portal_base(); } if ( ! $order instanceof \WC_Order ) { return $base; } $args = array( 'rtkt_order' => $order->get_id() ); if ( $guest || ! ( $order->get_customer_id() && is_user_logged_in() && get_current_user_id() === (int) $order->get_customer_id() ) ) { $args['rtkt_key'] = $order->get_order_key(); } if ( self::withdrawal_base() === '' ) { $args['rtkt_type'] = 'withdrawal'; } return add_query_arg( $args, $base ); } /** * Link to a request's status page. * * @param Request $request Request. * @param bool $guest Force the token link, e.g. for emails. * @return string */ public static function request_url( Request $request, $guest = false ) { if ( ! $guest && $request->customer_id() && is_user_logged_in() && get_current_user_id() === $request->customer_id() ) { return self::account_url( (string) $request->id() ); } // Emails get the token link even for account holders: they often read // mail while logged out, and My Account would make them log in first. return add_query_arg( array( 'rtkt_request' => $request->id(), 'rtkt_token' => $request->access_token(), ), self::portal_base() ); } /** * The request from the current query, if the visitor may see it. * * @return Request|null */ public static function request_from_query() { // phpcs:disable WordPress.Security.NonceVerification.Recommended -- read-only, authorized by the token. $id = isset( $_GET['rtkt_request'] ) ? absint( $_GET['rtkt_request'] ) : 0; $token = isset( $_GET['rtkt_token'] ) ? sanitize_text_field( wp_unslash( $_GET['rtkt_token'] ) ) : ''; // phpcs:enable if ( ! $id ) { return null; } $request = Requests::get( $id ); return self::can_view_request( $request, $token ) ? $request : null; } /** * Tell caching plugins and proxies not to store a page with personal data. * * @return void */ public static function no_cache() { if ( ! defined( 'DONOTCACHEPAGE' ) ) { define( 'DONOTCACHEPAGE', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedConstantFound -- the constant caching plugins read. } if ( ! headers_sent() ) { nocache_headers(); } } }