Plugin Directory

Changeset 3061787


Ignore:
Timestamp:
03/31/2024 04:35:08 PM (23 months ago)
Author:
casepress
Message:

Update to version 9.11 from GitHub

Location:
wooms
Files:
2 added
18 edited
1 copied

Legend:

Unmodified
Added
Removed
  • wooms/tags/9.11/includes/MenuTools.php

    r2854597 r3061787  
    22
    33namespace WooMS;
     4
    45/**
    56 *  Tool for MoySklad
     
    78class MenuTools {
    89
    9   /**
    10   * URL action
    11   */
    12   public static $url;
     10    /**
     11    * URL action
     12    */
     13    public static $url;
    1314
    14   /**
    15   * The Init
    16   */
    17   public static function init(){
     15    /**
     16    * The Init
     17    */
     18    public static function init() {
    1819
    19     self::$url = $_SERVER['REQUEST_URI'];
     20        self::$url = $_SERVER['REQUEST_URI'];
    2021
    21     add_action(
    22       'admin_menu',
    23       function () {
     22        add_action(
     23            'admin_menu',
     24            function () {
    2425
    25         if(current_user_can('manage_woocommerce')){
    26           add_menu_page(
    27             $page_title = 'МойСклад',
    28             $menu_title = 'МойСклад',
    29             $capability = 'manage_woocommerce',
    30             $menu_slug = 'moysklad',
    31             $function = array( __CLASS__, 'display_ui' ),
    32             $icon = 'dashicons-forms',
    33             '57.5'
    34           );
    35         }
     26                if ( current_user_can( 'manage_woocommerce' ) ) {
     27                    add_menu_page(
     28                        $page_title = 'МойСклад',
     29                        $menu_title = 'МойСклад',
     30                        $capability = 'manage_woocommerce',
     31                        $menu_slug = 'moysklad',
     32                        $function = array ( __CLASS__, 'display_ui' ),
     33                        $icon = 'dashicons-forms',
     34                        '57.5'
     35                    );
     36                }
    3637
    37       }
    38     );
     38            }
     39        );
    3940
    4041
    41   }
     42    }
    4243
    43   /**
    44    * Display UI
    45    */
    46   public static function display_ui()
    47   {
    48     printf('<h1>%s</h1>', 'Управление МойСклад');
    49     $items = [
    50       '<a style="color:green;" href="https://github.com/wpcraft-ru/wooms/wiki/GettingStarted" target="_blank">
    51           <strong>Начало работы</strong>
    52       </a>',
    53       sprintf('<a href="%s">Настройки</a>', admin_url("admin.php?page=mss-settings") ),
    54       '<a href="https://online.moysklad.ru/app/" target="_blank">Вход в МойСклад</a>',
    55       sprintf('<a href="%s">Диагностика проблем</a>', admin_url("site-health.php") ),
    56       '<a href="https://wpcraft.ru/hosting-wordpress-woocommerce/" target="_blank">Рекомендуемые хостинги</a>',
    57       '<a href="https://wpcraft.ru/wooms/" target="_blank">Контакты</a>',
    58     ];
    59 
    60     printf( '<p>%s</p>', implode('<span> | </span>', $items) );
    61 
    62     if(empty(get_option('woomss_pass'))){
    63       printf('<p>Укажите логин и пароль на <a href="%s">странице настроек</a></p>', admin_url('admin.php?page=mss-settings'));
    64     } else {
    65       if( empty($_GET['a']) ){
    66 
    67         do_action('wooms_tools_sections');
    68 
    69         // deprecated
    70         do_action('woomss_tool_actions_btns');
    71 
    72       } else {
    73 
    74         printf('<a href="%s">Вернуться...</a>', remove_query_arg( 'a', self::$url));
    75         do_action('woomss_tool_actions');
    76         do_action('woomss_tool_actions_' . $_GET['a']);
    77 
    78       }
    79     }
     44    /**
     45     * Display UI
     46     */
     47    public static function display_ui() {
     48        printf( '<h1>%s</h1>', 'Управление МойСклад' );
     49        $items = [
     50            sprintf( '<a href="%s">Настройки</a>', admin_url( "admin.php?page=mss-settings" ) ),
     51            '<a href="https://online.moysklad.ru/app/" target="_blank">Вход в МойСклад</a>',
     52            sprintf( '<a href="%s">Здоровье сайта</a>', admin_url( "site-health.php" ) ),
     53            '<a href="https://wpcraft.ru/blog/hosting-wordpress-woocommerce/" target="_blank">Рекомендуемые хостинги</a>',
     54            '<a href="https://wpcraft.ru/wooms/" target="_blank">Контакты</a>',
     55        ];
     56        ?>
     57        <div>
     58            <a href="https://wpcraft.ru/wooms/" class="button button-primary" target="_blank">Решаем проблемы</a>
     59            <br />
     60            <?= sprintf( '<p>%s</p>', implode( '<span> | </span>', $items ) ); ?>
     61        </div>
     62        <?php
    8063
    8164
    82   }
     65        if ( empty( get_option( 'woomss_pass' ) ) ) {
     66            printf( '<p>Укажите логин и пароль на <a href="%s">странице настроек</a></p>', admin_url( 'admin.php?page=mss-settings' ) );
     67        } else {
     68            if ( empty( $_GET['a'] ) ) {
     69
     70                do_action( 'wooms_tools_sections' );
     71
     72                // deprecated
     73                do_action( 'woomss_tool_actions_btns' );
     74
     75            } else {
     76
     77                printf( '<a href="%s">Вернуться...</a>', remove_query_arg( 'a', self::$url ) );
     78                do_action( 'woomss_tool_actions' );
     79                do_action( 'woomss_tool_actions_' . $_GET['a'] );
     80
     81            }
     82        }
     83
     84
     85    }
    8386
    8487
  • wooms/tags/9.11/includes/ProductStocks.php

    r3010225 r3061787  
    33namespace WooMS;
    44
     5use WC_Product;
    56use function WooMS\request;
    67
     8use function WooMS\get_config as get_config;
     9use function WooMS\get_config_name as get_config_name;
    710
    811defined( 'ABSPATH' ) || exit; // Exit if accessed directly
     
    2730    public static function init() {
    2831
     32        // add_action( 'init', function () {
     33        //  if ( ! isset ( $_GET['test_ProductStocks'] ) ) {
     34        //      return;
     35        //  }
     36
     37        //  // do_action('wooms_assortment_sync');
     38        //  // var_dump(1); exit;
     39
     40        //  $meta = get_post_meta( 68934 );
     41        //  echo '<pre>';
     42        //  var_dump( $meta );
     43        //  exit;
     44        // } );
     45
     46        add_filter( 'wooms_stock_product_save', [ __CLASS__, 'update_manage_stock' ], 10, 2 );
     47
    2948        add_action( 'wooms_assortment_sync', [ __CLASS__, 'batch_handler' ] );
    3049
     
    3756        add_action( 'wooms_variations_batch_end', [ __CLASS__, 'restart_after_batch' ] );
    3857        add_action( 'wooms_products_batch_end', [ __CLASS__, 'restart_after_batch' ] );
    39         add_action( 'wooms_main_walker_started', [ __CLASS__, 'restart' ] );
    40 
    41         add_action( 'admin_init', [__CLASS__, 'add_settings'], 30 );
     58
     59        add_action( 'admin_init', [ __CLASS__, 'add_settings' ], 30 );
    4260        add_action( 'wooms_tools_sections', array( __CLASS__, 'display_state' ), 17 );
    4361
    44         add_filter( 'wooms_stock_type', array( __CLASS__, 'select_type_stock' ) );
    45 
    46         //need for disable reset state for base plugin
    47         add_filter( 'wooms_reset_state_products', function ($reset) {
    48             return false;
    49         } );
    50     }
    51 
    52 
    53     public static function batch_handler($state = []) {
    54         if(empty($state)){
     62        // add_filter( 'wooms_stock_type', array( __CLASS__, 'select_type_stock' ) );
     63
     64    }
     65
     66
     67    public static function batch_handler( $state = [] ) {
     68        if ( empty( $state ) ) {
    5569            $state = [
    5670                'count' => 0
     
    7488
    7589        $products = get_posts( $args );
    76         if ( empty($products) ) {
    77             self::set_state( 'finish_timestamp', time() );
     90
     91        if ( empty( $products ) ) {
    7892            return false;
    7993        }
    8094
    81         $filters = [];
     95        $filters_by_id = [];
    8296        foreach ( $products as $product ) {
    83             $filters[] = 'id=' . get_post_meta( $product->ID, 'wooms_id', true );
    84         }
    85 
    86         // todo - переписать это как то лучше
     97            $filters_by_id[] = 'id=' . get_post_meta( $product->ID, 'wooms_id', true );
     98            delete_post_meta( $product->ID, self::$walker_hook_name );
     99        }
     100
     101        $filters = [
     102            implode( ';', $filters_by_id )
     103        ];
     104
    87105        $url = 'https://api.moysklad.ru/api/remap/1.2/entity/assortment';
    88106
     
    101119        $data = request( $url );
    102120
     121        // var_dump($data); exit;
     122
    103123        if ( empty( $data['rows'] ) ) {
    104124            return false;
    105125        }
    106126
    107 
    108         $ids = self::process_rows($data['rows']);
    109         if($ids){
     127        $ids = self::process_rows( $data['rows'] );
     128        if ( $ids ) {
    110129            $state['last_ids'] = $ids;
    111130        }
    112131
    113         $state['count'] += count($data['rows']);
    114 
    115         return as_schedule_single_action( time(), self::$walker_hook_name, [$state], 'WooMS' );
    116 
    117     }
    118 
    119     public static function process_rows($rows){
     132        $state['count'] += count( $data['rows'] );
     133
     134        return as_schedule_single_action( time(), self::$walker_hook_name, [ $state ], 'WooMS' );
     135
     136    }
     137
     138    public static function process_rows( $rows ) {
    120139
    121140        $ids = [];
    122141        foreach ( $rows as $row ) {
    123142
    124             if ( ! $product_id = self::get_product_id_by_uuid( $row['id'] ) ) {
     143            if ( ! $product_id = Helper::get_product_id_by_uuid( $row['id'] ) ) {
     144                Helper::log_error( 'Не нашли продукт по uuid', __CLASS__, $row );
    125145                continue;
    126146            }
    127147
    128148            if ( ! $product = wc_get_product( $product_id ) ) {
     149                Helper::log_error( 'Не нашли продукт по $product_id', __CLASS__, $row );
    129150                continue;
    130151            }
     
    133154
    134155            $product->update_meta_data( 'wooms_assortment_data', self::get_stock_data_log( $row, $product_id ) );
    135             $product->delete_meta_data( self::$walker_hook_name );
     156
    136157
    137158            /**
     
    142163            $product = apply_filters( 'wooms_stock_product_save', $product, $row );
    143164
     165
    144166            $ids[] = $product->save();
    145167        }
    146168
    147169        return $ids;
     170
     171    }
     172
     173
     174    public static function update_stock( WC_Product $product, $data_api ): WC_Product {
     175
     176        //если продукт вариативный, то его наличие определяется его вариациями и это отдельный поток хуков
     177        if ( $product->get_type() === 'variable' ) {
     178            return $product;
     179        }
     180
     181        /**
     182         * Поле по которому берем остаток?
     183         * quantity = это доступные остатки за вычетом резервов
     184         * stock = это все остатки без уета резерва
     185         */
     186        if(get_config('stock_and_reserve')){
     187            $stock = (int) $data_api['quantity'] ?? 0;
     188        } else {
     189            $stock = (int) $data_api['stock'] ?? 0;
     190        }
     191
     192        if ( $stock > 0 ) {
     193            $product->set_stock_quantity( $stock );
     194            $product->set_stock_status( 'instock' );
     195        } else {
     196            $product->set_stock_quantity( 0 );
     197            $product->set_stock_status( 'outofstock' );
     198        }
     199
     200        $log_data = [
     201            'stock' => $data_api['stock'],
     202            'quantity' => $data_api['quantity'],
     203            'type' => $product->get_type(),
     204        ];
     205
     206        if ( $product->get_type() === 'variation' ) {
     207            $log_data['product_parent'] = $product->get_parent_id();
     208        }
     209
     210        Helper::log( sprintf(
     211            'Остатки для продукта "%s" (ИД %s) = %s', $product->get_name(), $product->get_id(), $product->get_stock_quantity() ),
     212            __CLASS__,
     213            $log_data
     214        );
     215
     216        return $product;
     217    }
     218
     219
     220    /**
     221     * Если у сайта включена опция управление остатками - установить остатки для товара
     222     *
     223     * @todo вероятно опция типа wooms_warehouse_count - более не нужна
     224     */
     225    public static function update_manage_stock( WC_Product $product, $data_api ): WC_Product {
     226
     227        if ( ! get_option( 'woocommerce_manage_stock' ) ) {
     228            return $product;
     229        }
     230
     231        if ( ! $product->get_manage_stock() ) {
     232            $product->set_manage_stock( true );
     233            Helper::log( sprintf(
     234                'Включили управление запасами для продукта: %s (ИД %s)', $product->get_name(), $product->get_id() ),
     235                __CLASS__
     236            );
     237        }
     238
     239        //для вариативных товаров доступность определяется наличием вариаций
     240        if ( $product->get_type() === 'variation' ) {
     241
     242            $parent_id = $product->get_parent_id();
     243            $parent_product = wc_get_product( $parent_id );
     244            if ( empty( $parent_product ) ) {
     245                Helper::log_error( "Не нашли родительский продукт: {$parent_id}, вариация: {$product->get_id()}",
     246                    __CLASS__
     247                );
     248                return $product;
     249            }
     250            if ( $parent_product->get_manage_stock() ) {
     251
     252                Helper::log( sprintf(
     253                    'У основного продукта отключили управление остатками: %s (ИД %s)', $parent_product->get_name(), $parent_id ),
     254                    __CLASS__
     255                );
     256                $parent_product->set_manage_stock( false );
     257
     258                $parent_product->save();
     259            }
     260
     261        }
     262
     263        /**
     264         * это похоже надо выпилить
     265         *
     266         * потому что это не относится к синку МС и должно управляться как то иначе
     267         *
     268         * если это тут оставлять, то эта отметка должна быть на стороне МС
     269         */
     270        // if ( get_option( 'wooms_stock_empty_backorder' ) ) {
     271        // $product->set_backorders( 'notify' );
     272        // } else {
     273        // $product->set_backorders( 'no' );
     274        // }
     275
     276
     277        return $product;
    148278
    149279    }
     
    168298    }
    169299
    170     public static function update_stock( $product, $data_api ) {
    171         $product = wc_get_product( $product );
    172 
    173         $product_id = $product->get_id();
    174 
    175         /**
    176          * Поле по которому берем остаток?
    177          * quantity = это доступные остатки за вычетом резервов
    178          * stock = это все остатки без уета резерва
    179          */
    180         $stock_type = apply_filters( 'wooms_stock_type', 'quantity' );
    181 
    182         $stock = 0;
    183 
    184         if ( empty( $data_api[ $stock_type ] ) ) {
    185             $stock = 0;
    186         } else {
    187             $stock = (int) $data_api[ $stock_type ];
    188         }
    189 
    190         if ( get_option( 'wooms_stock_empty_backorder' ) ) {
    191             $product->set_backorders( 'notify' );
    192         } else {
    193             $product->set_backorders( 'no' );
    194         }
    195 
    196         if ( empty( get_option( 'wooms_warehouse_count' ) ) ) {
    197             $product->set_manage_stock( false );
    198         } else {
    199             if ( $product->is_type( 'variable' ) ) {
    200                 //для вариативных товаров доступность определяется наличием вариаций
    201                 $product->set_manage_stock( false );
    202             } else {
    203                 $product->set_manage_stock( true );
    204             }
    205         }
    206 
    207         if ( $stock <= 0 ) {
    208             if ( ! $product->is_type( 'variable' ) ) {
    209                 $product->set_stock_quantity( 0 );
    210                 $product->set_stock_status( 'outofstock' );
    211             }
    212         } else {
    213             $product->set_stock_quantity( $stock );
    214             $product->set_stock_status( 'instock' );
    215         }
    216 
    217         do_action(
    218             'wooms_logger',
    219             __CLASS__,
    220             sprintf( 'Остатки для продукта "%s" = %s (ИД %s)', $product->get_name(), $stock, $product_id ),
    221             sprintf( 'stock %s, quantity %s', $data_api['stock'], $data_api['quantity'] )
    222         );
    223 
    224         return $product;
    225     }
    226 
    227     /**
    228      * restart walker after added tast to queue
    229      */
    230     public static function restart() {
    231         self::set_state( 'finish_timestamp', 0 );
    232         self::set_state( 'count_all', 0 );
    233         self::set_state( 'count_save', 0 );
    234     }
    235 
    236300
    237301    public static function restart_after_batch() {
    238         if(as_has_scheduled_action(self::$walker_hook_name)){
     302        if ( ! self::is_enable() ) {
    239303            return;
    240304        }
    241305
     306        if ( as_has_scheduled_action( self::$walker_hook_name ) ) {
     307            return;
     308        }
     309
    242310        as_schedule_single_action( time(), self::$walker_hook_name, [], 'WooMS' );
    243     }
    244 
    245 
    246 
    247 
    248     /**
    249      * check is wait
    250      */
    251     public static function is_wait() {
    252         if ( self::get_state( 'finish_timestamp' ) ) {
    253             return true;
    254         }
    255 
    256         return false;
    257311    }
    258312
     
    279333
    280334
    281 
    282 
    283     /**
    284      * set state data
    285      */
    286335    public static function set_state( $key, $value ) {
    287336
     
    373422    }
    374423
    375     /**
    376      * Select type stock
    377      */
    378     public static function select_type_stock( $type_stock ) {
    379         if ( get_option( 'wooms_stocks_without_reserve' ) ) {
    380             $type_stock = 'stock';
    381         }
    382 
    383         return $type_stock;
    384     }
    385424
    386425    /**
    387426     * Update stock for variation
    388427     */
    389     public static function update_variation( $variation, $data_api ) {
     428    public static function update_variation( \WC_Product_Variation $variation, $data_api ) {
    390429        if ( self::is_enable() ) {
    391430            $variation->update_meta_data( self::$walker_hook_name, 1 );
     
    393432            $variation->set_catalog_visibility( 'visible' );
    394433            $variation->set_stock_status( 'instock' );
    395             $variation->set_manage_stock( 'no' );
     434            $variation->set_manage_stock( false );
    396435            $variation->set_status( 'publish' );
    397436        }
     
    410449            $product->set_catalog_visibility( 'visible' );
    411450            $product->set_stock_status( 'instock' );
    412             $product->set_manage_stock( 'no' );
     451            $product->set_manage_stock( false );
    413452            $product->set_status( 'publish' );
    414453        }
     
    438477        );
    439478
    440         register_setting( 'mss-settings', 'wooms_stocks_without_reserve' );
    441479        add_settings_field(
    442             $id = 'wooms_stocks_without_reserve',
    443             $title = 'Остатки без резерва',
    444             $callback = array( __CLASS__, 'display_field_wooms_stocks_without_reserve' ),
     480            $id = 'stock_and_reserve',
     481            $title = 'Учитывать остатки с резервом',
     482            $callback = function ($args) {
     483                printf( '<input type="checkbox" name="%s" value="1" %s />', $args['name'], $args['value'] );
     484
     485            },
    445486            $page = 'mss-settings',
    446             $section = 'woomss_section_warehouses'
    447         );
    448 
    449         register_setting( 'mss-settings', 'wooms_warehouse_count' );
    450         add_settings_field(
    451             $id = 'wooms_warehouse_count',
    452             $title = 'Управление запасами на уровне товаров',
    453             $callback = array( __CLASS__, 'display_wooms_warehouse_count' ),
    454             $page = 'mss-settings',
    455             $section = 'woomss_section_warehouses'
    456         );
    457 
    458         register_setting( 'mss-settings', 'wooms_stock_empty_backorder' );
    459         add_settings_field(
    460             $id = 'wooms_stock_empty_backorder',
    461             $title = 'Разрешать предзаказ при 0 остатке',
    462             $callback = array( __CLASS__, 'display_wooms_stock_empty_backorder' ),
    463             $page = 'mss-settings',
    464             $section = 'woomss_section_warehouses'
    465         );
     487            $section,
     488            $args = [
     489                'name' => get_config_name( 'stock_and_reserve' ),
     490                'value' => checked( 1, get_config( 'stock_and_reserve' ) ),
     491            ]
     492        );
     493
     494        // register_setting( 'mss-settings', 'wooms_warehouse_count' );
     495        // add_settings_field(
     496        //  $id = 'wooms_warehouse_count',
     497        //  $title = 'Управление запасами на уровне товаров',
     498        //  $callback = array( __CLASS__, 'display_wooms_warehouse_count' ),
     499        //  $page = 'mss-settings',
     500        //  $section = 'woomss_section_warehouses'
     501        // );
     502
     503        // register_setting( 'mss-settings', 'wooms_stock_empty_backorder' );
     504        // add_settings_field(
     505        //  $id = 'wooms_stock_empty_backorder',
     506        //  $title = 'Разрешать предзаказ при 0 остатке',
     507        //  $callback = array( __CLASS__, 'display_wooms_stock_empty_backorder' ),
     508        //  $page = 'mss-settings',
     509        //  $section = 'woomss_section_warehouses'
     510        // );
    466511
    467512        self::add_setting_warehouse_id();
     
    482527                $url = 'entity/store';
    483528                $data = request( $url );
    484                 if ( empty( $data['rows'] ) ) {
     529                if ( empty ( $data['rows'] ) ) {
    485530                    echo 'Система не смогла получить список складов из МойСклад';
    486531                    return;
     
    547592    }
    548593
    549     /**
    550      * display_field_wooms_stocks_without_reserve
    551      */
    552     public static function display_field_wooms_stocks_without_reserve() {
    553         $option = 'wooms_stocks_without_reserve';
    554         printf( '<input type="checkbox" name="%s" value="1" %s />', $option, checked( 1, get_option( $option ), false ) );
    555         echo '<p><small>Если включить опцию то на сайте будут учитываться остатки без учета резерва</small></p>';
    556     }
    557594
    558595    /**
     
    594631        }
    595632
    596         if ( $end_timestamp = self::get_state( 'finish_timestamp' ) ) {
    597             $end_timestamp = date( 'Y-m-d H:i:s', $end_timestamp );
    598             $strings[] = sprintf( 'Последняя успешная синхронизация (отметка времени UTC): %s', $end_timestamp );
    599         }
     633
     634        $strings[] = sprintf( 'Последняя успешная синхронизация: %s', Helper::get_timestamp_last_job_by_hook( self::$walker_hook_name ) ) ?? 'Нет данных';
    600635
    601636        $strings[] = sprintf( 'Очередь задач: <a href="%s">открыть</a>', admin_url( 'admin.php?page=wc-status&tab=action-scheduler&s=wooms_assortment_sync&orderby=schedule&order=desc' ) );
    602637
    603 
    604         if ( defined( 'WC_LOG_HANDLER' ) && 'WC_Log_Handler_DB' == WC_LOG_HANDLER ) {
    605             $strings[] = sprintf( 'Журнал обработки: <a href="%s">открыть</a>', admin_url( 'admin.php?page=wc-status&tab=logs&source=WooMS-ProductStocks' ) );
    606         } else {
    607             $strings[] = sprintf( 'Журнал обработки: <a href="%s">открыть</a>', admin_url( 'admin.php?page=wc-status&tab=logs' ) );
    608         }
     638        $strings[] = sprintf( 'Журнал обработки: <a href="%s">открыть</a>', admin_url( 'admin.php?page=wc-status&tab=logs&source=WooMS-ProductStocks' ) );
    609639
    610640        ?>
    611641        <h2>Остатки</h2>
    612642        <div class="wrap">
    613             <div id="message" class="notice notice-warning">
    614                 <?php
    615                 foreach ( $strings as $string ) {
    616                     printf( '<p>%s</p>', $string );
    617                 }
    618                 ?>
    619             </div>
     643
     644            <?php
     645            foreach ( $strings as $string ) {
     646                printf( '<p>%s</p>', $string );
     647            }
     648            ?>
     649
    620650        </div>
    621651
  • wooms/tags/9.11/includes/ProductVariable.php

    r2989239 r3061787  
    44
    55use function WooMS\request;
     6
    67
    78
     
    1314 */
    1415class ProductVariable {
     16
    1517    /**
    1618     * Save state in DB
     
    2729    public static $walker_hook_name = 'wooms_variables_walker_batch';
    2830
    29 
    30     /**
    31      * The init
    32      */
    3331    public static function init() {
    3432
    35         //walker
    3633        add_action( 'wooms_variables_walker_batch', [__CLASS__, 'walker'] );
    3734
     
    7168            ];
    7269
    73             self::set_state( $state );
     70
    7471        }
    7572
     
    8178        $url = add_query_arg( $state['query_arg'], $url );
    8279
    83         $filters = [];
     80        $filters = [
     81            'archived=false'
     82        ];
    8483
    8584        $filters = apply_filters( 'wooms_url_get_variants_filter', $filters );
     
    116115            $state['count'] += $i;
    117116            $state['query_arg']['offset'] += count( $data['rows'] );
    118             self::set_state( $state );
     117
    119118
    120119            do_action( 'wooms_variations_batch_end' );
     
    124123            return true;
    125124        } catch (\Exception $e) {
    126             self::set_state( 'lock', 0 );
    127             do_action(
    128                 'wooms_logger_error',
    129                 __CLASS__,
    130                 $e->getMessage()
    131             );
     125
     126            Helper::log_error( $e->getMessage(), __CLASS__  );
    132127            return false;
    133128        }
     
    142137        foreach ( $rows as $key => $row ) {
    143138
    144             if ( $row["meta"]["type"] != 'variant' ) {
     139            try {
     140                if ( $row["meta"]["type"] != 'variant' ) {
     141                    continue;
     142                }
     143
     144                $i++;
     145
     146                self::update_variation( $row );
     147
     148            } catch (\Exception $e) {
     149                Helper::log_error( $e->getMessage(), __CLASS__  );
    145150                continue;
    146151            }
    147 
    148             $i++;
    149 
    150             self::update_variation( $row );
    151152
    152153        }
     
    160161    public static function set_wait() {
    161162        as_unschedule_all_actions( self::$walker_hook_name );
    162         self::set_state( 'end_timestamp', time() );
     163
    163164    }
    164165
     
    330331        $variation->set_attributes( $attributes );
    331332
    332         do_action(
    333             'wooms_logger',
    334             __CLASS__,
    335             sprintf( 'Сохранены атрибуты для вариации %s (продукт: %s)', $variation_id, $product_id ),
    336             wc_print_r( $attributes, true )
    337         );
     333        Helper::log('Сохранены атрибуты для вариации', __CLASS__, [
     334            'name' => $variation->get_name(),
     335            'variation_id' => $variation_id,
     336            'product_id' => $product_id,
     337            'attributes' => $attributes,
     338        ]);
    338339
    339340        return $variation;
     
    350351
    351352        if ( ! empty( $row['archived'] ) ) {
    352             return null;
     353            return;
    353354        }
    354355
     
    358359
    359360        $product_href = $row['product']['meta']['href'];
    360         $product_id = self::get_product_id_by_uuid( $product_href );
     361        $product_id = Helper::get_product_id_by_uuid( $product_href );
    361362        $product_parent = wc_get_product( $product_id );
    362363
    363364        if(empty($product_parent)){
    364             do_action(
    365                 'wooms_logger_error',
    366                 __CLASS__,
    367                 sprintf( 'Нет базового продукта для вариации. %s', json_encode( ['product_id' => $product_id, '$row id' => $row ] ) )
    368             );
    369 
    370             return null;
    371 
     365            /**
     366             * так бывает
     367             * мы получаем вариации всей пачкой и для каких то может не быть базового продукта
     368             * чаще всего это не ошибка, но может быть и она
     369             */
     370            Helper::log('Нет базового продукта для вариации', __CLASS__, $row);
     371            return;
    372372        }
    373373
     
    376376            $product_parent->save();
    377377
    378             do_action(
    379                 'wooms_logger_error',
    380                 __CLASS__,
    381                 sprintf( 'Снова сохранили продукт как вариативный %s', $product_id )
    382             );
     378            Helper::log(sprintf( 'Снова сохранили продукт как вариативный %s', $product_id ), __CLASS__);
    383379        }
    384380
     
    433429
    434430        $variation = apply_filters( 'wooms_variation_save', $variation, $row, $product_id );
     431        $variation = apply_filters( 'wooms_variation_update', $variation, $row, $product_id );
    435432
    436433        $variation_id = $variation->save();
     
    546543     */
    547544    public static function walker_finish() {
    548         self::set_state( 'end_timestamp', time() );
    549         self::set_state( 'lock', 0 );
     545
    550546
    551547        do_action( 'wooms_wakler_variations_finish' );
     
    598594    }
    599595
    600 
    601     public static function is_wait() {
    602         //check run main walker
    603         if ( as_next_scheduled_action( 'wooms_products_walker_batch' ) ) {
    604             return true;
    605         }
    606 
    607         //check end pause
    608         if ( ! empty( self::get_state( 'end_timestamp' ) ) ) {
    609             return true;
    610         }
    611 
    612         return false;
    613     }
    614 
    615 
    616 
    617     /**
    618      * display_state
    619      */
    620596    public static function display_state() {
    621597
     
    644620
    645621        } else {
    646             $strings[] = sprintf( '<strong>Статус:</strong> %s', 'в ожидании задач' );
    647             $strings[] = sprintf( 'Последняя успешная синхронизация: %s', wooms_get_timestamp_last_job_by_hook( self::$walker_hook_name ) );
    648         }
    649 
     622            $strings[] = sprintf( '<strong>Статус:</strong> %s', 'Завершено' );
     623            $strings[] = sprintf( 'Последняя успешная синхронизация: %s', Helper::get_timestamp_last_job_by_hook( self::$walker_hook_name ) ) ?? 'Нет данных';
     624        }
    650625
    651626        $strings[] = sprintf( 'Очередь задач: <a href="%s">открыть</a>', admin_url( 'admin.php?page=wc-status&tab=action-scheduler&s=wooms_variables_walker_batch&orderby=schedule&order=desc' ) );
    652627
    653 
    654         if ( defined( 'WC_LOG_HANDLER' ) && 'WC_Log_Handler_DB' == WC_LOG_HANDLER ) {
    655             $strings[] = sprintf( 'Журнал обработки: <a href="%s">открыть</a>', admin_url( 'admin.php?page=wc-status&tab=logs&source=WooMS-ProductVariable' ) );
    656         } else {
    657             $strings[] = sprintf( 'Журнал обработки: <a href="%s">открыть</a>', admin_url( 'admin.php?page=wc-status&tab=logs' ) );
    658         }
     628        $strings[] = sprintf( 'Журнал обработки: <a href="%s">открыть</a>', admin_url( 'admin.php?page=wc-status&tab=logs&source=WooMS-ProductVariable' ) );
    659629
    660630        ?>
     
    767737    }
    768738
    769 
    770 
    771     /**
    772      * get state data
    773      */
    774     public static function get_state( $key = '' ) {
    775         if ( ! $state = get_option( self::$state_transient_key ) ) {
    776             $state = [];
    777             update_option( self::$state_transient_key, $state );
    778         }
    779 
    780         if ( empty( $key ) ) {
    781             return $state;
    782         }
    783 
    784         if ( empty( $state[ $key ] ) ) {
    785             return null;
    786         }
    787 
    788         return $state[ $key ];
    789     }
    790 
    791     /**
    792      * set state data
    793      */
    794     public static function set_state( $key, $value = null ) {
    795         if ( $value === null && is_array( $key ) ) {
    796             update_option( self::$state_transient_key, $key, false );
    797             return;
    798         }
    799 
    800         if ( ! $state = get_option( self::$state_transient_key ) ) {
    801             $state = [];
    802         }
    803 
    804         if ( is_array( $state ) ) {
    805             $state[ $key ] = $value;
    806         } else {
    807             $state = [];
    808             $state[ $key ] = $value;
    809         }
    810 
    811         update_option( self::$state_transient_key, $state, false );
    812     }
    813 
    814739    /**
    815740     * show wooms_id for variation in admin
  • wooms/tags/9.11/includes/Products.php

    r2989239 r3061787  
    55use function WooMS\request;
    66use function Testeroid\ddcli;
    7 use Error, Throwable, WC_Product;
     7use Error, Throwable, WC_Product, WooMS\Helper;
    88
    99defined( 'ABSPATH' ) || exit;
     
    6161
    6262    $filters = [
    63         // 'pathName~=Диваны',
     63        'archived=false'
    6464    ];
    6565
     
    104104
    105105function process_rows( $rows = [] ) {
    106 
    107     try {
    108 
    109         if ( empty( $rows ) ) {
    110             throw new Error('$rows is empty');
     106    $ids = [];
     107    foreach ( $rows as $row ) {
     108        $ids[] = $row['id'];
     109
     110        if ( apply_filters( 'wooms_skip_product_import', false, $row ) ) {
     111            continue;
    111112        }
    112113
    113         $ids = [];
    114         foreach ( $rows as $row ) {
    115             $ids[] = $row['id'];
    116 
    117             if ( apply_filters( 'wooms_skip_product_import', false, $row ) ) {
    118                 continue;
    119             }
    120 
    121             /**
    122              * в выдаче могут быть не только товары, но и вариации и мб что-то еще
    123              * птм нужна проверка что это точно продукт
    124              */
    125             if ( 'variant' == $row["meta"]["type"] ) {
    126                 continue;
    127             }
    128 
    129             $data = apply_filters( 'wooms_product_data', [], $row );
    130 
    131             product_update( $row, $data );
     114        /**
     115         * в выдаче могут быть не только товары, но и вариации и мб что-то еще
     116         * птм нужна проверка что это точно продукт
     117         */
     118        if ( 'variant' == $row["meta"]["type"] ) {
     119            continue;
    132120        }
    133121
    134 
    135         return true;
    136     } catch (Throwable $e) {
    137 
    138         $message = sprintf("wooms process fails: %s, ids: %s, code: %s", $e->getMessage(), json_encode($ids), $e->getCode());
    139         do_action( 'wooms_logger_error', __NAMESPACE__, $message );
    140         error_log($message);
    141 
    142         return false;
    143     }
    144 
    145 
     122        $data = apply_filters( 'wooms_product_data', [], $row );
     123
     124        product_update( $row, $data );
     125    }
    146126}
    147127
     
    223203    $product_id = 0;
    224204
    225     $product_id = get_product_id_by_uuid( $row['id'] );
     205    $product_id = Helper::get_product_id_by_uuid( $row['id'] );
    226206
    227207    if ( ! empty( $row['archived'] ) ) {
     
    248228
    249229    if ( empty( intval( $product_id ) ) ) {
    250         do_action(
    251             'wooms_logger_error',
    252             __NAMESPACE__,
    253             'Ошибка определения и добавления ИД продукта',
    254             $row
    255         );
     230        Helper::log_error('Ошибка определения и добавления ИД продукта', __NAMESPACE__, $row);
     231
    256232        return false;
    257233    }
     
    264240    $data_api = $row;
    265241
    266     $product->update_meta_data( 'wooms_id_' . $row['id'], 1 );
    267 
    268     /**
    269      * Хук позволяет работать с методами WC_Product
    270      * Сохраняет в БД все изменения за 1 раз
    271      * Снижает нагрузку на БД
    272      *
    273      * DEPRECATED
    274      */
    275     $product = apply_filters( 'wooms_product_save', $product, $data_api, $product_id );
    276242
    277243    //save data of source
     
    290256
    291257    $product->update_meta_data( 'wooms_updated_timestamp', date( "Y-m-d H:i:s" ) );
    292 
    293     $product->update_meta_data( 'wooms_id', $data_api['id'] );
    294 
    295258    $product->update_meta_data( 'wooms_updated_from_api', $data_api['updated'] );
    296259
     
    337300    }
    338301
    339     // issue https://github.com/wpcraft-ru/wooms/issues/302
     302    $product->update_meta_data( 'wooms_id', $data_api['id'] );
     303    $product->update_meta_data( 'wooms_id_' . $data_api['id'], 1 );
     304
     305    /**
     306     * reset state product
     307     *
     308     * @issue https://github.com/wpcraft-ru/wooms/issues/302
     309     */
    340310    $product->set_catalog_visibility( 'visible' );
    341 
    342     if ( apply_filters( 'wooms_reset_state_products', true ) ) {
    343         $product->set_stock_status( 'instock' );
    344         $product->set_manage_stock( false );
    345         $product->set_status( 'publish' );
    346     }
     311    $product->set_status( 'publish' );
    347312
    348313    $product = apply_filters( 'wooms_product_update', $product, $row, $data );
     
    350315    $product_id = $product->save();
    351316
    352     do_action(
    353         'wooms_logger',
    354         __NAMESPACE__,
    355         sprintf( 'Продукт: %s (%s) сохранен', $product->get_title(), $product_id )
    356     );
     317    Helper::log(sprintf( 'Продукт: %s (%s) сохранен', $product->get_title(), $product_id ), __NAMESPACE__);
    357318
    358319    return $product_id;
     
    475436        'timestamp' => $now,
    476437        'query_arg' => $query_arg_default,
    477         'end_timestamp' => 0,
    478438    ];
    479439
     
    484444}
    485445
    486 // function auto_start() {
    487 
    488 //   $end_timestamp = get_state( 'end_timestamp' );
    489 //   if( empty($end_timestamp)){
    490 //     return false;
    491 //   }
    492 
    493 //   if ( empty( get_option( 'woomss_pass' ) ) ) {
    494 //      return false;
    495 //  }
    496 
    497 //  if ( as_next_scheduled_action( HOOK_NAME ) ) {
    498 //      return;
    499 //  }
    500 
    501 
    502 
    503 //  return as_schedule_single_action( time(), HOOK_NAME, [], 'WooMS' );
    504 // }
    505 
    506446
    507447function render_ui() {
    508     printf( '<h2>%s</h2>', 'Каталог' );
     448    printf( '<h2>%s</h2>', 'Каталог и базовые продукты' );
    509449
    510450    $strings = [];
     
    516456    } else {
    517457        $strings[] = sprintf( 'Статус: %s', 'Завершено' );
    518         $strings[] = sprintf( 'Время последнего завершения: %s', wooms_get_timestamp_last_job_by_hook( HOOK_NAME ) );
     458        $strings[] = sprintf( 'Последняя успешная синхронизация: %s', Helper::get_timestamp_last_job_by_hook( HOOK_NAME ) ) ?? 'Нет данных';
    519459        printf(
    520460            '<a href="%s" class="button button-primary">Запустить синхронизацию продуктов вручную</a>',
     
    524464    }
    525465    $strings[] = sprintf( 'Очередь задач: <a href="%s">открыть</a>', admin_url( 'admin.php?page=wc-status&tab=action-scheduler&s=wooms_products_walker&orderby=schedule&order=desc' ) );
     466
    526467
    527468    foreach ( $strings as $string ) {
     
    569510    $data_meta = get_post_meta( $post->ID, 'wooms_meta', true );
    570511    $data_updated = get_post_meta( $post->ID, 'wooms_updated', true );
     512    $wooms_updated_timestamp = get_post_meta( $post->ID, 'wooms_updated_timestamp', true );
    571513    if ( $data_id ) {
    572514        printf( '<div>ID товара в МойСклад: <div><strong>%s</strong></div></div>', $data_id );
     
    583525    }
    584526
     527    if ( $data_updated ) {
     528        printf( '<div>Дата последнего обновления из API МойСклад: <strong>%s</strong></div>', $wooms_updated_timestamp );
     529    }
     530
    585531    do_action( 'wooms_display_product_metabox', $post->ID );
    586532}
  • wooms/tags/9.11/includes/ProductsCategories.php

    r2989239 r3061787  
    163163            }
    164164
    165             $term_id = wp_insert_term($row['name'], 'product_cat', $term_new)['term_id'] ?? null;
     165            // https://github.com/wpcraft-ru/wooms/issues/524#issuecomment-1860552168
     166            $term    = wp_insert_term( $row['name'], 'product_cat', $term_new );
     167            $term_id = ! is_wp_error( $term ) ? $term['term_id'] : null;
    166168
    167169            update_term_meta( $term_id, 'wooms_id', $row['id'] );
  • wooms/tags/9.11/includes/ProductsHiding.php

    r2842491 r3061787  
    22
    33namespace WooMS\ProductsHider;
     4
     5use WooMS\Helper;
    46
    57const HOOK_NAME = 'wooms_schedule_clear_old_products_walker';
     
    4345    $ids[] = $product_id;
    4446
    45     if ($product->get_type() == 'variable') {
    46       // $product->set_manage_stock('yes');
    47     }
     47    $product->set_status('draft');
    4848
    4949    $product->set_catalog_visibility('hidden');
    5050    $product->save();
    5151
    52     do_action(
    53       'wooms_logger',
    54       __NAMESPACE__,
    55       sprintf('Скрытие продукта: %s', $product_id)
    56     );
     52    Helper::log(sprintf('Скрытие продукта: %s', $product_id), __NAMESPACE__);
     53
    5754  }
    5855
     
    10299  }
    103100
     101
    104102  $args = array(
    105     'post_type' => ['product', 'product_variation'],
     103    'post_type' => ['product'],
     104    'post_status' => 'publish',
    106105    'numberposts' => 30,
    107106    'fields' => 'ids',
     107
    108108    'tax_query' => array(
    109109      array(
     
    162162  $strings[] = sprintf('Очередь задач: <a href="%s">открыть</a>', admin_url('admin.php?page=wc-status&tab=action-scheduler&s=wooms_schedule_clear_old_products_walker&orderby=schedule&order=desc'));
    163163
     164  $strings[] = sprintf( 'Журнал обработки: <a href="%s">открыть</a>', admin_url( 'admin.php?page=wc-status&tab=logs&source=WooMS-ProductsHider' ) );
     165
    164166  echo '<h2>Скрытие продуктов</h2>';
    165167  foreach ($strings as $string) {
  • wooms/tags/9.11/includes/Settings.php

    r2979725 r3061787  
    33namespace WooMS;
    44
    5 if (!defined('ABSPATH')) {
     5if ( ! defined( 'ABSPATH' ) ) {
    66    exit; // Exit if accessed directly
    77}
     
    1010const OPTIONS_PAGE = 'mss-settings';
    1111
    12 function get_config($key = null){
    13   $config = get_option(OPTION_KEY, []);
    14   if(empty($key)){
    15     return $config;
    16   }
    17   return $config[$key] ?? null;
    18 }
    19 
    20 function set_config($key, $value){
    21   $config = get_option(OPTION_KEY, []);
    22   $config[$key] = $value;
    23   return update_option(OPTION_KEY, $config, false);
     12function get_config( $key = null ) {
     13    $config = get_option( OPTION_KEY, [] );
     14    if ( empty( $key ) ) {
     15        return $config;
     16    }
     17    return $config[ $key ] ?? null;
     18}
     19
     20/**
     21 * Get name of form field by key
     22 */
     23function get_config_name( $key ) {
     24
     25    return OPTION_KEY . '[' . $key . ']';
     26}
     27
     28function set_config( $key, $value ) {
     29    $config = get_option( OPTION_KEY, [] );
     30    $config[ $key ] = $value;
     31    return update_option( OPTION_KEY, $config, false );
    2432}
    2533
     
    2836 * Settings
    2937 */
    30 class Settings
    31 {
     38class Settings {
    3239
    3340    /**
    3441     * The Init
    3542     */
    36     public static function init()
    37     {
     43    public static function init() {
    3844
    3945        add_action(
     
    5460                    'manage_options',
    5561                    'mss-settings',
    56                     array(__CLASS__, 'display_settings')
     62                    array ( __CLASS__, 'display_settings' )
    5763                );
    5864            },
     
    6066        );
    6167
    62         add_action('admin_init', array(__CLASS__, 'settings_general'), $priority = 5, $accepted_args = 1);
    63         add_action('admin_init', array(__CLASS__, 'settings_other'), $priority = 100, $accepted_args = 1);
    64 
    65         add_action('wooms_settings_after_header', [__CLASS__, 'render_nav_menu']);
    66     }
    67 
    68 
    69     public static function render_nav_menu(){
     68        add_action( 'admin_init', array( __CLASS__, 'settings_general' ), $priority = 5, $accepted_args = 1 );
     69        add_action( 'admin_init', array( __CLASS__, 'settings_other' ), $priority = 100, $accepted_args = 1 );
     70
     71        add_action( 'wooms_settings_after_header', [ __CLASS__, 'render_nav_menu' ] );
     72    }
     73
     74
     75    public static function render_nav_menu() {
    7076
    7177        $nav_items = [
    72             'getting-started' => sprintf('<a href="%s" target="_blank">%s</a>', 'https://github.com/wpcraft-ru/wooms/wiki/GettingStarted', 'С чего начать?'),
    73             'diagnostic' => sprintf('<a href="%s">%s</a>', admin_url('site-health.php'), 'Диагностика проблем'),
    74             'ms' => sprintf('<a href="%s" target="_blank">%s</a>', 'https://online.moysklad.ru/', 'Вход в МойСклад'),
     78            'dev' => sprintf( '<a href="%s" target="_blank">%s</a>', 'https://github.com/wpcraft-ru/wooms/', 'Разработка и решение проблем' ),
     79            'docs' => sprintf( '<a href="%s" target="_blank">%s</a>', 'https://github.com/wpcraft-ru/wooms/wiki', 'Документация' ),
     80
     81            'ms' => sprintf( '<a href="%s" target="_blank">%s</a>', 'https://online.moysklad.ru/', 'Вход в МойСклад' ),
    7582        ];
    7683
    77         $nav_items = apply_filters('wooms_settings_nav_items', $nav_items);
    78 
    79         echo implode(' | ', $nav_items);
    80 
    81     }
    82 
    83 
    84 
    85 
    86 
    87     public static function settings_general()
    88     {
    89 
    90         add_settings_section('woomss_section_login', 'Данные для доступа МойСклад', null, 'mss-settings');
    91 
    92     register_setting( 'mss-settings', 'wooms_config' );
    93 
    94         register_setting('mss-settings', 'woomss_login');
     84        $nav_items = apply_filters( 'wooms_settings_nav_items', $nav_items );
     85
     86        ?>
     87        <div>
     88            <a href="https://wpcraft.ru/wooms/" class="button button-primary" target="_blank">Помощь с настройками</a>
     89            <br/>
     90            <br/>
     91            <?= implode( ' | ', $nav_items ); ?>
     92        </div>
     93        <?php
     94
     95
     96
     97    }
     98
     99
     100
     101
     102
     103    public static function settings_general() {
     104
     105        add_settings_section( 'woomss_section_login', 'Данные для доступа МойСклад', null, 'mss-settings' );
     106
     107        register_setting( 'mss-settings', 'wooms_config' );
     108
     109        register_setting( 'mss-settings', 'woomss_login' );
    95110        add_settings_field(
    96111            $id = 'woomss_login',
    97112            $title = 'Логин (admin@...)',
    98             $callback = array(__CLASS__, 'display_form_login',),
     113            $callback = array( __CLASS__, 'display_form_login', ),
    99114            $page = 'mss-settings',
    100115            $section = 'woomss_section_login'
    101116        );
    102117
    103         register_setting('mss-settings', 'woomss_pass');
     118        register_setting( 'mss-settings', 'woomss_pass' );
    104119        add_settings_field(
    105120            $id = 'woomss_pass',
    106121            $title = 'Пароль',
    107             $callback = array(__CLASS__, 'display_form_pass'),
     122            $callback = array( __CLASS__, 'display_form_pass' ),
    108123            $page = 'mss-settings',
    109124            $section = 'woomss_section_login'
     
    114129     * display_form_pass
    115130     */
    116     public static function display_form_pass()
    117     {
    118         printf('<input type="password" name="woomss_pass" value="%s"/>', get_option('woomss_pass'));
     131    public static function display_form_pass() {
     132        printf( '<input type="password" name="woomss_pass" value="%s"/>', get_option( 'woomss_pass' ) );
    119133    }
    120134
     
    122136     * display_form_login
    123137     */
    124     public static function display_form_login()
    125     {
    126         printf('<input type="text" name="woomss_login" value="%s"/>', get_option('woomss_login'));
    127 
    128         printf('<p>%s</p>', 'Вводить нужно только логин и пароль здесь. На стороне МойСклад ничего настраивать не нужно.');
     138    public static function display_form_login() {
     139        printf( '<input type="text" name="woomss_login" value="%s"/>', get_option( 'woomss_login' ) );
     140
     141        printf( '<p>%s</p>', 'Вводить нужно только логин и пароль здесь. На стороне МойСклад ничего настраивать не нужно.' );
    129142    }
    130143
     
    132145     * Settings - Other
    133146     */
    134     public static function settings_other()
    135     {
    136         add_settings_section('woomss_section_other', 'Прочие настройки', null, 'mss-settings');
    137 
    138         register_setting('mss-settings', 'wooms_use_uuid');
     147    public static function settings_other() {
     148        add_settings_section( 'woomss_section_other', 'Прочие настройки', null, 'mss-settings' );
     149
     150        register_setting( 'mss-settings', 'wooms_use_uuid' );
    139151        add_settings_field(
    140152            $id = 'wooms_use_uuid',
    141153            $title = 'Использование UUID',
    142             $callback = array(__CLASS__, 'display_field_wooms_use_uuid'),
     154            $callback = array( __CLASS__, 'display_field_wooms_use_uuid' ),
    143155            $page = 'mss-settings',
    144156            $section = 'woomss_section_other'
    145157        );
    146158
    147         register_setting('mss-settings', 'wooms_replace_title');
     159        register_setting( 'mss-settings', 'wooms_replace_title' );
    148160        add_settings_field(
    149161            $id = 'wooms_replace_title',
    150162            $title = 'Замена заголовка при обновлении',
    151             $callback = array(__CLASS__, 'display_wooms_replace_title'),
     163            $callback = array( __CLASS__, 'display_wooms_replace_title' ),
    152164            $page = 'mss-settings',
    153165            $section = 'woomss_section_other'
    154166        );
    155167
    156         register_setting('mss-settings', 'wooms_replace_description');
     168        register_setting( 'mss-settings', 'wooms_replace_description' );
    157169        add_settings_field(
    158170            $id = 'wooms_replace_description',
    159171            $title = 'Замена описания при обновлении',
    160             $callback = array(__CLASS__, 'display_wooms_replace_desc'),
     172            $callback = array( __CLASS__, 'display_wooms_replace_desc' ),
    161173            $page = 'mss-settings',
    162174            $section = 'woomss_section_other'
     
    167179     * display_wooms_replace_desc
    168180     */
    169     public static function display_wooms_replace_desc()
    170     {
     181    public static function display_wooms_replace_desc() {
    171182
    172183        $option_name = 'wooms_replace_description';
    173         printf('<input type="checkbox" name="%s" value="1" %s />', $option_name, checked(1, get_option($option_name), false));
    174 ?>
     184        printf( '<input type="checkbox" name="%s" value="1" %s />', $option_name, checked( 1, get_option( $option_name ), false ) );
     185        ?>
    175186        <p>
    176187            <small>Если включить опцию, то плагин будет обновлять описание продукта из МойСклад всегда.</small>
    177188        </p>
    178     <?php
     189        <?php
    179190
    180191    }
     
    183194     * display_wooms_replace_title
    184195     */
    185     public static function display_wooms_replace_title()
    186     {
     196    public static function display_wooms_replace_title() {
    187197
    188198        $option_name = 'wooms_replace_title';
    189         printf('<input type="checkbox" name="%s" value="1" %s />', $option_name, checked(1, get_option($option_name), false));
    190     ?>
     199        printf( '<input type="checkbox" name="%s" value="1" %s />', $option_name, checked( 1, get_option( $option_name ), false ) );
     200        ?>
    191201        <p>
    192             <small>Если включить опцию, то плагин будет обновлять заголовки продукта из МойСклад. Иначе при наличии заголовока он не будет обновлен.</small>
     202            <small>Если включить опцию, то плагин будет обновлять заголовки продукта из МойСклад. Иначе при наличии заголовока
     203                он не будет обновлен.</small>
    193204        </p>
    194     <?php
     205        <?php
    195206
    196207    }
     
    199210     * display_field_wooms_use_uuid
    200211     */
    201     public static function display_field_wooms_use_uuid()
    202     {
     212    public static function display_field_wooms_use_uuid() {
    203213
    204214        $option_name = 'wooms_use_uuid';
    205         printf('<input type="checkbox" name="%s" value="1" %s />', $option_name, checked(1, get_option($option_name), false));
    206     ?>
     215        printf( '<input type="checkbox" name="%s" value="1" %s />', $option_name, checked( 1, get_option( $option_name ), false ) );
     216        ?>
    207217
    208218        <p><strong>Если товары не попадают из МойСклад на сайт - попробуйте включить эту опцию.</strong></p>
    209219        <p>
    210             <small>По умолчанию используется связь продуктов по артикулу. Это позволяет обеспечить синхронизацию без удаления всех продуктов с сайта при их наличии. Но без артикула
    211                 товары не будут синхронизироваться. Если товаров на сайте нет, либо их можно удалить без вреда, то можно включить синхронизацию по UUID. В этом случае артикулы
     220            <small>По умолчанию используется связь продуктов по артикулу. Это позволяет обеспечить синхронизацию без удаления
     221                всех продуктов с сайта при их наличии. Но без артикула
     222                товары не будут синхронизироваться. Если товаров на сайте нет, либо их можно удалить без вреда, то можно
     223                включить синхронизацию по UUID. В этом случае артикулы
    212224                будут не нужны. <br />При создании записи о продукте произойдет связка по UUID (meta_key = wooms_id)
    213225            </small>
    214226        </p>
    215     <?php
     227        <?php
    216228
    217229    }
     
    220232     * display_settings
    221233     */
    222     public static function display_settings()
    223     {
    224 
    225     ?>
     234    public static function display_settings() {
     235
     236        ?>
    226237        <form method="POST" action="options.php">
    227238
    228239            <h1>Настройки интеграции МойСклад</h1>
    229240
    230             <?php do_action('wooms_settings_after_header') ?>
     241            <?php do_action( 'wooms_settings_after_header' ) ?>
    231242
    232243            <?php
    233244
    234             settings_fields('mss-settings');
    235             do_settings_sections('mss-settings');
     245            settings_fields( 'mss-settings' );
     246            do_settings_sections( 'mss-settings' );
    236247            submit_button();
    237248            ?>
     
    239250
    240251
    241 <?php
    242 
    243         printf('<p><a href="%s">Управление синхронизацией</a></p>', admin_url('admin.php?page=moysklad'));
    244         printf('<p><a href="%s" target="_blank">Расширения и дополнения</a></p>', "https://github.com/topics/wooms");
    245         printf('<p><a href="%s" target="_blank">Предложения по улучшению и запросы на доработку</a></p>', "https://github.com/wpcraft-ru/wooms/issues");
    246         printf('<p><a href="%s" target="_blank">Рекомендуемые хостинги</a></p>', "https://wpcraft.ru/hosting-wordpress-woocommerce/");
    247         printf('<p><a href="%s" target="_blank">Контакты</a></p>', "https://wpcraft.ru/wooms/");
     252        <?php
     253
     254        printf( '<p><a href="%s">Управление синхронизацией</a></p>', admin_url( 'admin.php?page=moysklad' ) );
     255        printf( '<p><a href="%s" target="_blank">Помощь с настройкой</a></p>', "https://wpcraft.ru/wooms/?utm_source=wooms_plugin_settings_page" );
    248256    }
    249257}
  • wooms/tags/9.11/readme.txt

    r3010824 r3061787  
    11=== WooMS ===
    22Contributors: casepress
    3 Donate link: https://wpcraft.ru/product/wooms-extra/
     3Donate link: https://wpcraft.ru/pay/
    44Tags: moysklad, woocommerce, sync, integration
    55Requires at least: 6.0
     
    2424*   Гибкие настройки
    2525
    26 [Руководство по быстрому началу работы](https://github.com/wpcraft-ru/wooms/wiki/GettingStarted)
     26[Руководство по быстрому началу работы](https://wpcraft.ru/wooms/)
    2727
    2828Исходники для желающих принять участие в разработке: [https://github.com/wpcraft-ru/wooms/](https://github.com/wpcraft-ru/wooms/)
     
    7777== Changelog ==
    7878
     79= 9.11 =
     80- Тест совместимости WooCommerce 8.7.0
     81- Улучшена синхронизация остатков
     82- Не обновляются остатки по товарам https://github.com/wpcraft-ru/wooms/issues/544 https://github.com/wpcraft-ru/wooms/issues/524
     83- Совместимость: 'Высокопроизводительное хранилище заказов' https://github.com/wpcraft-ru/wooms/issues/539
     84
    7985= 9.10 =
    8086- Исправлена ошибка с версией
    81 - Обновдены авто тесты
     87- Обновлены авто тесты
    8288
    8389= 9.9 =
  • wooms/tags/9.11/wooms.php

    r3010824 r3061787  
    2020 * WC tested up to: 8.4.0
    2121 *
    22  * Version: 9.10
     22 * Version: 9.11
    2323 */
    2424
     
    2626
    2727// Exit if accessed directly
    28 defined('ABSPATH') || exit;
     28defined( 'ABSPATH' ) || exit;
    2929
    3030/**
    3131 * Add hook for activate plugin
    3232 */
    33 register_activation_hook(__FILE__, function () {
    34   do_action('wooms_activate');
    35 });
    36 
    37 register_deactivation_hook(__FILE__, function () {
    38   do_action('wooms_deactivate');
    39 });
     33register_activation_hook( __FILE__, function () {
     34    do_action( 'wooms_activate' );
     35} );
     36
     37register_deactivation_hook( __FILE__, function () {
     38    do_action( 'wooms_deactivate' );
     39} );
    4040
    4141
    4242require_once __DIR__ . '/includes/functions.php';
    4343
    44 add_action('plugins_loaded', function () {
    45   if (!wooms_can_start()) {
    46     return;
    47   }
    48 
    49   $files = glob(__DIR__ . '/includes/*.php');
    50   foreach ($files as $file) {
    51     require_once $file;
    52   }
    53   add_action('admin_enqueue_scripts', __NAMESPACE__ . '\\' . 'admin_styles');
    54   add_action('save_post', 'wooms_id_check_if_unique', 10, 3);
    55 });
    56 
    57 add_filter('plugin_row_meta', __NAMESPACE__ . '\\add_wooms_plugin_row_meta', 10, 2);
    58 
    59 
    60 add_filter( "plugin_action_links_" . plugin_basename(__FILE__), function($links){
     44add_action( 'plugins_loaded', function () {
     45    if ( ! wooms_can_start() ) {
     46        return;
     47    }
     48
     49    $files = glob( __DIR__ . '/includes/*.php' );
     50    foreach ( $files as $file ) {
     51        require_once $file;
     52    }
     53    add_action( 'admin_enqueue_scripts', __NAMESPACE__ . '\\' . 'admin_styles' );
     54    add_action( 'save_post', 'wooms_id_check_if_unique', 10, 3 );
     55} );
     56
     57add_filter( 'plugin_row_meta', __NAMESPACE__ . '\\add_wooms_plugin_row_meta', 10, 2 );
     58
     59
     60add_filter( "plugin_action_links_" . plugin_basename( __FILE__ ), function ($links) {
    6161    $mng_link = '<a href="admin.php?page=moysklad">Управление</a>';
    6262    $settings_link = '<a href="admin.php?page=mss-settings">Настройки</a>';
    63     array_unshift($links, $mng_link);
    64     array_unshift($links, $settings_link);
    65     return $links;
    66 });
     63    array_unshift( $links, $mng_link );
     64    array_unshift( $links, $settings_link );
     65    return $links;
     66} );
    6767
    6868
     
    7070 * сообщяем про то что Extra плагин более не актуален
    7171 */
    72 add_action('after_plugin_row_wooms-extra/wooms-extra.php', function($data, $response){
    73 
    74     $wp_list_table = _get_list_table('WP_Plugins_List_Table');
     72add_action( 'after_plugin_row_wooms-extra/wooms-extra.php', function ($data, $response) {
     73
     74    $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
    7575
    7676    printf(
    77       '<tr class="plugin-update-tr">
     77        '<tr class="plugin-update-tr">
    7878          <td colspan="%s" class="plugin-update update-message notice inline notice-warning notice-alt">
    7979            <div class="update-message">
     
    8282          </td>
    8383        </tr>',
    84       $wp_list_table->get_column_count()
     84        $wp_list_table->get_column_count()
    8585    );
    86 }, 10, 2);
    87 add_filter('wooms_xt_load', '__return_false');
     86}, 10, 2 );
     87add_filter( 'wooms_xt_load', '__return_false' );
    8888
    8989
     
    9191 * Add GettingStarted link in row meta at pligins list
    9292 */
    93 function add_wooms_plugin_row_meta($links, $file)
    94 {
    95   if (strpos($file, 'wooms.php') !== false) {
    96     $new_links = array(
    97       '<a href="https://github.com/wpcraft-ru/wooms/wiki/GettingStarted" target="_blank"><strong>Руководство по началу работы</strong></a>',
    98       '<a href="https://wpcraft.ru/wooms/?utm_source=plugin" target="_blank"><strong>Консультации</strong></a>',
    99       '<a href="https://github.com/orgs/wpcraft-ru/projects/2" target="_blank"><strong>Задачи</strong></a>',
    100     );
    101 
    102     $links = array_merge($links, $new_links);
    103   }
    104 
    105   return $links;
     93function add_wooms_plugin_row_meta( $links, $file ) {
     94    if ( strpos( $file, 'wooms.php' ) !== false ) {
     95        $new_links = array(
     96            '<a href="https://github.com/wpcraft-ru/wooms/wiki/GettingStarted" target="_blank"><strong>Руководство по началу работы</strong></a>',
     97            '<a href="https://wpcraft.ru/wooms/?utm_source=plugin" target="_blank"><strong>Консультации</strong></a>',
     98            '<a href="https://github.com/orgs/wpcraft-ru/projects/2" target="_blank"><strong>Задачи</strong></a>',
     99        );
     100
     101        $links = array_merge( $links, $new_links );
     102    }
     103
     104    return $links;
    106105}
    107106
     
    112111 * @return void
    113112 */
    114 function admin_styles()
    115 {
    116   $admin_style = plugin_dir_url(__FILE__) . 'css/admin.css';
    117 
    118   wp_enqueue_style('wooms_styles', $admin_style, array());
    119 }
    120 
    121 
    122 
    123 function get_api_url($path){
     113function admin_styles() {
     114    $admin_style = plugin_dir_url( __FILE__ ) . 'css/admin.css';
     115
     116    wp_enqueue_style( 'wooms_styles', $admin_style, array() );
     117}
     118
     119
     120
     121function get_api_url( $path ) {
    124122    return $url = 'https://api.moysklad.ru/api/remap/1.2/' . $path;
    125123}
    126124
    127 function request($path = '', $data = array(), $type = 'GET'){
    128   // https://api.moysklad.ru/api/remap/1.2/
    129 
    130 
    131   if (empty($path)) {
    132     return false;
    133   }
    134 
    135   if(str_contains($path, 'https://api.moysklad.ru/api/remap/1.2/')){
    136     $url = $path;
    137   } else {
    138     $url = 'https://api.moysklad.ru/api/remap/1.2/' . $path;
    139   }
    140 
    141 
    142 
    143   //@link https://github.com/wpcraft-ru/wooms/issues/177
    144   $url = str_replace('product_id', 'product.id', $url);
    145   $url = str_replace('store_id', 'store.id', $url);
    146   $url = str_replace('consignment_id', 'consignment.id', $url);
    147   $url = str_replace('variant_id', 'variant.id', $url);
    148   $url = str_replace('productFolder_id', 'productFolder.id', $url);
    149 
    150   if (!empty($data) && 'GET' == $type) {
    151     $type = 'POST';
    152   }
    153   if ('GET' == $type) {
    154     $data = null;
    155   } else {
    156     $data = json_encode($data);
    157   }
    158 
    159   $args = array(
    160     'method'      => $type,
    161     'timeout'     => 45,
    162     'redirection' => 5,
    163     'headers'     => array(
    164       "Content-Type"  => 'application/json;charset=utf-8',
    165       "Accept-Encoding" => "gzip",
    166       'Authorization' => 'Basic ' .
    167         base64_encode(get_option('woomss_login') . ':' . get_option('woomss_pass')),
    168     ),
    169     'body'        => $data,
    170   );
    171 
    172   $request = wp_remote_request($url, $args);
    173   if (is_wp_error($request)) {
    174     do_action(
    175       'wooms_logger_error',
    176       $type = 'WooMS-Request',
    177       $title = 'Ошибка REST API WP Error',
    178       $desc = $request->get_error_message()
    179     );
    180 
    181     return false;
    182   }
    183 
    184   if (empty($request['body'])) {
    185     do_action(
    186       'wooms_logger_error',
    187       $type = 'WooMS-Request',
    188       $title = 'REST API вернулся без требуемых данных'
    189     );
    190 
    191     return false;
    192   }
    193 
    194   $response = json_decode($request['body'], true);
    195 
    196   if (!empty($response["errors"]) and is_array($response["errors"])) {
    197     foreach ($response["errors"] as $error) {
    198       do_action(
    199         'wooms_logger_error',
    200         $type = 'WooMS-Request',
    201         $title = $url,
    202         $response
    203       );
    204     }
    205   }
    206 
    207   return $response;
    208 }
    209 
    210 
    211 function get_session_id(){
    212   return \WooMS\Products\get_session_id();
    213 }
     125function request( $path = '', $data = array(), $type = 'GET' ) {
     126    // https://api.moysklad.ru/api/remap/1.2/
     127
     128
     129    if ( empty ( $path ) ) {
     130        return false;
     131    }
     132
     133    if ( str_contains( $path, 'https://api.moysklad.ru/api/remap/1.2/' ) ) {
     134        $url = $path;
     135    } else {
     136        $url = 'https://api.moysklad.ru/api/remap/1.2/' . $path;
     137    }
     138
     139
     140
     141    //@link https://github.com/wpcraft-ru/wooms/issues/177
     142    $url = str_replace( 'product_id', 'product.id', $url );
     143    $url = str_replace( 'store_id', 'store.id', $url );
     144    $url = str_replace( 'consignment_id', 'consignment.id', $url );
     145    $url = str_replace( 'variant_id', 'variant.id', $url );
     146    $url = str_replace( 'productFolder_id', 'productFolder.id', $url );
     147
     148    if ( ! empty ( $data ) && 'GET' == $type ) {
     149        $type = 'POST';
     150    }
     151    if ( 'GET' == $type ) {
     152        $data = null;
     153    } else {
     154        $data = json_encode( $data );
     155    }
     156
     157    $args = array(
     158        'method' => $type,
     159        'timeout' => 45,
     160        'redirection' => 5,
     161        'headers' => array(
     162                "Content-Type" => 'application/json;charset=utf-8',
     163                "Accept-Encoding" => "gzip",
     164                'Authorization' => 'Basic ' .
     165                    base64_encode( get_option( 'woomss_login' ) . ':' . get_option( 'woomss_pass' ) ),
     166            ),
     167        'body' => $data,
     168    );
     169
     170    $request = wp_remote_request( $url, $args );
     171    if ( is_wp_error( $request ) ) {
     172        do_action(
     173            'wooms_logger_error',
     174            $type = 'WooMS-Request',
     175            $title = 'Ошибка REST API WP Error',
     176            $desc = $request->get_error_message()
     177        );
     178
     179        return false;
     180    }
     181
     182    if ( empty ( $request['body'] ) ) {
     183        do_action(
     184            'wooms_logger_error',
     185            $type = 'WooMS-Request',
     186            $title = 'REST API вернулся без требуемых данных'
     187        );
     188
     189        return false;
     190    }
     191
     192    $response = json_decode( $request['body'], true );
     193
     194    if ( ! empty ( $response["errors"] ) and is_array( $response["errors"] ) ) {
     195        foreach ( $response["errors"] as $error ) {
     196            do_action(
     197                'wooms_logger_error',
     198                $type = 'WooMS-Request',
     199                $title = $url,
     200                $response
     201            );
     202        }
     203    }
     204
     205    return $response;
     206}
     207
     208
     209function get_session_id() {
     210    return \WooMS\Products\get_session_id();
     211}
     212
     213/**
     214 * doc https://github.com/woocommerce/woocommerce/wiki/High-Performance-Order-Storage-Upgrade-Recipe-Book
     215 * doc https://woo.com/document/high-performance-order-storage/
     216 * issue https://github.com/wpcraft-ru/wooms/issues/539
     217 */
     218add_action( 'before_woocommerce_init', function () {
     219    if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class) ) {
     220        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );
     221    }
     222} );
  • wooms/trunk/includes/MenuTools.php

    r2854597 r3061787  
    22
    33namespace WooMS;
     4
    45/**
    56 *  Tool for MoySklad
     
    78class MenuTools {
    89
    9   /**
    10   * URL action
    11   */
    12   public static $url;
     10    /**
     11    * URL action
     12    */
     13    public static $url;
    1314
    14   /**
    15   * The Init
    16   */
    17   public static function init(){
     15    /**
     16    * The Init
     17    */
     18    public static function init() {
    1819
    19     self::$url = $_SERVER['REQUEST_URI'];
     20        self::$url = $_SERVER['REQUEST_URI'];
    2021
    21     add_action(
    22       'admin_menu',
    23       function () {
     22        add_action(
     23            'admin_menu',
     24            function () {
    2425
    25         if(current_user_can('manage_woocommerce')){
    26           add_menu_page(
    27             $page_title = 'МойСклад',
    28             $menu_title = 'МойСклад',
    29             $capability = 'manage_woocommerce',
    30             $menu_slug = 'moysklad',
    31             $function = array( __CLASS__, 'display_ui' ),
    32             $icon = 'dashicons-forms',
    33             '57.5'
    34           );
    35         }
     26                if ( current_user_can( 'manage_woocommerce' ) ) {
     27                    add_menu_page(
     28                        $page_title = 'МойСклад',
     29                        $menu_title = 'МойСклад',
     30                        $capability = 'manage_woocommerce',
     31                        $menu_slug = 'moysklad',
     32                        $function = array ( __CLASS__, 'display_ui' ),
     33                        $icon = 'dashicons-forms',
     34                        '57.5'
     35                    );
     36                }
    3637
    37       }
    38     );
     38            }
     39        );
    3940
    4041
    41   }
     42    }
    4243
    43   /**
    44    * Display UI
    45    */
    46   public static function display_ui()
    47   {
    48     printf('<h1>%s</h1>', 'Управление МойСклад');
    49     $items = [
    50       '<a style="color:green;" href="https://github.com/wpcraft-ru/wooms/wiki/GettingStarted" target="_blank">
    51           <strong>Начало работы</strong>
    52       </a>',
    53       sprintf('<a href="%s">Настройки</a>', admin_url("admin.php?page=mss-settings") ),
    54       '<a href="https://online.moysklad.ru/app/" target="_blank">Вход в МойСклад</a>',
    55       sprintf('<a href="%s">Диагностика проблем</a>', admin_url("site-health.php") ),
    56       '<a href="https://wpcraft.ru/hosting-wordpress-woocommerce/" target="_blank">Рекомендуемые хостинги</a>',
    57       '<a href="https://wpcraft.ru/wooms/" target="_blank">Контакты</a>',
    58     ];
    59 
    60     printf( '<p>%s</p>', implode('<span> | </span>', $items) );
    61 
    62     if(empty(get_option('woomss_pass'))){
    63       printf('<p>Укажите логин и пароль на <a href="%s">странице настроек</a></p>', admin_url('admin.php?page=mss-settings'));
    64     } else {
    65       if( empty($_GET['a']) ){
    66 
    67         do_action('wooms_tools_sections');
    68 
    69         // deprecated
    70         do_action('woomss_tool_actions_btns');
    71 
    72       } else {
    73 
    74         printf('<a href="%s">Вернуться...</a>', remove_query_arg( 'a', self::$url));
    75         do_action('woomss_tool_actions');
    76         do_action('woomss_tool_actions_' . $_GET['a']);
    77 
    78       }
    79     }
     44    /**
     45     * Display UI
     46     */
     47    public static function display_ui() {
     48        printf( '<h1>%s</h1>', 'Управление МойСклад' );
     49        $items = [
     50            sprintf( '<a href="%s">Настройки</a>', admin_url( "admin.php?page=mss-settings" ) ),
     51            '<a href="https://online.moysklad.ru/app/" target="_blank">Вход в МойСклад</a>',
     52            sprintf( '<a href="%s">Здоровье сайта</a>', admin_url( "site-health.php" ) ),
     53            '<a href="https://wpcraft.ru/blog/hosting-wordpress-woocommerce/" target="_blank">Рекомендуемые хостинги</a>',
     54            '<a href="https://wpcraft.ru/wooms/" target="_blank">Контакты</a>',
     55        ];
     56        ?>
     57        <div>
     58            <a href="https://wpcraft.ru/wooms/" class="button button-primary" target="_blank">Решаем проблемы</a>
     59            <br />
     60            <?= sprintf( '<p>%s</p>', implode( '<span> | </span>', $items ) ); ?>
     61        </div>
     62        <?php
    8063
    8164
    82   }
     65        if ( empty( get_option( 'woomss_pass' ) ) ) {
     66            printf( '<p>Укажите логин и пароль на <a href="%s">странице настроек</a></p>', admin_url( 'admin.php?page=mss-settings' ) );
     67        } else {
     68            if ( empty( $_GET['a'] ) ) {
     69
     70                do_action( 'wooms_tools_sections' );
     71
     72                // deprecated
     73                do_action( 'woomss_tool_actions_btns' );
     74
     75            } else {
     76
     77                printf( '<a href="%s">Вернуться...</a>', remove_query_arg( 'a', self::$url ) );
     78                do_action( 'woomss_tool_actions' );
     79                do_action( 'woomss_tool_actions_' . $_GET['a'] );
     80
     81            }
     82        }
     83
     84
     85    }
    8386
    8487
  • wooms/trunk/includes/ProductStocks.php

    r3010225 r3061787  
    33namespace WooMS;
    44
     5use WC_Product;
    56use function WooMS\request;
    67
     8use function WooMS\get_config as get_config;
     9use function WooMS\get_config_name as get_config_name;
    710
    811defined( 'ABSPATH' ) || exit; // Exit if accessed directly
     
    2730    public static function init() {
    2831
     32        // add_action( 'init', function () {
     33        //  if ( ! isset ( $_GET['test_ProductStocks'] ) ) {
     34        //      return;
     35        //  }
     36
     37        //  // do_action('wooms_assortment_sync');
     38        //  // var_dump(1); exit;
     39
     40        //  $meta = get_post_meta( 68934 );
     41        //  echo '<pre>';
     42        //  var_dump( $meta );
     43        //  exit;
     44        // } );
     45
     46        add_filter( 'wooms_stock_product_save', [ __CLASS__, 'update_manage_stock' ], 10, 2 );
     47
    2948        add_action( 'wooms_assortment_sync', [ __CLASS__, 'batch_handler' ] );
    3049
     
    3756        add_action( 'wooms_variations_batch_end', [ __CLASS__, 'restart_after_batch' ] );
    3857        add_action( 'wooms_products_batch_end', [ __CLASS__, 'restart_after_batch' ] );
    39         add_action( 'wooms_main_walker_started', [ __CLASS__, 'restart' ] );
    40 
    41         add_action( 'admin_init', [__CLASS__, 'add_settings'], 30 );
     58
     59        add_action( 'admin_init', [ __CLASS__, 'add_settings' ], 30 );
    4260        add_action( 'wooms_tools_sections', array( __CLASS__, 'display_state' ), 17 );
    4361
    44         add_filter( 'wooms_stock_type', array( __CLASS__, 'select_type_stock' ) );
    45 
    46         //need for disable reset state for base plugin
    47         add_filter( 'wooms_reset_state_products', function ($reset) {
    48             return false;
    49         } );
    50     }
    51 
    52 
    53     public static function batch_handler($state = []) {
    54         if(empty($state)){
     62        // add_filter( 'wooms_stock_type', array( __CLASS__, 'select_type_stock' ) );
     63
     64    }
     65
     66
     67    public static function batch_handler( $state = [] ) {
     68        if ( empty( $state ) ) {
    5569            $state = [
    5670                'count' => 0
     
    7488
    7589        $products = get_posts( $args );
    76         if ( empty($products) ) {
    77             self::set_state( 'finish_timestamp', time() );
     90
     91        if ( empty( $products ) ) {
    7892            return false;
    7993        }
    8094
    81         $filters = [];
     95        $filters_by_id = [];
    8296        foreach ( $products as $product ) {
    83             $filters[] = 'id=' . get_post_meta( $product->ID, 'wooms_id', true );
    84         }
    85 
    86         // todo - переписать это как то лучше
     97            $filters_by_id[] = 'id=' . get_post_meta( $product->ID, 'wooms_id', true );
     98            delete_post_meta( $product->ID, self::$walker_hook_name );
     99        }
     100
     101        $filters = [
     102            implode( ';', $filters_by_id )
     103        ];
     104
    87105        $url = 'https://api.moysklad.ru/api/remap/1.2/entity/assortment';
    88106
     
    101119        $data = request( $url );
    102120
     121        // var_dump($data); exit;
     122
    103123        if ( empty( $data['rows'] ) ) {
    104124            return false;
    105125        }
    106126
    107 
    108         $ids = self::process_rows($data['rows']);
    109         if($ids){
     127        $ids = self::process_rows( $data['rows'] );
     128        if ( $ids ) {
    110129            $state['last_ids'] = $ids;
    111130        }
    112131
    113         $state['count'] += count($data['rows']);
    114 
    115         return as_schedule_single_action( time(), self::$walker_hook_name, [$state], 'WooMS' );
    116 
    117     }
    118 
    119     public static function process_rows($rows){
     132        $state['count'] += count( $data['rows'] );
     133
     134        return as_schedule_single_action( time(), self::$walker_hook_name, [ $state ], 'WooMS' );
     135
     136    }
     137
     138    public static function process_rows( $rows ) {
    120139
    121140        $ids = [];
    122141        foreach ( $rows as $row ) {
    123142
    124             if ( ! $product_id = self::get_product_id_by_uuid( $row['id'] ) ) {
     143            if ( ! $product_id = Helper::get_product_id_by_uuid( $row['id'] ) ) {
     144                Helper::log_error( 'Не нашли продукт по uuid', __CLASS__, $row );
    125145                continue;
    126146            }
    127147
    128148            if ( ! $product = wc_get_product( $product_id ) ) {
     149                Helper::log_error( 'Не нашли продукт по $product_id', __CLASS__, $row );
    129150                continue;
    130151            }
     
    133154
    134155            $product->update_meta_data( 'wooms_assortment_data', self::get_stock_data_log( $row, $product_id ) );
    135             $product->delete_meta_data( self::$walker_hook_name );
     156
    136157
    137158            /**
     
    142163            $product = apply_filters( 'wooms_stock_product_save', $product, $row );
    143164
     165
    144166            $ids[] = $product->save();
    145167        }
    146168
    147169        return $ids;
     170
     171    }
     172
     173
     174    public static function update_stock( WC_Product $product, $data_api ): WC_Product {
     175
     176        //если продукт вариативный, то его наличие определяется его вариациями и это отдельный поток хуков
     177        if ( $product->get_type() === 'variable' ) {
     178            return $product;
     179        }
     180
     181        /**
     182         * Поле по которому берем остаток?
     183         * quantity = это доступные остатки за вычетом резервов
     184         * stock = это все остатки без уета резерва
     185         */
     186        if(get_config('stock_and_reserve')){
     187            $stock = (int) $data_api['quantity'] ?? 0;
     188        } else {
     189            $stock = (int) $data_api['stock'] ?? 0;
     190        }
     191
     192        if ( $stock > 0 ) {
     193            $product->set_stock_quantity( $stock );
     194            $product->set_stock_status( 'instock' );
     195        } else {
     196            $product->set_stock_quantity( 0 );
     197            $product->set_stock_status( 'outofstock' );
     198        }
     199
     200        $log_data = [
     201            'stock' => $data_api['stock'],
     202            'quantity' => $data_api['quantity'],
     203            'type' => $product->get_type(),
     204        ];
     205
     206        if ( $product->get_type() === 'variation' ) {
     207            $log_data['product_parent'] = $product->get_parent_id();
     208        }
     209
     210        Helper::log( sprintf(
     211            'Остатки для продукта "%s" (ИД %s) = %s', $product->get_name(), $product->get_id(), $product->get_stock_quantity() ),
     212            __CLASS__,
     213            $log_data
     214        );
     215
     216        return $product;
     217    }
     218
     219
     220    /**
     221     * Если у сайта включена опция управление остатками - установить остатки для товара
     222     *
     223     * @todo вероятно опция типа wooms_warehouse_count - более не нужна
     224     */
     225    public static function update_manage_stock( WC_Product $product, $data_api ): WC_Product {
     226
     227        if ( ! get_option( 'woocommerce_manage_stock' ) ) {
     228            return $product;
     229        }
     230
     231        if ( ! $product->get_manage_stock() ) {
     232            $product->set_manage_stock( true );
     233            Helper::log( sprintf(
     234                'Включили управление запасами для продукта: %s (ИД %s)', $product->get_name(), $product->get_id() ),
     235                __CLASS__
     236            );
     237        }
     238
     239        //для вариативных товаров доступность определяется наличием вариаций
     240        if ( $product->get_type() === 'variation' ) {
     241
     242            $parent_id = $product->get_parent_id();
     243            $parent_product = wc_get_product( $parent_id );
     244            if ( empty( $parent_product ) ) {
     245                Helper::log_error( "Не нашли родительский продукт: {$parent_id}, вариация: {$product->get_id()}",
     246                    __CLASS__
     247                );
     248                return $product;
     249            }
     250            if ( $parent_product->get_manage_stock() ) {
     251
     252                Helper::log( sprintf(
     253                    'У основного продукта отключили управление остатками: %s (ИД %s)', $parent_product->get_name(), $parent_id ),
     254                    __CLASS__
     255                );
     256                $parent_product->set_manage_stock( false );
     257
     258                $parent_product->save();
     259            }
     260
     261        }
     262
     263        /**
     264         * это похоже надо выпилить
     265         *
     266         * потому что это не относится к синку МС и должно управляться как то иначе
     267         *
     268         * если это тут оставлять, то эта отметка должна быть на стороне МС
     269         */
     270        // if ( get_option( 'wooms_stock_empty_backorder' ) ) {
     271        // $product->set_backorders( 'notify' );
     272        // } else {
     273        // $product->set_backorders( 'no' );
     274        // }
     275
     276
     277        return $product;
    148278
    149279    }
     
    168298    }
    169299
    170     public static function update_stock( $product, $data_api ) {
    171         $product = wc_get_product( $product );
    172 
    173         $product_id = $product->get_id();
    174 
    175         /**
    176          * Поле по которому берем остаток?
    177          * quantity = это доступные остатки за вычетом резервов
    178          * stock = это все остатки без уета резерва
    179          */
    180         $stock_type = apply_filters( 'wooms_stock_type', 'quantity' );
    181 
    182         $stock = 0;
    183 
    184         if ( empty( $data_api[ $stock_type ] ) ) {
    185             $stock = 0;
    186         } else {
    187             $stock = (int) $data_api[ $stock_type ];
    188         }
    189 
    190         if ( get_option( 'wooms_stock_empty_backorder' ) ) {
    191             $product->set_backorders( 'notify' );
    192         } else {
    193             $product->set_backorders( 'no' );
    194         }
    195 
    196         if ( empty( get_option( 'wooms_warehouse_count' ) ) ) {
    197             $product->set_manage_stock( false );
    198         } else {
    199             if ( $product->is_type( 'variable' ) ) {
    200                 //для вариативных товаров доступность определяется наличием вариаций
    201                 $product->set_manage_stock( false );
    202             } else {
    203                 $product->set_manage_stock( true );
    204             }
    205         }
    206 
    207         if ( $stock <= 0 ) {
    208             if ( ! $product->is_type( 'variable' ) ) {
    209                 $product->set_stock_quantity( 0 );
    210                 $product->set_stock_status( 'outofstock' );
    211             }
    212         } else {
    213             $product->set_stock_quantity( $stock );
    214             $product->set_stock_status( 'instock' );
    215         }
    216 
    217         do_action(
    218             'wooms_logger',
    219             __CLASS__,
    220             sprintf( 'Остатки для продукта "%s" = %s (ИД %s)', $product->get_name(), $stock, $product_id ),
    221             sprintf( 'stock %s, quantity %s', $data_api['stock'], $data_api['quantity'] )
    222         );
    223 
    224         return $product;
    225     }
    226 
    227     /**
    228      * restart walker after added tast to queue
    229      */
    230     public static function restart() {
    231         self::set_state( 'finish_timestamp', 0 );
    232         self::set_state( 'count_all', 0 );
    233         self::set_state( 'count_save', 0 );
    234     }
    235 
    236300
    237301    public static function restart_after_batch() {
    238         if(as_has_scheduled_action(self::$walker_hook_name)){
     302        if ( ! self::is_enable() ) {
    239303            return;
    240304        }
    241305
     306        if ( as_has_scheduled_action( self::$walker_hook_name ) ) {
     307            return;
     308        }
     309
    242310        as_schedule_single_action( time(), self::$walker_hook_name, [], 'WooMS' );
    243     }
    244 
    245 
    246 
    247 
    248     /**
    249      * check is wait
    250      */
    251     public static function is_wait() {
    252         if ( self::get_state( 'finish_timestamp' ) ) {
    253             return true;
    254         }
    255 
    256         return false;
    257311    }
    258312
     
    279333
    280334
    281 
    282 
    283     /**
    284      * set state data
    285      */
    286335    public static function set_state( $key, $value ) {
    287336
     
    373422    }
    374423
    375     /**
    376      * Select type stock
    377      */
    378     public static function select_type_stock( $type_stock ) {
    379         if ( get_option( 'wooms_stocks_without_reserve' ) ) {
    380             $type_stock = 'stock';
    381         }
    382 
    383         return $type_stock;
    384     }
    385424
    386425    /**
    387426     * Update stock for variation
    388427     */
    389     public static function update_variation( $variation, $data_api ) {
     428    public static function update_variation( \WC_Product_Variation $variation, $data_api ) {
    390429        if ( self::is_enable() ) {
    391430            $variation->update_meta_data( self::$walker_hook_name, 1 );
     
    393432            $variation->set_catalog_visibility( 'visible' );
    394433            $variation->set_stock_status( 'instock' );
    395             $variation->set_manage_stock( 'no' );
     434            $variation->set_manage_stock( false );
    396435            $variation->set_status( 'publish' );
    397436        }
     
    410449            $product->set_catalog_visibility( 'visible' );
    411450            $product->set_stock_status( 'instock' );
    412             $product->set_manage_stock( 'no' );
     451            $product->set_manage_stock( false );
    413452            $product->set_status( 'publish' );
    414453        }
     
    438477        );
    439478
    440         register_setting( 'mss-settings', 'wooms_stocks_without_reserve' );
    441479        add_settings_field(
    442             $id = 'wooms_stocks_without_reserve',
    443             $title = 'Остатки без резерва',
    444             $callback = array( __CLASS__, 'display_field_wooms_stocks_without_reserve' ),
     480            $id = 'stock_and_reserve',
     481            $title = 'Учитывать остатки с резервом',
     482            $callback = function ($args) {
     483                printf( '<input type="checkbox" name="%s" value="1" %s />', $args['name'], $args['value'] );
     484
     485            },
    445486            $page = 'mss-settings',
    446             $section = 'woomss_section_warehouses'
    447         );
    448 
    449         register_setting( 'mss-settings', 'wooms_warehouse_count' );
    450         add_settings_field(
    451             $id = 'wooms_warehouse_count',
    452             $title = 'Управление запасами на уровне товаров',
    453             $callback = array( __CLASS__, 'display_wooms_warehouse_count' ),
    454             $page = 'mss-settings',
    455             $section = 'woomss_section_warehouses'
    456         );
    457 
    458         register_setting( 'mss-settings', 'wooms_stock_empty_backorder' );
    459         add_settings_field(
    460             $id = 'wooms_stock_empty_backorder',
    461             $title = 'Разрешать предзаказ при 0 остатке',
    462             $callback = array( __CLASS__, 'display_wooms_stock_empty_backorder' ),
    463             $page = 'mss-settings',
    464             $section = 'woomss_section_warehouses'
    465         );
     487            $section,
     488            $args = [
     489                'name' => get_config_name( 'stock_and_reserve' ),
     490                'value' => checked( 1, get_config( 'stock_and_reserve' ) ),
     491            ]
     492        );
     493
     494        // register_setting( 'mss-settings', 'wooms_warehouse_count' );
     495        // add_settings_field(
     496        //  $id = 'wooms_warehouse_count',
     497        //  $title = 'Управление запасами на уровне товаров',
     498        //  $callback = array( __CLASS__, 'display_wooms_warehouse_count' ),
     499        //  $page = 'mss-settings',
     500        //  $section = 'woomss_section_warehouses'
     501        // );
     502
     503        // register_setting( 'mss-settings', 'wooms_stock_empty_backorder' );
     504        // add_settings_field(
     505        //  $id = 'wooms_stock_empty_backorder',
     506        //  $title = 'Разрешать предзаказ при 0 остатке',
     507        //  $callback = array( __CLASS__, 'display_wooms_stock_empty_backorder' ),
     508        //  $page = 'mss-settings',
     509        //  $section = 'woomss_section_warehouses'
     510        // );
    466511
    467512        self::add_setting_warehouse_id();
     
    482527                $url = 'entity/store';
    483528                $data = request( $url );
    484                 if ( empty( $data['rows'] ) ) {
     529                if ( empty ( $data['rows'] ) ) {
    485530                    echo 'Система не смогла получить список складов из МойСклад';
    486531                    return;
     
    547592    }
    548593
    549     /**
    550      * display_field_wooms_stocks_without_reserve
    551      */
    552     public static function display_field_wooms_stocks_without_reserve() {
    553         $option = 'wooms_stocks_without_reserve';
    554         printf( '<input type="checkbox" name="%s" value="1" %s />', $option, checked( 1, get_option( $option ), false ) );
    555         echo '<p><small>Если включить опцию то на сайте будут учитываться остатки без учета резерва</small></p>';
    556     }
    557594
    558595    /**
     
    594631        }
    595632
    596         if ( $end_timestamp = self::get_state( 'finish_timestamp' ) ) {
    597             $end_timestamp = date( 'Y-m-d H:i:s', $end_timestamp );
    598             $strings[] = sprintf( 'Последняя успешная синхронизация (отметка времени UTC): %s', $end_timestamp );
    599         }
     633
     634        $strings[] = sprintf( 'Последняя успешная синхронизация: %s', Helper::get_timestamp_last_job_by_hook( self::$walker_hook_name ) ) ?? 'Нет данных';
    600635
    601636        $strings[] = sprintf( 'Очередь задач: <a href="%s">открыть</a>', admin_url( 'admin.php?page=wc-status&tab=action-scheduler&s=wooms_assortment_sync&orderby=schedule&order=desc' ) );
    602637
    603 
    604         if ( defined( 'WC_LOG_HANDLER' ) && 'WC_Log_Handler_DB' == WC_LOG_HANDLER ) {
    605             $strings[] = sprintf( 'Журнал обработки: <a href="%s">открыть</a>', admin_url( 'admin.php?page=wc-status&tab=logs&source=WooMS-ProductStocks' ) );
    606         } else {
    607             $strings[] = sprintf( 'Журнал обработки: <a href="%s">открыть</a>', admin_url( 'admin.php?page=wc-status&tab=logs' ) );
    608         }
     638        $strings[] = sprintf( 'Журнал обработки: <a href="%s">открыть</a>', admin_url( 'admin.php?page=wc-status&tab=logs&source=WooMS-ProductStocks' ) );
    609639
    610640        ?>
    611641        <h2>Остатки</h2>
    612642        <div class="wrap">
    613             <div id="message" class="notice notice-warning">
    614                 <?php
    615                 foreach ( $strings as $string ) {
    616                     printf( '<p>%s</p>', $string );
    617                 }
    618                 ?>
    619             </div>
     643
     644            <?php
     645            foreach ( $strings as $string ) {
     646                printf( '<p>%s</p>', $string );
     647            }
     648            ?>
     649
    620650        </div>
    621651
  • wooms/trunk/includes/ProductVariable.php

    r2989239 r3061787  
    44
    55use function WooMS\request;
     6
    67
    78
     
    1314 */
    1415class ProductVariable {
     16
    1517    /**
    1618     * Save state in DB
     
    2729    public static $walker_hook_name = 'wooms_variables_walker_batch';
    2830
    29 
    30     /**
    31      * The init
    32      */
    3331    public static function init() {
    3432
    35         //walker
    3633        add_action( 'wooms_variables_walker_batch', [__CLASS__, 'walker'] );
    3734
     
    7168            ];
    7269
    73             self::set_state( $state );
     70
    7471        }
    7572
     
    8178        $url = add_query_arg( $state['query_arg'], $url );
    8279
    83         $filters = [];
     80        $filters = [
     81            'archived=false'
     82        ];
    8483
    8584        $filters = apply_filters( 'wooms_url_get_variants_filter', $filters );
     
    116115            $state['count'] += $i;
    117116            $state['query_arg']['offset'] += count( $data['rows'] );
    118             self::set_state( $state );
     117
    119118
    120119            do_action( 'wooms_variations_batch_end' );
     
    124123            return true;
    125124        } catch (\Exception $e) {
    126             self::set_state( 'lock', 0 );
    127             do_action(
    128                 'wooms_logger_error',
    129                 __CLASS__,
    130                 $e->getMessage()
    131             );
     125
     126            Helper::log_error( $e->getMessage(), __CLASS__  );
    132127            return false;
    133128        }
     
    142137        foreach ( $rows as $key => $row ) {
    143138
    144             if ( $row["meta"]["type"] != 'variant' ) {
     139            try {
     140                if ( $row["meta"]["type"] != 'variant' ) {
     141                    continue;
     142                }
     143
     144                $i++;
     145
     146                self::update_variation( $row );
     147
     148            } catch (\Exception $e) {
     149                Helper::log_error( $e->getMessage(), __CLASS__  );
    145150                continue;
    146151            }
    147 
    148             $i++;
    149 
    150             self::update_variation( $row );
    151152
    152153        }
     
    160161    public static function set_wait() {
    161162        as_unschedule_all_actions( self::$walker_hook_name );
    162         self::set_state( 'end_timestamp', time() );
     163
    163164    }
    164165
     
    330331        $variation->set_attributes( $attributes );
    331332
    332         do_action(
    333             'wooms_logger',
    334             __CLASS__,
    335             sprintf( 'Сохранены атрибуты для вариации %s (продукт: %s)', $variation_id, $product_id ),
    336             wc_print_r( $attributes, true )
    337         );
     333        Helper::log('Сохранены атрибуты для вариации', __CLASS__, [
     334            'name' => $variation->get_name(),
     335            'variation_id' => $variation_id,
     336            'product_id' => $product_id,
     337            'attributes' => $attributes,
     338        ]);
    338339
    339340        return $variation;
     
    350351
    351352        if ( ! empty( $row['archived'] ) ) {
    352             return null;
     353            return;
    353354        }
    354355
     
    358359
    359360        $product_href = $row['product']['meta']['href'];
    360         $product_id = self::get_product_id_by_uuid( $product_href );
     361        $product_id = Helper::get_product_id_by_uuid( $product_href );
    361362        $product_parent = wc_get_product( $product_id );
    362363
    363364        if(empty($product_parent)){
    364             do_action(
    365                 'wooms_logger_error',
    366                 __CLASS__,
    367                 sprintf( 'Нет базового продукта для вариации. %s', json_encode( ['product_id' => $product_id, '$row id' => $row ] ) )
    368             );
    369 
    370             return null;
    371 
     365            /**
     366             * так бывает
     367             * мы получаем вариации всей пачкой и для каких то может не быть базового продукта
     368             * чаще всего это не ошибка, но может быть и она
     369             */
     370            Helper::log('Нет базового продукта для вариации', __CLASS__, $row);
     371            return;
    372372        }
    373373
     
    376376            $product_parent->save();
    377377
    378             do_action(
    379                 'wooms_logger_error',
    380                 __CLASS__,
    381                 sprintf( 'Снова сохранили продукт как вариативный %s', $product_id )
    382             );
     378            Helper::log(sprintf( 'Снова сохранили продукт как вариативный %s', $product_id ), __CLASS__);
    383379        }
    384380
     
    433429
    434430        $variation = apply_filters( 'wooms_variation_save', $variation, $row, $product_id );
     431        $variation = apply_filters( 'wooms_variation_update', $variation, $row, $product_id );
    435432
    436433        $variation_id = $variation->save();
     
    546543     */
    547544    public static function walker_finish() {
    548         self::set_state( 'end_timestamp', time() );
    549         self::set_state( 'lock', 0 );
     545
    550546
    551547        do_action( 'wooms_wakler_variations_finish' );
     
    598594    }
    599595
    600 
    601     public static function is_wait() {
    602         //check run main walker
    603         if ( as_next_scheduled_action( 'wooms_products_walker_batch' ) ) {
    604             return true;
    605         }
    606 
    607         //check end pause
    608         if ( ! empty( self::get_state( 'end_timestamp' ) ) ) {
    609             return true;
    610         }
    611 
    612         return false;
    613     }
    614 
    615 
    616 
    617     /**
    618      * display_state
    619      */
    620596    public static function display_state() {
    621597
     
    644620
    645621        } else {
    646             $strings[] = sprintf( '<strong>Статус:</strong> %s', 'в ожидании задач' );
    647             $strings[] = sprintf( 'Последняя успешная синхронизация: %s', wooms_get_timestamp_last_job_by_hook( self::$walker_hook_name ) );
    648         }
    649 
     622            $strings[] = sprintf( '<strong>Статус:</strong> %s', 'Завершено' );
     623            $strings[] = sprintf( 'Последняя успешная синхронизация: %s', Helper::get_timestamp_last_job_by_hook( self::$walker_hook_name ) ) ?? 'Нет данных';
     624        }
    650625
    651626        $strings[] = sprintf( 'Очередь задач: <a href="%s">открыть</a>', admin_url( 'admin.php?page=wc-status&tab=action-scheduler&s=wooms_variables_walker_batch&orderby=schedule&order=desc' ) );
    652627
    653 
    654         if ( defined( 'WC_LOG_HANDLER' ) && 'WC_Log_Handler_DB' == WC_LOG_HANDLER ) {
    655             $strings[] = sprintf( 'Журнал обработки: <a href="%s">открыть</a>', admin_url( 'admin.php?page=wc-status&tab=logs&source=WooMS-ProductVariable' ) );
    656         } else {
    657             $strings[] = sprintf( 'Журнал обработки: <a href="%s">открыть</a>', admin_url( 'admin.php?page=wc-status&tab=logs' ) );
    658         }
     628        $strings[] = sprintf( 'Журнал обработки: <a href="%s">открыть</a>', admin_url( 'admin.php?page=wc-status&tab=logs&source=WooMS-ProductVariable' ) );
    659629
    660630        ?>
     
    767737    }
    768738
    769 
    770 
    771     /**
    772      * get state data
    773      */
    774     public static function get_state( $key = '' ) {
    775         if ( ! $state = get_option( self::$state_transient_key ) ) {
    776             $state = [];
    777             update_option( self::$state_transient_key, $state );
    778         }
    779 
    780         if ( empty( $key ) ) {
    781             return $state;
    782         }
    783 
    784         if ( empty( $state[ $key ] ) ) {
    785             return null;
    786         }
    787 
    788         return $state[ $key ];
    789     }
    790 
    791     /**
    792      * set state data
    793      */
    794     public static function set_state( $key, $value = null ) {
    795         if ( $value === null && is_array( $key ) ) {
    796             update_option( self::$state_transient_key, $key, false );
    797             return;
    798         }
    799 
    800         if ( ! $state = get_option( self::$state_transient_key ) ) {
    801             $state = [];
    802         }
    803 
    804         if ( is_array( $state ) ) {
    805             $state[ $key ] = $value;
    806         } else {
    807             $state = [];
    808             $state[ $key ] = $value;
    809         }
    810 
    811         update_option( self::$state_transient_key, $state, false );
    812     }
    813 
    814739    /**
    815740     * show wooms_id for variation in admin
  • wooms/trunk/includes/Products.php

    r2989239 r3061787  
    55use function WooMS\request;
    66use function Testeroid\ddcli;
    7 use Error, Throwable, WC_Product;
     7use Error, Throwable, WC_Product, WooMS\Helper;
    88
    99defined( 'ABSPATH' ) || exit;
     
    6161
    6262    $filters = [
    63         // 'pathName~=Диваны',
     63        'archived=false'
    6464    ];
    6565
     
    104104
    105105function process_rows( $rows = [] ) {
    106 
    107     try {
    108 
    109         if ( empty( $rows ) ) {
    110             throw new Error('$rows is empty');
     106    $ids = [];
     107    foreach ( $rows as $row ) {
     108        $ids[] = $row['id'];
     109
     110        if ( apply_filters( 'wooms_skip_product_import', false, $row ) ) {
     111            continue;
    111112        }
    112113
    113         $ids = [];
    114         foreach ( $rows as $row ) {
    115             $ids[] = $row['id'];
    116 
    117             if ( apply_filters( 'wooms_skip_product_import', false, $row ) ) {
    118                 continue;
    119             }
    120 
    121             /**
    122              * в выдаче могут быть не только товары, но и вариации и мб что-то еще
    123              * птм нужна проверка что это точно продукт
    124              */
    125             if ( 'variant' == $row["meta"]["type"] ) {
    126                 continue;
    127             }
    128 
    129             $data = apply_filters( 'wooms_product_data', [], $row );
    130 
    131             product_update( $row, $data );
     114        /**
     115         * в выдаче могут быть не только товары, но и вариации и мб что-то еще
     116         * птм нужна проверка что это точно продукт
     117         */
     118        if ( 'variant' == $row["meta"]["type"] ) {
     119            continue;
    132120        }
    133121
    134 
    135         return true;
    136     } catch (Throwable $e) {
    137 
    138         $message = sprintf("wooms process fails: %s, ids: %s, code: %s", $e->getMessage(), json_encode($ids), $e->getCode());
    139         do_action( 'wooms_logger_error', __NAMESPACE__, $message );
    140         error_log($message);
    141 
    142         return false;
    143     }
    144 
    145 
     122        $data = apply_filters( 'wooms_product_data', [], $row );
     123
     124        product_update( $row, $data );
     125    }
    146126}
    147127
     
    223203    $product_id = 0;
    224204
    225     $product_id = get_product_id_by_uuid( $row['id'] );
     205    $product_id = Helper::get_product_id_by_uuid( $row['id'] );
    226206
    227207    if ( ! empty( $row['archived'] ) ) {
     
    248228
    249229    if ( empty( intval( $product_id ) ) ) {
    250         do_action(
    251             'wooms_logger_error',
    252             __NAMESPACE__,
    253             'Ошибка определения и добавления ИД продукта',
    254             $row
    255         );
     230        Helper::log_error('Ошибка определения и добавления ИД продукта', __NAMESPACE__, $row);
     231
    256232        return false;
    257233    }
     
    264240    $data_api = $row;
    265241
    266     $product->update_meta_data( 'wooms_id_' . $row['id'], 1 );
    267 
    268     /**
    269      * Хук позволяет работать с методами WC_Product
    270      * Сохраняет в БД все изменения за 1 раз
    271      * Снижает нагрузку на БД
    272      *
    273      * DEPRECATED
    274      */
    275     $product = apply_filters( 'wooms_product_save', $product, $data_api, $product_id );
    276242
    277243    //save data of source
     
    290256
    291257    $product->update_meta_data( 'wooms_updated_timestamp', date( "Y-m-d H:i:s" ) );
    292 
    293     $product->update_meta_data( 'wooms_id', $data_api['id'] );
    294 
    295258    $product->update_meta_data( 'wooms_updated_from_api', $data_api['updated'] );
    296259
     
    337300    }
    338301
    339     // issue https://github.com/wpcraft-ru/wooms/issues/302
     302    $product->update_meta_data( 'wooms_id', $data_api['id'] );
     303    $product->update_meta_data( 'wooms_id_' . $data_api['id'], 1 );
     304
     305    /**
     306     * reset state product
     307     *
     308     * @issue https://github.com/wpcraft-ru/wooms/issues/302
     309     */
    340310    $product->set_catalog_visibility( 'visible' );
    341 
    342     if ( apply_filters( 'wooms_reset_state_products', true ) ) {
    343         $product->set_stock_status( 'instock' );
    344         $product->set_manage_stock( false );
    345         $product->set_status( 'publish' );
    346     }
     311    $product->set_status( 'publish' );
    347312
    348313    $product = apply_filters( 'wooms_product_update', $product, $row, $data );
     
    350315    $product_id = $product->save();
    351316
    352     do_action(
    353         'wooms_logger',
    354         __NAMESPACE__,
    355         sprintf( 'Продукт: %s (%s) сохранен', $product->get_title(), $product_id )
    356     );
     317    Helper::log(sprintf( 'Продукт: %s (%s) сохранен', $product->get_title(), $product_id ), __NAMESPACE__);
    357318
    358319    return $product_id;
     
    475436        'timestamp' => $now,
    476437        'query_arg' => $query_arg_default,
    477         'end_timestamp' => 0,
    478438    ];
    479439
     
    484444}
    485445
    486 // function auto_start() {
    487 
    488 //   $end_timestamp = get_state( 'end_timestamp' );
    489 //   if( empty($end_timestamp)){
    490 //     return false;
    491 //   }
    492 
    493 //   if ( empty( get_option( 'woomss_pass' ) ) ) {
    494 //      return false;
    495 //  }
    496 
    497 //  if ( as_next_scheduled_action( HOOK_NAME ) ) {
    498 //      return;
    499 //  }
    500 
    501 
    502 
    503 //  return as_schedule_single_action( time(), HOOK_NAME, [], 'WooMS' );
    504 // }
    505 
    506446
    507447function render_ui() {
    508     printf( '<h2>%s</h2>', 'Каталог' );
     448    printf( '<h2>%s</h2>', 'Каталог и базовые продукты' );
    509449
    510450    $strings = [];
     
    516456    } else {
    517457        $strings[] = sprintf( 'Статус: %s', 'Завершено' );
    518         $strings[] = sprintf( 'Время последнего завершения: %s', wooms_get_timestamp_last_job_by_hook( HOOK_NAME ) );
     458        $strings[] = sprintf( 'Последняя успешная синхронизация: %s', Helper::get_timestamp_last_job_by_hook( HOOK_NAME ) ) ?? 'Нет данных';
    519459        printf(
    520460            '<a href="%s" class="button button-primary">Запустить синхронизацию продуктов вручную</a>',
     
    524464    }
    525465    $strings[] = sprintf( 'Очередь задач: <a href="%s">открыть</a>', admin_url( 'admin.php?page=wc-status&tab=action-scheduler&s=wooms_products_walker&orderby=schedule&order=desc' ) );
     466
    526467
    527468    foreach ( $strings as $string ) {
     
    569510    $data_meta = get_post_meta( $post->ID, 'wooms_meta', true );
    570511    $data_updated = get_post_meta( $post->ID, 'wooms_updated', true );
     512    $wooms_updated_timestamp = get_post_meta( $post->ID, 'wooms_updated_timestamp', true );
    571513    if ( $data_id ) {
    572514        printf( '<div>ID товара в МойСклад: <div><strong>%s</strong></div></div>', $data_id );
     
    583525    }
    584526
     527    if ( $data_updated ) {
     528        printf( '<div>Дата последнего обновления из API МойСклад: <strong>%s</strong></div>', $wooms_updated_timestamp );
     529    }
     530
    585531    do_action( 'wooms_display_product_metabox', $post->ID );
    586532}
  • wooms/trunk/includes/ProductsCategories.php

    r2989239 r3061787  
    163163            }
    164164
    165             $term_id = wp_insert_term($row['name'], 'product_cat', $term_new)['term_id'] ?? null;
     165            // https://github.com/wpcraft-ru/wooms/issues/524#issuecomment-1860552168
     166            $term    = wp_insert_term( $row['name'], 'product_cat', $term_new );
     167            $term_id = ! is_wp_error( $term ) ? $term['term_id'] : null;
    166168
    167169            update_term_meta( $term_id, 'wooms_id', $row['id'] );
  • wooms/trunk/includes/ProductsHiding.php

    r2842491 r3061787  
    22
    33namespace WooMS\ProductsHider;
     4
     5use WooMS\Helper;
    46
    57const HOOK_NAME = 'wooms_schedule_clear_old_products_walker';
     
    4345    $ids[] = $product_id;
    4446
    45     if ($product->get_type() == 'variable') {
    46       // $product->set_manage_stock('yes');
    47     }
     47    $product->set_status('draft');
    4848
    4949    $product->set_catalog_visibility('hidden');
    5050    $product->save();
    5151
    52     do_action(
    53       'wooms_logger',
    54       __NAMESPACE__,
    55       sprintf('Скрытие продукта: %s', $product_id)
    56     );
     52    Helper::log(sprintf('Скрытие продукта: %s', $product_id), __NAMESPACE__);
     53
    5754  }
    5855
     
    10299  }
    103100
     101
    104102  $args = array(
    105     'post_type' => ['product', 'product_variation'],
     103    'post_type' => ['product'],
     104    'post_status' => 'publish',
    106105    'numberposts' => 30,
    107106    'fields' => 'ids',
     107
    108108    'tax_query' => array(
    109109      array(
     
    162162  $strings[] = sprintf('Очередь задач: <a href="%s">открыть</a>', admin_url('admin.php?page=wc-status&tab=action-scheduler&s=wooms_schedule_clear_old_products_walker&orderby=schedule&order=desc'));
    163163
     164  $strings[] = sprintf( 'Журнал обработки: <a href="%s">открыть</a>', admin_url( 'admin.php?page=wc-status&tab=logs&source=WooMS-ProductsHider' ) );
     165
    164166  echo '<h2>Скрытие продуктов</h2>';
    165167  foreach ($strings as $string) {
  • wooms/trunk/includes/Settings.php

    r2979725 r3061787  
    33namespace WooMS;
    44
    5 if (!defined('ABSPATH')) {
     5if ( ! defined( 'ABSPATH' ) ) {
    66    exit; // Exit if accessed directly
    77}
     
    1010const OPTIONS_PAGE = 'mss-settings';
    1111
    12 function get_config($key = null){
    13   $config = get_option(OPTION_KEY, []);
    14   if(empty($key)){
    15     return $config;
    16   }
    17   return $config[$key] ?? null;
    18 }
    19 
    20 function set_config($key, $value){
    21   $config = get_option(OPTION_KEY, []);
    22   $config[$key] = $value;
    23   return update_option(OPTION_KEY, $config, false);
     12function get_config( $key = null ) {
     13    $config = get_option( OPTION_KEY, [] );
     14    if ( empty( $key ) ) {
     15        return $config;
     16    }
     17    return $config[ $key ] ?? null;
     18}
     19
     20/**
     21 * Get name of form field by key
     22 */
     23function get_config_name( $key ) {
     24
     25    return OPTION_KEY . '[' . $key . ']';
     26}
     27
     28function set_config( $key, $value ) {
     29    $config = get_option( OPTION_KEY, [] );
     30    $config[ $key ] = $value;
     31    return update_option( OPTION_KEY, $config, false );
    2432}
    2533
     
    2836 * Settings
    2937 */
    30 class Settings
    31 {
     38class Settings {
    3239
    3340    /**
    3441     * The Init
    3542     */
    36     public static function init()
    37     {
     43    public static function init() {
    3844
    3945        add_action(
     
    5460                    'manage_options',
    5561                    'mss-settings',
    56                     array(__CLASS__, 'display_settings')
     62                    array ( __CLASS__, 'display_settings' )
    5763                );
    5864            },
     
    6066        );
    6167
    62         add_action('admin_init', array(__CLASS__, 'settings_general'), $priority = 5, $accepted_args = 1);
    63         add_action('admin_init', array(__CLASS__, 'settings_other'), $priority = 100, $accepted_args = 1);
    64 
    65         add_action('wooms_settings_after_header', [__CLASS__, 'render_nav_menu']);
    66     }
    67 
    68 
    69     public static function render_nav_menu(){
     68        add_action( 'admin_init', array( __CLASS__, 'settings_general' ), $priority = 5, $accepted_args = 1 );
     69        add_action( 'admin_init', array( __CLASS__, 'settings_other' ), $priority = 100, $accepted_args = 1 );
     70
     71        add_action( 'wooms_settings_after_header', [ __CLASS__, 'render_nav_menu' ] );
     72    }
     73
     74
     75    public static function render_nav_menu() {
    7076
    7177        $nav_items = [
    72             'getting-started' => sprintf('<a href="%s" target="_blank">%s</a>', 'https://github.com/wpcraft-ru/wooms/wiki/GettingStarted', 'С чего начать?'),
    73             'diagnostic' => sprintf('<a href="%s">%s</a>', admin_url('site-health.php'), 'Диагностика проблем'),
    74             'ms' => sprintf('<a href="%s" target="_blank">%s</a>', 'https://online.moysklad.ru/', 'Вход в МойСклад'),
     78            'dev' => sprintf( '<a href="%s" target="_blank">%s</a>', 'https://github.com/wpcraft-ru/wooms/', 'Разработка и решение проблем' ),
     79            'docs' => sprintf( '<a href="%s" target="_blank">%s</a>', 'https://github.com/wpcraft-ru/wooms/wiki', 'Документация' ),
     80
     81            'ms' => sprintf( '<a href="%s" target="_blank">%s</a>', 'https://online.moysklad.ru/', 'Вход в МойСклад' ),
    7582        ];
    7683
    77         $nav_items = apply_filters('wooms_settings_nav_items', $nav_items);
    78 
    79         echo implode(' | ', $nav_items);
    80 
    81     }
    82 
    83 
    84 
    85 
    86 
    87     public static function settings_general()
    88     {
    89 
    90         add_settings_section('woomss_section_login', 'Данные для доступа МойСклад', null, 'mss-settings');
    91 
    92     register_setting( 'mss-settings', 'wooms_config' );
    93 
    94         register_setting('mss-settings', 'woomss_login');
     84        $nav_items = apply_filters( 'wooms_settings_nav_items', $nav_items );
     85
     86        ?>
     87        <div>
     88            <a href="https://wpcraft.ru/wooms/" class="button button-primary" target="_blank">Помощь с настройками</a>
     89            <br/>
     90            <br/>
     91            <?= implode( ' | ', $nav_items ); ?>
     92        </div>
     93        <?php
     94
     95
     96
     97    }
     98
     99
     100
     101
     102
     103    public static function settings_general() {
     104
     105        add_settings_section( 'woomss_section_login', 'Данные для доступа МойСклад', null, 'mss-settings' );
     106
     107        register_setting( 'mss-settings', 'wooms_config' );
     108
     109        register_setting( 'mss-settings', 'woomss_login' );
    95110        add_settings_field(
    96111            $id = 'woomss_login',
    97112            $title = 'Логин (admin@...)',
    98             $callback = array(__CLASS__, 'display_form_login',),
     113            $callback = array( __CLASS__, 'display_form_login', ),
    99114            $page = 'mss-settings',
    100115            $section = 'woomss_section_login'
    101116        );
    102117
    103         register_setting('mss-settings', 'woomss_pass');
     118        register_setting( 'mss-settings', 'woomss_pass' );
    104119        add_settings_field(
    105120            $id = 'woomss_pass',
    106121            $title = 'Пароль',
    107             $callback = array(__CLASS__, 'display_form_pass'),
     122            $callback = array( __CLASS__, 'display_form_pass' ),
    108123            $page = 'mss-settings',
    109124            $section = 'woomss_section_login'
     
    114129     * display_form_pass
    115130     */
    116     public static function display_form_pass()
    117     {
    118         printf('<input type="password" name="woomss_pass" value="%s"/>', get_option('woomss_pass'));
     131    public static function display_form_pass() {
     132        printf( '<input type="password" name="woomss_pass" value="%s"/>', get_option( 'woomss_pass' ) );
    119133    }
    120134
     
    122136     * display_form_login
    123137     */
    124     public static function display_form_login()
    125     {
    126         printf('<input type="text" name="woomss_login" value="%s"/>', get_option('woomss_login'));
    127 
    128         printf('<p>%s</p>', 'Вводить нужно только логин и пароль здесь. На стороне МойСклад ничего настраивать не нужно.');
     138    public static function display_form_login() {
     139        printf( '<input type="text" name="woomss_login" value="%s"/>', get_option( 'woomss_login' ) );
     140
     141        printf( '<p>%s</p>', 'Вводить нужно только логин и пароль здесь. На стороне МойСклад ничего настраивать не нужно.' );
    129142    }
    130143
     
    132145     * Settings - Other
    133146     */
    134     public static function settings_other()
    135     {
    136         add_settings_section('woomss_section_other', 'Прочие настройки', null, 'mss-settings');
    137 
    138         register_setting('mss-settings', 'wooms_use_uuid');
     147    public static function settings_other() {
     148        add_settings_section( 'woomss_section_other', 'Прочие настройки', null, 'mss-settings' );
     149
     150        register_setting( 'mss-settings', 'wooms_use_uuid' );
    139151        add_settings_field(
    140152            $id = 'wooms_use_uuid',
    141153            $title = 'Использование UUID',
    142             $callback = array(__CLASS__, 'display_field_wooms_use_uuid'),
     154            $callback = array( __CLASS__, 'display_field_wooms_use_uuid' ),
    143155            $page = 'mss-settings',
    144156            $section = 'woomss_section_other'
    145157        );
    146158
    147         register_setting('mss-settings', 'wooms_replace_title');
     159        register_setting( 'mss-settings', 'wooms_replace_title' );
    148160        add_settings_field(
    149161            $id = 'wooms_replace_title',
    150162            $title = 'Замена заголовка при обновлении',
    151             $callback = array(__CLASS__, 'display_wooms_replace_title'),
     163            $callback = array( __CLASS__, 'display_wooms_replace_title' ),
    152164            $page = 'mss-settings',
    153165            $section = 'woomss_section_other'
    154166        );
    155167
    156         register_setting('mss-settings', 'wooms_replace_description');
     168        register_setting( 'mss-settings', 'wooms_replace_description' );
    157169        add_settings_field(
    158170            $id = 'wooms_replace_description',
    159171            $title = 'Замена описания при обновлении',
    160             $callback = array(__CLASS__, 'display_wooms_replace_desc'),
     172            $callback = array( __CLASS__, 'display_wooms_replace_desc' ),
    161173            $page = 'mss-settings',
    162174            $section = 'woomss_section_other'
     
    167179     * display_wooms_replace_desc
    168180     */
    169     public static function display_wooms_replace_desc()
    170     {
     181    public static function display_wooms_replace_desc() {
    171182
    172183        $option_name = 'wooms_replace_description';
    173         printf('<input type="checkbox" name="%s" value="1" %s />', $option_name, checked(1, get_option($option_name), false));
    174 ?>
     184        printf( '<input type="checkbox" name="%s" value="1" %s />', $option_name, checked( 1, get_option( $option_name ), false ) );
     185        ?>
    175186        <p>
    176187            <small>Если включить опцию, то плагин будет обновлять описание продукта из МойСклад всегда.</small>
    177188        </p>
    178     <?php
     189        <?php
    179190
    180191    }
     
    183194     * display_wooms_replace_title
    184195     */
    185     public static function display_wooms_replace_title()
    186     {
     196    public static function display_wooms_replace_title() {
    187197
    188198        $option_name = 'wooms_replace_title';
    189         printf('<input type="checkbox" name="%s" value="1" %s />', $option_name, checked(1, get_option($option_name), false));
    190     ?>
     199        printf( '<input type="checkbox" name="%s" value="1" %s />', $option_name, checked( 1, get_option( $option_name ), false ) );
     200        ?>
    191201        <p>
    192             <small>Если включить опцию, то плагин будет обновлять заголовки продукта из МойСклад. Иначе при наличии заголовока он не будет обновлен.</small>
     202            <small>Если включить опцию, то плагин будет обновлять заголовки продукта из МойСклад. Иначе при наличии заголовока
     203                он не будет обновлен.</small>
    193204        </p>
    194     <?php
     205        <?php
    195206
    196207    }
     
    199210     * display_field_wooms_use_uuid
    200211     */
    201     public static function display_field_wooms_use_uuid()
    202     {
     212    public static function display_field_wooms_use_uuid() {
    203213
    204214        $option_name = 'wooms_use_uuid';
    205         printf('<input type="checkbox" name="%s" value="1" %s />', $option_name, checked(1, get_option($option_name), false));
    206     ?>
     215        printf( '<input type="checkbox" name="%s" value="1" %s />', $option_name, checked( 1, get_option( $option_name ), false ) );
     216        ?>
    207217
    208218        <p><strong>Если товары не попадают из МойСклад на сайт - попробуйте включить эту опцию.</strong></p>
    209219        <p>
    210             <small>По умолчанию используется связь продуктов по артикулу. Это позволяет обеспечить синхронизацию без удаления всех продуктов с сайта при их наличии. Но без артикула
    211                 товары не будут синхронизироваться. Если товаров на сайте нет, либо их можно удалить без вреда, то можно включить синхронизацию по UUID. В этом случае артикулы
     220            <small>По умолчанию используется связь продуктов по артикулу. Это позволяет обеспечить синхронизацию без удаления
     221                всех продуктов с сайта при их наличии. Но без артикула
     222                товары не будут синхронизироваться. Если товаров на сайте нет, либо их можно удалить без вреда, то можно
     223                включить синхронизацию по UUID. В этом случае артикулы
    212224                будут не нужны. <br />При создании записи о продукте произойдет связка по UUID (meta_key = wooms_id)
    213225            </small>
    214226        </p>
    215     <?php
     227        <?php
    216228
    217229    }
     
    220232     * display_settings
    221233     */
    222     public static function display_settings()
    223     {
    224 
    225     ?>
     234    public static function display_settings() {
     235
     236        ?>
    226237        <form method="POST" action="options.php">
    227238
    228239            <h1>Настройки интеграции МойСклад</h1>
    229240
    230             <?php do_action('wooms_settings_after_header') ?>
     241            <?php do_action( 'wooms_settings_after_header' ) ?>
    231242
    232243            <?php
    233244
    234             settings_fields('mss-settings');
    235             do_settings_sections('mss-settings');
     245            settings_fields( 'mss-settings' );
     246            do_settings_sections( 'mss-settings' );
    236247            submit_button();
    237248            ?>
     
    239250
    240251
    241 <?php
    242 
    243         printf('<p><a href="%s">Управление синхронизацией</a></p>', admin_url('admin.php?page=moysklad'));
    244         printf('<p><a href="%s" target="_blank">Расширения и дополнения</a></p>', "https://github.com/topics/wooms");
    245         printf('<p><a href="%s" target="_blank">Предложения по улучшению и запросы на доработку</a></p>', "https://github.com/wpcraft-ru/wooms/issues");
    246         printf('<p><a href="%s" target="_blank">Рекомендуемые хостинги</a></p>', "https://wpcraft.ru/hosting-wordpress-woocommerce/");
    247         printf('<p><a href="%s" target="_blank">Контакты</a></p>', "https://wpcraft.ru/wooms/");
     252        <?php
     253
     254        printf( '<p><a href="%s">Управление синхронизацией</a></p>', admin_url( 'admin.php?page=moysklad' ) );
     255        printf( '<p><a href="%s" target="_blank">Помощь с настройкой</a></p>', "https://wpcraft.ru/wooms/?utm_source=wooms_plugin_settings_page" );
    248256    }
    249257}
  • wooms/trunk/readme.txt

    r3010824 r3061787  
    11=== WooMS ===
    22Contributors: casepress
    3 Donate link: https://wpcraft.ru/product/wooms-extra/
     3Donate link: https://wpcraft.ru/pay/
    44Tags: moysklad, woocommerce, sync, integration
    55Requires at least: 6.0
     
    2424*   Гибкие настройки
    2525
    26 [Руководство по быстрому началу работы](https://github.com/wpcraft-ru/wooms/wiki/GettingStarted)
     26[Руководство по быстрому началу работы](https://wpcraft.ru/wooms/)
    2727
    2828Исходники для желающих принять участие в разработке: [https://github.com/wpcraft-ru/wooms/](https://github.com/wpcraft-ru/wooms/)
     
    7777== Changelog ==
    7878
     79= 9.11 =
     80- Тест совместимости WooCommerce 8.7.0
     81- Улучшена синхронизация остатков
     82- Не обновляются остатки по товарам https://github.com/wpcraft-ru/wooms/issues/544 https://github.com/wpcraft-ru/wooms/issues/524
     83- Совместимость: 'Высокопроизводительное хранилище заказов' https://github.com/wpcraft-ru/wooms/issues/539
     84
    7985= 9.10 =
    8086- Исправлена ошибка с версией
    81 - Обновдены авто тесты
     87- Обновлены авто тесты
    8288
    8389= 9.9 =
  • wooms/trunk/wooms.php

    r3010824 r3061787  
    2020 * WC tested up to: 8.4.0
    2121 *
    22  * Version: 9.10
     22 * Version: 9.11
    2323 */
    2424
     
    2626
    2727// Exit if accessed directly
    28 defined('ABSPATH') || exit;
     28defined( 'ABSPATH' ) || exit;
    2929
    3030/**
    3131 * Add hook for activate plugin
    3232 */
    33 register_activation_hook(__FILE__, function () {
    34   do_action('wooms_activate');
    35 });
    36 
    37 register_deactivation_hook(__FILE__, function () {
    38   do_action('wooms_deactivate');
    39 });
     33register_activation_hook( __FILE__, function () {
     34    do_action( 'wooms_activate' );
     35} );
     36
     37register_deactivation_hook( __FILE__, function () {
     38    do_action( 'wooms_deactivate' );
     39} );
    4040
    4141
    4242require_once __DIR__ . '/includes/functions.php';
    4343
    44 add_action('plugins_loaded', function () {
    45   if (!wooms_can_start()) {
    46     return;
    47   }
    48 
    49   $files = glob(__DIR__ . '/includes/*.php');
    50   foreach ($files as $file) {
    51     require_once $file;
    52   }
    53   add_action('admin_enqueue_scripts', __NAMESPACE__ . '\\' . 'admin_styles');
    54   add_action('save_post', 'wooms_id_check_if_unique', 10, 3);
    55 });
    56 
    57 add_filter('plugin_row_meta', __NAMESPACE__ . '\\add_wooms_plugin_row_meta', 10, 2);
    58 
    59 
    60 add_filter( "plugin_action_links_" . plugin_basename(__FILE__), function($links){
     44add_action( 'plugins_loaded', function () {
     45    if ( ! wooms_can_start() ) {
     46        return;
     47    }
     48
     49    $files = glob( __DIR__ . '/includes/*.php' );
     50    foreach ( $files as $file ) {
     51        require_once $file;
     52    }
     53    add_action( 'admin_enqueue_scripts', __NAMESPACE__ . '\\' . 'admin_styles' );
     54    add_action( 'save_post', 'wooms_id_check_if_unique', 10, 3 );
     55} );
     56
     57add_filter( 'plugin_row_meta', __NAMESPACE__ . '\\add_wooms_plugin_row_meta', 10, 2 );
     58
     59
     60add_filter( "plugin_action_links_" . plugin_basename( __FILE__ ), function ($links) {
    6161    $mng_link = '<a href="admin.php?page=moysklad">Управление</a>';
    6262    $settings_link = '<a href="admin.php?page=mss-settings">Настройки</a>';
    63     array_unshift($links, $mng_link);
    64     array_unshift($links, $settings_link);
    65     return $links;
    66 });
     63    array_unshift( $links, $mng_link );
     64    array_unshift( $links, $settings_link );
     65    return $links;
     66} );
    6767
    6868
     
    7070 * сообщяем про то что Extra плагин более не актуален
    7171 */
    72 add_action('after_plugin_row_wooms-extra/wooms-extra.php', function($data, $response){
    73 
    74     $wp_list_table = _get_list_table('WP_Plugins_List_Table');
     72add_action( 'after_plugin_row_wooms-extra/wooms-extra.php', function ($data, $response) {
     73
     74    $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
    7575
    7676    printf(
    77       '<tr class="plugin-update-tr">
     77        '<tr class="plugin-update-tr">
    7878          <td colspan="%s" class="plugin-update update-message notice inline notice-warning notice-alt">
    7979            <div class="update-message">
     
    8282          </td>
    8383        </tr>',
    84       $wp_list_table->get_column_count()
     84        $wp_list_table->get_column_count()
    8585    );
    86 }, 10, 2);
    87 add_filter('wooms_xt_load', '__return_false');
     86}, 10, 2 );
     87add_filter( 'wooms_xt_load', '__return_false' );
    8888
    8989
     
    9191 * Add GettingStarted link in row meta at pligins list
    9292 */
    93 function add_wooms_plugin_row_meta($links, $file)
    94 {
    95   if (strpos($file, 'wooms.php') !== false) {
    96     $new_links = array(
    97       '<a href="https://github.com/wpcraft-ru/wooms/wiki/GettingStarted" target="_blank"><strong>Руководство по началу работы</strong></a>',
    98       '<a href="https://wpcraft.ru/wooms/?utm_source=plugin" target="_blank"><strong>Консультации</strong></a>',
    99       '<a href="https://github.com/orgs/wpcraft-ru/projects/2" target="_blank"><strong>Задачи</strong></a>',
    100     );
    101 
    102     $links = array_merge($links, $new_links);
    103   }
    104 
    105   return $links;
     93function add_wooms_plugin_row_meta( $links, $file ) {
     94    if ( strpos( $file, 'wooms.php' ) !== false ) {
     95        $new_links = array(
     96            '<a href="https://github.com/wpcraft-ru/wooms/wiki/GettingStarted" target="_blank"><strong>Руководство по началу работы</strong></a>',
     97            '<a href="https://wpcraft.ru/wooms/?utm_source=plugin" target="_blank"><strong>Консультации</strong></a>',
     98            '<a href="https://github.com/orgs/wpcraft-ru/projects/2" target="_blank"><strong>Задачи</strong></a>',
     99        );
     100
     101        $links = array_merge( $links, $new_links );
     102    }
     103
     104    return $links;
    106105}
    107106
     
    112111 * @return void
    113112 */
    114 function admin_styles()
    115 {
    116   $admin_style = plugin_dir_url(__FILE__) . 'css/admin.css';
    117 
    118   wp_enqueue_style('wooms_styles', $admin_style, array());
    119 }
    120 
    121 
    122 
    123 function get_api_url($path){
     113function admin_styles() {
     114    $admin_style = plugin_dir_url( __FILE__ ) . 'css/admin.css';
     115
     116    wp_enqueue_style( 'wooms_styles', $admin_style, array() );
     117}
     118
     119
     120
     121function get_api_url( $path ) {
    124122    return $url = 'https://api.moysklad.ru/api/remap/1.2/' . $path;
    125123}
    126124
    127 function request($path = '', $data = array(), $type = 'GET'){
    128   // https://api.moysklad.ru/api/remap/1.2/
    129 
    130 
    131   if (empty($path)) {
    132     return false;
    133   }
    134 
    135   if(str_contains($path, 'https://api.moysklad.ru/api/remap/1.2/')){
    136     $url = $path;
    137   } else {
    138     $url = 'https://api.moysklad.ru/api/remap/1.2/' . $path;
    139   }
    140 
    141 
    142 
    143   //@link https://github.com/wpcraft-ru/wooms/issues/177
    144   $url = str_replace('product_id', 'product.id', $url);
    145   $url = str_replace('store_id', 'store.id', $url);
    146   $url = str_replace('consignment_id', 'consignment.id', $url);
    147   $url = str_replace('variant_id', 'variant.id', $url);
    148   $url = str_replace('productFolder_id', 'productFolder.id', $url);
    149 
    150   if (!empty($data) && 'GET' == $type) {
    151     $type = 'POST';
    152   }
    153   if ('GET' == $type) {
    154     $data = null;
    155   } else {
    156     $data = json_encode($data);
    157   }
    158 
    159   $args = array(
    160     'method'      => $type,
    161     'timeout'     => 45,
    162     'redirection' => 5,
    163     'headers'     => array(
    164       "Content-Type"  => 'application/json;charset=utf-8',
    165       "Accept-Encoding" => "gzip",
    166       'Authorization' => 'Basic ' .
    167         base64_encode(get_option('woomss_login') . ':' . get_option('woomss_pass')),
    168     ),
    169     'body'        => $data,
    170   );
    171 
    172   $request = wp_remote_request($url, $args);
    173   if (is_wp_error($request)) {
    174     do_action(
    175       'wooms_logger_error',
    176       $type = 'WooMS-Request',
    177       $title = 'Ошибка REST API WP Error',
    178       $desc = $request->get_error_message()
    179     );
    180 
    181     return false;
    182   }
    183 
    184   if (empty($request['body'])) {
    185     do_action(
    186       'wooms_logger_error',
    187       $type = 'WooMS-Request',
    188       $title = 'REST API вернулся без требуемых данных'
    189     );
    190 
    191     return false;
    192   }
    193 
    194   $response = json_decode($request['body'], true);
    195 
    196   if (!empty($response["errors"]) and is_array($response["errors"])) {
    197     foreach ($response["errors"] as $error) {
    198       do_action(
    199         'wooms_logger_error',
    200         $type = 'WooMS-Request',
    201         $title = $url,
    202         $response
    203       );
    204     }
    205   }
    206 
    207   return $response;
    208 }
    209 
    210 
    211 function get_session_id(){
    212   return \WooMS\Products\get_session_id();
    213 }
     125function request( $path = '', $data = array(), $type = 'GET' ) {
     126    // https://api.moysklad.ru/api/remap/1.2/
     127
     128
     129    if ( empty ( $path ) ) {
     130        return false;
     131    }
     132
     133    if ( str_contains( $path, 'https://api.moysklad.ru/api/remap/1.2/' ) ) {
     134        $url = $path;
     135    } else {
     136        $url = 'https://api.moysklad.ru/api/remap/1.2/' . $path;
     137    }
     138
     139
     140
     141    //@link https://github.com/wpcraft-ru/wooms/issues/177
     142    $url = str_replace( 'product_id', 'product.id', $url );
     143    $url = str_replace( 'store_id', 'store.id', $url );
     144    $url = str_replace( 'consignment_id', 'consignment.id', $url );
     145    $url = str_replace( 'variant_id', 'variant.id', $url );
     146    $url = str_replace( 'productFolder_id', 'productFolder.id', $url );
     147
     148    if ( ! empty ( $data ) && 'GET' == $type ) {
     149        $type = 'POST';
     150    }
     151    if ( 'GET' == $type ) {
     152        $data = null;
     153    } else {
     154        $data = json_encode( $data );
     155    }
     156
     157    $args = array(
     158        'method' => $type,
     159        'timeout' => 45,
     160        'redirection' => 5,
     161        'headers' => array(
     162                "Content-Type" => 'application/json;charset=utf-8',
     163                "Accept-Encoding" => "gzip",
     164                'Authorization' => 'Basic ' .
     165                    base64_encode( get_option( 'woomss_login' ) . ':' . get_option( 'woomss_pass' ) ),
     166            ),
     167        'body' => $data,
     168    );
     169
     170    $request = wp_remote_request( $url, $args );
     171    if ( is_wp_error( $request ) ) {
     172        do_action(
     173            'wooms_logger_error',
     174            $type = 'WooMS-Request',
     175            $title = 'Ошибка REST API WP Error',
     176            $desc = $request->get_error_message()
     177        );
     178
     179        return false;
     180    }
     181
     182    if ( empty ( $request['body'] ) ) {
     183        do_action(
     184            'wooms_logger_error',
     185            $type = 'WooMS-Request',
     186            $title = 'REST API вернулся без требуемых данных'
     187        );
     188
     189        return false;
     190    }
     191
     192    $response = json_decode( $request['body'], true );
     193
     194    if ( ! empty ( $response["errors"] ) and is_array( $response["errors"] ) ) {
     195        foreach ( $response["errors"] as $error ) {
     196            do_action(
     197                'wooms_logger_error',
     198                $type = 'WooMS-Request',
     199                $title = $url,
     200                $response
     201            );
     202        }
     203    }
     204
     205    return $response;
     206}
     207
     208
     209function get_session_id() {
     210    return \WooMS\Products\get_session_id();
     211}
     212
     213/**
     214 * doc https://github.com/woocommerce/woocommerce/wiki/High-Performance-Order-Storage-Upgrade-Recipe-Book
     215 * doc https://woo.com/document/high-performance-order-storage/
     216 * issue https://github.com/wpcraft-ru/wooms/issues/539
     217 */
     218add_action( 'before_woocommerce_init', function () {
     219    if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class) ) {
     220        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );
     221    }
     222} );
Note: See TracChangeset for help on using the changeset viewer.