�PNG  IHDR22?�� pHYs  �� OiCCPPhotoshop ICC profilexڝSgTS�=���BK���KoR RB���&*! J�!��Q�EEȠ�����Q, � ��!���������{�kּ������>���� �H3Q5� �B�������.@� $p�d!s�#�~<<+"��x� �M��0���B�\���t�8K�@z�B�@F���&S�`�cb�P-`'������{[�!�� e�Dh;��V�EX0fK�9�-0IWfH���� � 0Q��){`�##x��F�W<�+��*x��<�$9E�[-qWW.(�I+6aa�@.�y�2�4���������x����6��_-��"bb���ϫp@�t~��,/��;�m��%�h^ �u��f�@����W�p�~<�5�j>{�-�]c�K'Xt����o��(�h���w��?�G�%�fI�q^D$.Tʳ?�D��*�A��,���� �`6�B$��BB d�r`)��B(�Ͱ*`/�@4�Qh��p.�U�=p�a��(�� A�a!ڈb�X#����!�H�$ ɈQ"K�5H1R�T UH�=r9�\F��;�2����G1���Q=� �C��7�F� �dt1�����r�=�6��Ыhڏ>C�0��3�l0.��B�8, �c˱"� ���V����cϱw�E� 6wB aAHXLXN�H� $4� 7 �Q�'"��K�&���b21�XH,#��/{�C�7$�C2'��I��T��F�nR#�,��4H#���dk�9�, +ȅ����3��!�[ �b@q��S�(R�jJ��4�e�2AU��Rݨ�T5�ZB���R�Q��4u�9̓IK�����hh�i��t�ݕN��W���G���w ��Ljg(�gw��L�Ӌ�T071���oUX*�*|�� �J�&�*/T����ު U�U�T��^S}�FU3S� Ԗ�U��P�SSg�;���g�oT?�~Y��Y�L�OC�Q��_�� c�x,!k ��u�5�&���|v*�����=���9C3J3W�R�f?�q��tN �(���~���)�)�4L�1e\k����X�H�Q�G�6������E�Y��A�J'\'Gg����S�Sݧ �M=:��.�k���Dw�n��^��Lo��y���}/�T�m���G X� $� �<�5qo</���QC]�@C�a�a�ᄑ��<��F�F�i�\�$�m�mƣ&&!&KM�M�RM��)�;L;L���͢�֙5�=1�2��כ߷`ZxZ,����eI��Z�Yn�Z9Y�XUZ]�F���%ֻ�����N�N���gð�ɶ�����ۮ�m�}agbg�Ů��}�}��= ���Z~s�r:V:ޚΜ�?}����/gX���3��)�i�S��Ggg�s�󈋉K��.�>.���Ƚ�Jt�q]�z���������ۯ�6�i�ܟ�4�)�Y3s���C�Q��? ��0k߬~OCO�g��#/c/�W�װ��w��a�>�>r��>�<7�2�Y_�7��ȷ�O�o�_��C#�d�z����%g��A�[��z|!��?:�e����A���AA�������!h�쐭!��Α�i�P~���a�a��~ '���W�?�p�X�1�5w��Cs�D�D�Dޛg1O9�-J5*>�.j<�7�4�?�.fY��X�XIlK9.*�6nl������� �{�/�]py�����.,:�@L�N8��A*��%�w%� y��g"/�6ш�C\*N�H*Mz�쑼5y$�3�,幄'���L Lݛ:��v m2=:�1����qB�!M��g�g�fvˬe����n��/��k���Y- �B��TZ(�*�geWf�͉�9���+��̳�ې7�����ᒶ��KW-X潬j9�������(�x��oʿ�ܔ���Ĺd�f�f���-�[����n �ڴ �V����E�/��(ۻ��C���<��e����;?T�T�T�T6��ݵa��n��{��4���[���>ɾ�UUM�f�e�I���?�������m]�Nmq����#�׹���=TR��+�G�����w- 6 U����#pDy��� �� :�v�{���vg/jB��F�S��[b[�O�>����z�G��499�?r����C�d�&����ˮ/~�����јѡ�򗓿m|������������x31^�V���w�w��O�| (�h���SЧ��������c3-� cHRMz%������u0�`:�o�_�F5IDATx��ytUս�?�;���fN$$��@B�!�k��� -*�gE���j�O�kQ�ʠ`U�B_ �AÐ0%�Ȕ�@r3ޛ;߳��$�@��v����^�s����������$��ߢ !�W��5�̱'-٘������4�>�Rƫ$�G��0U�H}�_ _� #��k�MJ/=�9Du *ڲ�k�PQ;0��j|�*�$�^컂脛y���>�z×� B��� ��(�:$�ʔ_�6��C!B����MVx��a��ζyY����j��ƋY2�9�F�{r��r�딟F��Q��hY6��� x��[l��RC��������nt@��;P��3��� F�w��7��:�P���ɋ'���mj���Bƪ�$�Q�L��y��߷g��\���z����v5�p�v$�v櫻�`6~K �Y�X����,�:��"�o�e0II"(��,������l_�C���/4�+f�E�!q��:����u����c��樼.UE�@� �]K�W���$-�h]�JG���Dz)�`��.�A/ ���mᏣc�3jK� �!�>���$�Q�!�_�? \�C2(E �M$Z I{�U���s�ǣ���=��@Բe ޻��W�����@ �w����}�9v,)��.}*|"�s��di���,���G�]W�AC�������|<����[��ߕ������K�*�G nߴ!��‹��J�!��6(L�a)��Am��������;adf��:�xm��nh�;֦I��(���o�C~ډa?�=��s����h��E������xp����)���_���t��W�����´;8���`dz=(��@@�+,�;�`�fhl��XȌ�3,uI�~z(J����� �ZX�A����H'�À�㜦�82|��a�n�z2��I���� ���EY�h�ε<�0�q�{��C��v�˅��?"@��χ�x�WS+��N�~�KQ�J�8ل�� _.W��� !TU{�����,��"�� �;�������HI S� ��))�o�1�H�D� ���� (� ;����"Ҕ��,���� �F=���O��&�Ph>�`���y��߲ &S��P�<��'��1s�1cĂ�N����2)����@�u��tv��<�+�-&�����h��[!FSG���' � z z0��<����8d&�����E0�,��<��"!P�b4��� �{S�����X����.�囤���T��hEF��X�q0"-<����h���]�Py*����F⩍��@v�˂�Y08�� .q��a��s����(!<̫1�3�L�H��7sYW�`��qtu�\7��?�@�Y�� %Ka�x�GZ�*W�P��y�����N0r9��Z�c�%���q,��k�����!!,��>���IB��� �x1�Xu�Y���v-���ֺ��N������JP��a�2`�e5��w��u;�6�i���̃��(K���ťa��(l51��JL��O'%���]���ٖ뿉!��{*�p+f ���i8��D�ȑ���ܩ�M��V��ӟz��x�7Z�1i}�^͜���6e����x��)u�d�ˏ�V�eG�\�X1�����=n�U'�~Y����L�\,�(d!x ,�:�TW8� M`r���@��r+v�Q0��>^;˴�VbF��('����� �*O��i��j�Ӆ����^�S3&� ���{������.ی�� N;��NU%d0�Ce\r"�C�b��&t7N�7��� �ȪD�[%l�۪�$��'m?�A9tI�9>��NVL ��� 6v~M�����ъ�B���0����9$&=ώm��W�0���L���&��E���f�f��'+�9��hv��7,���M��6�D�&�^� �����8 D֮�����o��k^z��O��hP�8q�5d*��YVq3�{��������#LX4�?��jP=3�~�؅c�ݰ�̱�ұ��8̲��2�G�����j��έ�9��w7���U�X�w�85C��?!I&���o&����L���I#�^�eV�,�^t5�k� �xs˛\��U�8��."���{���ǵ�l4��ݼ�;��r"���G�/~���gJV�N糦��ZZ^k+NN�D��I$�=OE�z����|*�*{��%k���G��>�`9��b;�s���8,�qs��c��.b��q�%�>r��n�R�Ƨ�%�,�A��le#�8���}; 21�0�b�&�QX�f���q�00����$>�h�N�'�a3��A���/�r ��L5�8�GԲ'�����w;��c#�q1���h$*��V^�k��QĽ�b:i������� ����H F#�_���,��]g����Ը����`RUU���� ��"�qD���>-��ϤI�~��3�̴�����NZ[[555�eeek7�m����YF#[��Đ��R��i��L�H�r ��@��J-�Pŝ��_|�-��6y��ks�V�U~��6���w.����(��0A� 4��f��� /���C�xŊ�ٳ����z=6�����rg���mKo��o�/����a�g���?'9%9��P��斓��~���L{�� �H��{AW��B��$����v�1b�&Mb�ر��ر#�0`�`xMBp! )Z�Nmo�mZ�g�}�eذaWTVV ���'99��C5��&�&+5�bT>|8��PUUETT����&���t��~TE%��'������b�tEGG;RSS�S�N�v��ѯ��t����u1@�ޚ"f��͈���r'L�Ph��m��ƌ�74o��`�x�q�P���NRSS�X,�����l&&&��MFFA!-��`��ҷ�n��Yuu�����x<I�LB%����KԒ50�!�3�bz�����ʸKL���;---�l6[��`��������Ȏ;�����egg4��!D�T��jWujyZ��������K����%����p�^���X,6��sV=�ܖ����6�3�X ���4ҿ��A2�&����_k�;d�� �VfOIEND�B`�
Warning: session_start(): Session cannot be started after headers have already been sent in /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php on line 124

Warning: Cannot modify header information - headers already sent by (output started at /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php:1) in /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php on line 130

Warning: Cannot modify header information - headers already sent by (output started at /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php:1) in /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php on line 131

Warning: Cannot modify header information - headers already sent by (output started at /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php:1) in /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php on line 132

Warning: Cannot modify header information - headers already sent by (output started at /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php:1) in /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php on line 133

Warning: Cannot modify header information - headers already sent by (output started at /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php:1) in /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php on line 134

Warning: Cannot modify header information - headers already sent by (output started at /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php:1) in /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php on line 135

Warning: Cannot modify header information - headers already sent by (output started at /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php:1) in /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php on line 547

Warning: Cannot modify header information - headers already sent by (output started at /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php:1) in /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php on line 548

Warning: Cannot modify header information - headers already sent by (output started at /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php:1) in /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php on line 549

Warning: Cannot modify header information - headers already sent by (output started at /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php:1) in /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php on line 550

Warning: Cannot modify header information - headers already sent by (output started at /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php:1) in /home/mciraet/www/wp-includes/php-ai-client/src/Providers/Enums/Documentsoliders.php on line 551
pages[ $id ] = $options; } } /** * Determine the current page ID, if it was registered with this controller. */ public function determine_current_page() { $current_url = ''; $current_screen_id = $this->get_current_screen_id(); if ( isset( $_SERVER['REQUEST_URI'] ) ) { $current_url = esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ); } $current_query = wp_parse_url( $current_url, PHP_URL_QUERY ); parse_str( (string) $current_query, $current_pieces ); $current_path = empty( $current_pieces['page'] ) ? '' : $current_pieces['page']; $current_path .= empty( $current_pieces['path'] ) ? '' : '&path=' . $current_pieces['path']; foreach ( $this->pages as $page ) { if ( isset( $page['js_page'] ) && $page['js_page'] ) { // Check registered admin pages. if ( $page['path'] === $current_path ) { $this->current_page = $page; return; } } else { // Check connected admin pages. if ( isset( $page['screen_id'] ) && $page['screen_id'] === $current_screen_id ) { $this->current_page = $page; return; } } } $this->current_page = false; } /** * Get breadcrumbs for WooCommerce Admin Page navigation. * * @return array Navigation pieces (breadcrumbs). */ public function get_breadcrumbs() { $current_page = $this->get_current_page(); // Bail if this isn't a page registered with this controller. if ( false === $current_page ) { // Filter documentation below. return apply_filters( 'woocommerce_navigation_get_breadcrumbs', array( '' ), $current_page ); } $page_title = ! empty( $current_page['page_title'] ) ? $current_page['page_title'] : $current_page['title']; $page_title = (array) $page_title; if ( 1 === count( $page_title ) ) { $breadcrumbs = $page_title; } else { // If this page has multiple title pieces, only link the first one. $breadcrumbs = array_merge( array( array( $current_page['path'], reset( $page_title ) ), ), array_slice( $page_title, 1 ) ); } if ( isset( $current_page['parent'] ) ) { $parent_id = $current_page['parent']; while ( $parent_id ) { if ( isset( $this->pages[ $parent_id ] ) ) { $parent = $this->pages[ $parent_id ]; if ( 0 === strpos( $parent['path'], self::PAGE_ROOT ) ) { $parent['path'] = 'admin.php?page=' . $parent['path']; } array_unshift( $breadcrumbs, array( $parent['path'], reset( $parent['title'] ) ) ); $parent_id = isset( $parent['parent'] ) ? $parent['parent'] : false; } else { $parent_id = false; } } } $woocommerce_breadcrumb = array( 'admin.php?page=' . self::PAGE_ROOT, __( 'WooCommerce', 'woocommerce' ) ); array_unshift( $breadcrumbs, $woocommerce_breadcrumb ); /** * The navigation breadcrumbs for the current page. * * @param array $breadcrumbs Navigation pieces (breadcrumbs). * @param array|boolean $current_page The connected page data or false if not identified. */ return apply_filters( 'woocommerce_navigation_get_breadcrumbs', $breadcrumbs, $current_page ); } /** * Get the current page. * * @return array|boolean Current page or false if not registered with this controller. */ public function get_current_page() { // If 'current_screen' hasn't fired yet, the current page calculation // will fail which causes `false` to be returned for all subsequent calls. if ( ! did_action( 'current_screen' ) ) { _doing_it_wrong( __FUNCTION__, esc_html__( 'Current page retrieval should be called on or after the `current_screen` hook.', 'woocommerce' ), '0.16.0' ); } if ( is_null( $this->current_page ) ) { $this->determine_current_page(); } return $this->current_page; } /** * Returns the current screen ID. * * This is slightly different from WP's get_current_screen, in that it attaches an action, * so certain pages like 'add new' pages can have different breadcrumbs or handling. * It also catches some more unique dynamic pages like taxonomy/attribute management. * * Format: * - {$current_screen->action}-{$current_screen->action}-tab-section * - {$current_screen->action}-{$current_screen->action}-tab * - {$current_screen->action}-{$current_screen->action} if no tab is present * - {$current_screen->action} if no action or tab is present * * @return string Current screen ID. */ public function get_current_screen_id() { // Return early if this is a REST API request. if ( wp_is_serving_rest_request() ) { /** * Filter the current screen ID for REST API requests. * * @since 3.9.0 * * @param string|boolean $screen_id The screen id or false if not identified. * @param WP_Screen $current_screen The current WP_Screen. */ return apply_filters( 'woocommerce_navigation_current_screen_id', false, null ); } $current_screen = get_current_screen(); if ( ! $current_screen ) { // Filter documentation below. return apply_filters( 'woocommerce_navigation_current_screen_id', false, $current_screen ); } $screen_pieces = array( $current_screen->id ); if ( $current_screen->action ) { $screen_pieces[] = $current_screen->action; } if ( ! empty( $current_screen->taxonomy ) && isset( $current_screen->post_type ) && 'product' === $current_screen->post_type ) { // Editing a product attribute. if ( 0 === strpos( $current_screen->taxonomy, 'pa_' ) ) { $screen_pieces = array( 'product_page_product_attribute-edit' ); } // Editing a product taxonomy term. if ( ! empty( $_GET['tag_ID'] ) ) { $screen_pieces = array( $current_screen->taxonomy ); } } // Pages with default tab values. $pages_with_tabs = apply_filters( 'woocommerce_navigation_pages_with_tabs', array( 'wc-reports' => 'orders', 'wc-settings' => 'general', 'wc-status' => 'status', 'wc-addons' => 'browse-extensions', ) ); // Tabs that have sections as well. $wc_emails = \WC_Emails::instance(); $wc_email_ids = array_map( 'sanitize_title', array_keys( $wc_emails->get_emails() ) ); $tabs_with_sections = apply_filters( 'woocommerce_navigation_page_tab_sections', array( 'products' => array( '', 'inventory', 'downloadable', 'download_urls', 'advanced' ), 'shipping' => array( '', 'options', 'classes', 'pickup_location' ), 'checkout' => array( WC_Gateway_BACS::ID, WC_Gateway_Cheque::ID, WC_Gateway_COD::ID, WC_Gateway_Paypal::ID ), 'email' => $wc_email_ids, 'advanced' => array( '', 'keys', 'webhooks', 'woocommerce_com', 'features', 'blueprint', ), 'browse-extensions' => array( 'helper' ), ) ); if ( ! empty( $_GET['page'] ) ) { $page = wc_clean( wp_unslash( $_GET['page'] ) ); if ( in_array( $page, array_keys( $pages_with_tabs ) ) ) { if ( ! empty( $_GET['tab'] ) ) { $tab = wc_clean( wp_unslash( $_GET['tab'] ) ); } else { $tab = $pages_with_tabs[ $page ]; } $screen_pieces[] = $tab; if ( ! empty( $_GET['section'] ) ) { $section = wc_clean( wp_unslash( $_GET['section'] ) ); if ( isset( $tabs_with_sections[ $tab ] ) && in_array( $section, array_values( $tabs_with_sections[ $tab ] ), true ) ) { $screen_pieces[] = $section; } } // Editing a shipping zone. if ( ( 'shipping' === $tab ) && isset( $_GET['zone_id'] ) ) { $screen_pieces[] = 'edit_zone'; } } } /** * The current screen id. * * Used for identifying pages to render the WooCommerce Admin header. * * @param string|boolean $screen_id The screen id or false if not identified. * @param WP_Screen $current_screen The current WP_Screen. */ return apply_filters( 'woocommerce_navigation_current_screen_id', implode( '-', $screen_pieces ), $current_screen ); } /** * Returns the path from an ID. * * @param string $id ID to get path for. * @return string Path for the given ID, or the ID on lookup miss. */ public function get_path_from_id( $id ) { if ( isset( $this->pages[ $id ] ) && isset( $this->pages[ $id ]['path'] ) ) { return $this->pages[ $id ]['path']; } return $id; } /** * Returns true if we are on a page connected to this controller. * * @return boolean */ public function is_connected_page() { $current_page = $this->get_current_page(); if ( false === $current_page ) { $is_connected_page = false; } else { $is_connected_page = isset( $current_page['js_page'] ) ? ! $current_page['js_page'] : true; } // Disable embed on the block editor. $current_screen = did_action( 'current_screen' ) ? get_current_screen() : false; if ( ! empty( $current_screen ) && method_exists( $current_screen, 'is_block_editor' ) && $current_screen->is_block_editor() ) { $is_connected_page = false; } /** * Whether or not the current page is an existing page connected to this controller. * * Used to determine if the WooCommerce Admin header should be rendered. * * @param boolean $is_connected_page True if the current page is connected. * @param array|boolean $current_page The connected page data or false if not identified. */ return apply_filters( 'woocommerce_navigation_is_connected_page', $is_connected_page, $current_page ); } /** * Returns true if we are on a page registered with this controller. * * @return boolean */ public function is_registered_page() { $current_page = $this->get_current_page(); if ( false === $current_page ) { $is_registered_page = false; } else { $is_registered_page = isset( $current_page['js_page'] ) && $current_page['js_page']; } /** * Whether or not the current page was registered with this controller. * * Used to determine if this is a JS-powered WooCommerce Admin page. * * @param boolean $is_registered_page True if the current page was registered with this controller. * @param array|boolean $current_page The registered page data or false if not identified. */ return apply_filters( 'woocommerce_navigation_is_registered_page', $is_registered_page, $current_page ); } /** * Adds a JS powered page to wc-admin. * * @param array $options { * Array describing the page. * * @type string id Id to reference the page. * @type string title Page title. Used in menus and breadcrumbs. * @type string|null parent Parent ID. Null for new top level page. * @type string path Path for this page, full path in app context; ex /analytics/report * @type string capability Capability needed to access the page. * @type string icon Icon. Dashicons helper class, base64-encoded SVG, or 'none'. * @type int position Menu item position. * @type int order Navigation item order. * } */ public function register_page( $options ) { $defaults = array( 'id' => null, 'parent' => null, 'title' => '', 'page_title' => '', 'capability' => 'view_woocommerce_reports', 'path' => '', 'icon' => '', 'position' => null, 'js_page' => true, ); $options = wp_parse_args( $options, $defaults ); if ( 0 !== strpos( $options['path'], self::PAGE_ROOT ) ) { $options['path'] = self::PAGE_ROOT . '&path=' . $options['path']; } if ( null !== $options['position'] ) { $options['position'] = intval( round( $options['position'] ) ); } if ( empty( $options['page_title'] ) ) { $options['page_title'] = $options['title']; } if ( is_null( $options['parent'] ) ) { add_menu_page( $options['page_title'], $options['title'], $options['capability'], $options['path'], array( __CLASS__, 'page_wrapper' ), $options['icon'], $options['position'] ); } else { $parent_path = $this->get_path_from_id( $options['parent'] ); // @todo check for null path. add_submenu_page( $parent_path, $options['page_title'], $options['title'], $options['capability'], $options['path'], array( __CLASS__, 'page_wrapper' ) ); } $this->connect_page( $options ); } /** * Get registered pages. * * @return array */ public function get_pages() { return $this->pages; } /** * Set up a div for the app to render into. */ public static function page_wrapper() { Loader::page_wrapper(); } /** * Connects existing WooCommerce pages. * * @todo The entry point for the embed needs moved to this class as well. */ public function register_page_handler() { require_once WC_ADMIN_ABSPATH . 'includes/react-admin/connect-existing-pages.php'; } /** * Registers the store details (profiler) page. */ public function register_store_details_page() { wc_admin_register_page( array( 'id' => 'setup-wizard', 'title' => __( 'Setup Wizard', 'woocommerce' ), 'parent' => '', 'path' => '/setup-wizard', ) ); } /** * Remove the menu item for the app entry point page. */ public function remove_app_entry_page_menu_item() { global $submenu; // User does not have capabilities to see the submenu. if ( ! current_user_can( 'manage_woocommerce' ) || empty( $submenu['woocommerce'] ) ) { return; } $wc_admin_key = null; foreach ( $submenu['woocommerce'] as $submenu_key => $submenu_item ) { // Our app entry page menu item has no title. if ( is_null( $submenu_item[0] ) && self::APP_ENTRY_POINT === $submenu_item[2] ) { $wc_admin_key = $submenu_key; break; } } if ( ! $wc_admin_key ) { return; } unset( $submenu['woocommerce'][ $wc_admin_key ] ); } /** * Returns true if we are on a JS powered admin page or * a "classic" (non JS app) powered admin page (an embedded page). */ public static function is_admin_or_embed_page() { return self::is_admin_page() || self::is_embed_page(); } /** * Returns true if we are on a JS powered admin page. */ public static function is_admin_page() { // phpcs:disable WordPress.Security.NonceVerification return isset( $_GET['page'] ) && 'wc-admin' === $_GET['page']; // phpcs:enable WordPress.Security.NonceVerification } /** * Returns true if we are on a settings page. */ public static function is_settings_page() { // phpcs:disable WordPress.Security.NonceVerification return isset( $_GET['page'] ) && 'wc-settings' === $_GET['page']; // phpcs:enable WordPress.Security.NonceVerification } /** * Returns true if we are on a "classic" (non JS app) powered admin page. * * TODO: See usage in `admin.php`. This needs refactored and implemented properly in core. */ public static function is_embed_page() { return wc_admin_is_connected_page(); } /** * Redirect payment tasks to the settings page. * * Redirects both 'payments' and 'woocommerce-payments' tasks to the Payments settings page, * when it is safe to do so in terms of backwards compatibility. */ public function maybe_redirect_payment_tasks_to_settings() { // Bail if we are not in the WP admin or not on a WC admin page. if ( ! is_admin() || ! self::is_admin_page() ) { return; } // Bail if we are not requesting a page for a WooCommerce task. // phpcs:ignore WordPress.Security.NonceVerification if ( empty( $_GET['task'] ) ) { return; } // Only sufficiently capable users should be redirected. if ( ! current_user_can( 'manage_woocommerce' ) ) { return; } // Get the current task ID. // phpcs:ignore WordPress.Security.NonceVerification $task_id = wc_clean( wp_unslash( $_GET['task'] ) ); // Bail if the task is not a payments task. if ( ! in_array( $task_id, array( 'payments', 'woocommerce-payments' ), true ) ) { return; } $redirect_url = admin_url( 'admin.php?page=wc-settings&tab=checkout&from=WCADMIN_PAYMENT_TASK' ); // The WooPayments task is always redirected to the settings page. if ( 'woocommerce-payments' === $task_id ) { wp_safe_redirect( $redirect_url ); exit; } // The generic payments task is only redirected if the request is a regular user request, // not part of an onboarding flow or other special case. $special_request_params = array( // This is used by the legacy, Payments task-based suggestions onboarding flow. // Nobody should be using this anymore, but just in case. 'connection-return', // This is used by the legacy, Payments task-based suggestions onboarding flow. // Nobody should be using this anymore, but just in case. 'id', // Some params for gateway IDs, just in case. 'gateway_id', 'gateway-id', // Sometimes the gateway is referred to as 'method'. Stay clear of it. 'method', // If there is a success or error param, better not redirect. 'success', 'error', // If the URL is nonced, better not redirect. '_wpnonce', ); foreach ( $special_request_params as $param ) { // phpcs:ignore WordPress.Security.NonceVerification if ( isset( $_GET[ $param ] ) ) { return; } } // If we reach this point, we can safely redirect to the settings page. wp_safe_redirect( $redirect_url ); exit; } }