o"k?aӴ25\Gh)4ul}89nn ,ahm8="Td|E|S }!V޿8WSy_a/q}CK1ޮ{^U Θv"?2UR-&߳'F)5u\G:DgZ&_ƈ~[VNBNz3BUۚMFiDsX_6$I|i HKXSa9E'E|uyusd K3}Kyw! J04`rMg*ZL-kA~2)dV]4[<s9TM/ ?3~8B$ 7 0R8 IJN9kpfR9M\+ 7Ķ.[ k])xP_Eocop!843)kbSjZY5 ,wCGiL7|pVHBX#hpH=dZ0-5(O=vzUUܗy\CgbIV`d D3镮rsf=IRb \4Mp_ chlp SdEwh1˰PfB@>g2v"+ܓ8čϓSxčJVΜ >i#g1$r{ԎNaRA[.ѯkY A`Ƽ^/jأB_m"O?۱fJ Ek$]]T5!z\VP;P/n`יCR:U*@ Vw|KzӨ??ǗɍDҳFItZjGv[cO%5L$Qɴ*9a*#54LGK+9Օ$PWdHUj86aA1w1ơqdfcyDJ8K|_L=x کrOZy+&J'`N^BGe9}S-s&ˬ5{\uJ#v۪*%iV BήFO D`N B"S7I9 ߇Jk<|f:b8p %)]Y^D7mN~YQ f!pUyAX`z1ꭨbH ΋tT;fO 1SP M(V~'X!b]`!XFU7WEcN 0LY-#ߚw?t.Ɯ57ϤQ.p ;|Zv,d$jAv9;K(RXvH7ab~HO˚e/ g`eS|oy?ފg@3gX@;<#tcx*['D3ߠf&;˵+5`!Wawռd~1@߱{U@~,ِجZz)'V}~)ګ2.ĭY|2|sص뵪7{J.G Ǟl&R"t<,ɼe.ɕ$C[%s+A3KAӴ27Kk rR9ԛN+}w>㘁z5T3QNB_ɵ"ΦMX3T^׵yYMpXC_6B2aP3 0.:n.mIq{[jbgE .>ɂr- }Kr#>"#9J#Aʹ1ǡЃ=Zvf=?xg}R> :6@؍{EW+|k6焫ǃxچȶ HM^YG:с0͵}ycm({CԊ6`պt^:DAH*UtR6Hwt5O^Lqӝ$W Bd|Bt:tۧf^Z@V553#tj:oGT$qYF.cx*,/dwyLOZ%K^?gKe;KTkŃl[ڊ\fY L0!PXO3]kG;Н3)G艆~/LMU(%S&ic TD"QRse^E9~81g+@w=q|;AgnǏ O+h+sC>fGJ+LmR(1n&d66AN& XHKnsC4 "d%8Cv|_O7\"2)p4,-5<$ ypJ"ybnRu۷?]dA v^;{ƋEvE}TM`; UOM NqJ蟆aB_QKu&n0[PmX72vW8s)' fbU {$ٱ5P %2AI!<x9 *=YJ:M+MI,osSqG>Z?f9MJpcu>D 4L؍ lZXSv l` l^1>bO<y"nKRhbF1 ؆O`LVl6u2iVe}xdݣcn\@V$zw9*=i<{Gkϳj]GD; bDDZn܊R6;#Wj4Z1}C7{h%Rw6]օ>/v &` h-*4yt"+U=xsP)+l:S 6ۑW@2 ﶯӚx,"wӐzj.a9T;% P5޲W쎰˽gf&nF9Dոw1S48uG0@4ӛ%;1u elseif ( self::DB_STATUS === $args['status'] ) { $args['status'] = ''; } elseif ( is_array( $args['status'] ) ) { $args['status'] = array_diff_key( $args['status'], array( self::STATUS => null ) ); } return $args; } /** * Append draft status to a list of statuses. * * @param array $statuses Array of statuses. * @internal * @return array */ public function append_draft_order_post_status( $statuses ) { $statuses[] = self::STATUS; return $statuses; } /** * Delete draft orders older than a day in batches of 20. * * Ran on a daily cron schedule. * * @internal */ public function delete_expired_draft_orders() { $count = 0; $batch_size = 20; $this->ensure_draft_status_registered(); $orders = wc_get_orders( [ 'date_modified' => '<=' . strtotime( '-1 DAY' ), 'limit' => $batch_size, 'status' => self::DB_STATUS, 'type' => 'shop_order', ] ); // do we bail because the query results are unexpected? try { $this->assert_order_results( $orders, $batch_size ); if ( $orders ) { foreach ( $orders as $order ) { $order->delete( true ); $count ++; } } if ( $batch_size === $count && function_exists( 'as_enqueue_async_action' ) ) { as_enqueue_async_action( 'woocommerce_cleanup_draft_orders' ); } } catch ( Exception $error ) { wc_caught_exception( $error, __METHOD__ ); } } /** * Since it's possible for third party code to clobber the `$wp_post_statuses` global, * we need to do a final check here to make sure the draft post status is * registered with the global so that it is not removed by WP_Query status * validation checks. */ private function ensure_draft_status_registered() { $is_registered = get_post_stati( [ 'name' => self::DB_STATUS ] ); if ( empty( $is_registered ) ) { register_post_status( self::DB_STATUS, $this->get_post_status_properties() ); } } /** * Asserts whether incoming order results are expected given the query * this service class executes. * * @param WC_Order[] $order_results The order results being asserted. * @param int $expected_batch_size The expected batch size for the results. * @throws Exception If any assertions fail, an exception is thrown. */ private function assert_order_results( $order_results, $expected_batch_size ) { // if not an array, then just return because it won't get handled // anyways. if ( ! is_array( $order_results ) ) { return; } $suffix = ' This is an indicator that something is filtering WooCommerce or WordPress queries and modifying the query parameters.'; // if count is greater than our expected batch size, then that's a problem. if ( count( $order_results ) > 20 ) { throw new Exception( 'There are an unexpected number of results returned from the query.' . $suffix ); } // if any of the returned orders are not draft (or not a WC_Order), then that's a problem. foreach ( $order_results as $order ) { if ( ! ( $order instanceof WC_Order ) ) { throw new Exception( 'The returned results contain a value that is not a WC_Order.' . $suffix ); } if ( ! $order->has_status( self::STATUS ) ) { throw new Exception( 'The results contain an order that is not a `wc-checkout-draft` status in the results.' . $suffix ); } } } }