label, in WooCommerce's order. * * @return array */ public static function choices() { if ( ! function_exists( 'wc_get_order_statuses' ) ) { return array( 'completed' => __( 'Completed', 'careback' ) ); } $out = array(); foreach ( wc_get_order_statuses() as $key => $label ) { $slug = 0 === strpos( (string) $key, 'wc-' ) ? substr( (string) $key, 3 ) : (string) $key; if ( '' === $slug || in_array( $slug, self::EXCLUDED, true ) ) { continue; } $out[ $slug ] = (string) $label; } return $out; } /** * The status that means delivered: the one stored when it is one to choose, * Completed otherwise. * * @param Settings $settings Plugin settings. * @return string Status slug without "wc-". */ public static function delivered_status( Settings $settings ) { $status = sanitize_key( (string) $settings->get( 'delivered_status', 'completed' ) ); if ( 'completed' === $status || ! isset( self::choices()[ $status ] ) ) { return 'completed'; } return $status; } /** * Days added to the day of the status, 0 to 30. * * @param Settings $settings Plugin settings. * @return int */ public static function buffer_days( Settings $settings ) { return max( 0, min( self::BUFFER_MAX, (int) $settings->get( 'delivery_buffer_days', 0 ) ) ); } /** * When the order got the status that means delivered, or 0 when it has * not. For Completed WooCommerce's completion date; for another status the * moment recorded by record(), else — the order in that status now, from * before the record was kept — the day it was last changed. * * @param \WC_Order $order Order. * @param Settings $settings Plugin settings. * @return int Unix timestamp. */ public static function status_reached_at( \WC_Order $order, Settings $settings ) { $status = self::delivered_status( $settings ); if ( 'completed' === $status ) { $completed = $order->get_date_completed(); return $completed ? $completed->getTimestamp() : 0; } $recorded = (int) $order->get_meta( self::STATUS_META ); if ( $recorded > 0 ) { return $recorded; } if ( $order->get_status() === $status ) { $modified = $order->get_date_modified(); return $modified ? $modified->getTimestamp() : 0; } return 0; } /** * Records the moment an order gets the chosen status, when it is not * Completed (WooCommerce keeps that date itself). Runs as the status * changes — in wp-admin, a payment or a shipping plugin, never on a page a * visitor merely opens — and writes the order's meta only. * * @param int $order_id Order id. * @param string $from Status before. * @param string $to Status now. * @param \WC_Order|null $order Order. * @return void */ public static function record( $order_id, $from = '', $to = '', $order = null ) { unset( $from ); $status = self::delivered_status( new Settings() ); if ( 'completed' === $status || (string) $to !== $status ) { return; } $order = $order instanceof \WC_Order ? $order : wc_get_order( (int) $order_id ); if ( ! $order instanceof \WC_Order ) { return; } $order->update_meta_data( self::STATUS_META, (string) time() ); $order->save_meta_data(); } }