Changeset 3061787
- Timestamp:
- 03/31/2024 04:35:08 PM (23 months ago)
- Location:
- wooms
- Files:
-
- 2 added
- 18 edited
- 1 copied
-
tags/9.11 (copied) (copied from wooms/trunk)
-
tags/9.11/includes/Helper.php (added)
-
tags/9.11/includes/MenuTools.php (modified) (2 diffs)
-
tags/9.11/includes/ProductStocks.php (modified) (16 diffs)
-
tags/9.11/includes/ProductVariable.php (modified) (18 diffs)
-
tags/9.11/includes/Products.php (modified) (15 diffs)
-
tags/9.11/includes/ProductsCategories.php (modified) (1 diff)
-
tags/9.11/includes/ProductsHiding.php (modified) (4 diffs)
-
tags/9.11/includes/Settings.php (modified) (13 diffs)
-
tags/9.11/readme.txt (modified) (3 diffs)
-
tags/9.11/wooms.php (modified) (6 diffs)
-
trunk/includes/Helper.php (added)
-
trunk/includes/MenuTools.php (modified) (2 diffs)
-
trunk/includes/ProductStocks.php (modified) (16 diffs)
-
trunk/includes/ProductVariable.php (modified) (18 diffs)
-
trunk/includes/Products.php (modified) (15 diffs)
-
trunk/includes/ProductsCategories.php (modified) (1 diff)
-
trunk/includes/ProductsHiding.php (modified) (4 diffs)
-
trunk/includes/Settings.php (modified) (13 diffs)
-
trunk/readme.txt (modified) (3 diffs)
-
trunk/wooms.php (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
wooms/tags/9.11/includes/MenuTools.php
r2854597 r3061787 2 2 3 3 namespace WooMS; 4 4 5 /** 5 6 * Tool for MoySklad … … 7 8 class MenuTools { 8 9 9 /**10 * URL action11 */12 public static $url;10 /** 11 * URL action 12 */ 13 public static $url; 13 14 14 /**15 * The Init16 */17 public static function init(){15 /** 16 * The Init 17 */ 18 public static function init() { 18 19 19 self::$url = $_SERVER['REQUEST_URI'];20 self::$url = $_SERVER['REQUEST_URI']; 20 21 21 add_action(22 'admin_menu',23 function () {22 add_action( 23 'admin_menu', 24 function () { 24 25 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 } 36 37 37 }38 );38 } 39 ); 39 40 40 41 41 }42 } 42 43 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 80 63 81 64 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 } 83 86 84 87 -
wooms/tags/9.11/includes/ProductStocks.php
r3010225 r3061787 3 3 namespace WooMS; 4 4 5 use WC_Product; 5 6 use function WooMS\request; 6 7 8 use function WooMS\get_config as get_config; 9 use function WooMS\get_config_name as get_config_name; 7 10 8 11 defined( 'ABSPATH' ) || exit; // Exit if accessed directly … … 27 30 public static function init() { 28 31 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 29 48 add_action( 'wooms_assortment_sync', [ __CLASS__, 'batch_handler' ] ); 30 49 … … 37 56 add_action( 'wooms_variations_batch_end', [ __CLASS__, 'restart_after_batch' ] ); 38 57 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 ); 42 60 add_action( 'wooms_tools_sections', array( __CLASS__, 'display_state' ), 17 ); 43 61 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 ) ) { 55 69 $state = [ 56 70 'count' => 0 … … 74 88 75 89 $products = get_posts( $args ); 76 if ( empty($products) ) { 77 self::set_state( 'finish_timestamp', time() );90 91 if ( empty( $products ) ) { 78 92 return false; 79 93 } 80 94 81 $filters = [];95 $filters_by_id = []; 82 96 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 87 105 $url = 'https://api.moysklad.ru/api/remap/1.2/entity/assortment'; 88 106 … … 101 119 $data = request( $url ); 102 120 121 // var_dump($data); exit; 122 103 123 if ( empty( $data['rows'] ) ) { 104 124 return false; 105 125 } 106 126 107 108 $ids = self::process_rows($data['rows']); 109 if($ids){ 127 $ids = self::process_rows( $data['rows'] ); 128 if ( $ids ) { 110 129 $state['last_ids'] = $ids; 111 130 } 112 131 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 ) { 120 139 121 140 $ids = []; 122 141 foreach ( $rows as $row ) { 123 142 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 ); 125 145 continue; 126 146 } 127 147 128 148 if ( ! $product = wc_get_product( $product_id ) ) { 149 Helper::log_error( 'Не нашли продукт по $product_id', __CLASS__, $row ); 129 150 continue; 130 151 } … … 133 154 134 155 $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 136 157 137 158 /** … … 142 163 $product = apply_filters( 'wooms_stock_product_save', $product, $row ); 143 164 165 144 166 $ids[] = $product->save(); 145 167 } 146 168 147 169 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; 148 278 149 279 } … … 168 298 } 169 299 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 queue229 */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 236 300 237 301 public static function restart_after_batch() { 238 if (as_has_scheduled_action(self::$walker_hook_name)){302 if ( ! self::is_enable() ) { 239 303 return; 240 304 } 241 305 306 if ( as_has_scheduled_action( self::$walker_hook_name ) ) { 307 return; 308 } 309 242 310 as_schedule_single_action( time(), self::$walker_hook_name, [], 'WooMS' ); 243 }244 245 246 247 248 /**249 * check is wait250 */251 public static function is_wait() {252 if ( self::get_state( 'finish_timestamp' ) ) {253 return true;254 }255 256 return false;257 311 } 258 312 … … 279 333 280 334 281 282 283 /**284 * set state data285 */286 335 public static function set_state( $key, $value ) { 287 336 … … 373 422 } 374 423 375 /**376 * Select type stock377 */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 }385 424 386 425 /** 387 426 * Update stock for variation 388 427 */ 389 public static function update_variation( $variation, $data_api ) {428 public static function update_variation( \WC_Product_Variation $variation, $data_api ) { 390 429 if ( self::is_enable() ) { 391 430 $variation->update_meta_data( self::$walker_hook_name, 1 ); … … 393 432 $variation->set_catalog_visibility( 'visible' ); 394 433 $variation->set_stock_status( 'instock' ); 395 $variation->set_manage_stock( 'no');434 $variation->set_manage_stock( false ); 396 435 $variation->set_status( 'publish' ); 397 436 } … … 410 449 $product->set_catalog_visibility( 'visible' ); 411 450 $product->set_stock_status( 'instock' ); 412 $product->set_manage_stock( 'no');451 $product->set_manage_stock( false ); 413 452 $product->set_status( 'publish' ); 414 453 } … … 438 477 ); 439 478 440 register_setting( 'mss-settings', 'wooms_stocks_without_reserve' );441 479 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 }, 445 486 $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 // ); 466 511 467 512 self::add_setting_warehouse_id(); … … 482 527 $url = 'entity/store'; 483 528 $data = request( $url ); 484 if ( empty ( $data['rows'] ) ) {529 if ( empty ( $data['rows'] ) ) { 485 530 echo 'Система не смогла получить список складов из МойСклад'; 486 531 return; … … 547 592 } 548 593 549 /**550 * display_field_wooms_stocks_without_reserve551 */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 }557 594 558 595 /** … … 594 631 } 595 632 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 ) ) ?? 'Нет данных'; 600 635 601 636 $strings[] = sprintf( 'Очередь задач: <a href="%s">открыть</a>', admin_url( 'admin.php?page=wc-status&tab=action-scheduler&s=wooms_assortment_sync&orderby=schedule&order=desc' ) ); 602 637 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' ) ); 609 639 610 640 ?> 611 641 <h2>Остатки</h2> 612 642 <div class="wrap"> 613 <div id="message" class="notice notice-warning"> 614 <?php615 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 620 650 </div> 621 651 -
wooms/tags/9.11/includes/ProductVariable.php
r2989239 r3061787 4 4 5 5 use function WooMS\request; 6 6 7 7 8 … … 13 14 */ 14 15 class ProductVariable { 16 15 17 /** 16 18 * Save state in DB … … 27 29 public static $walker_hook_name = 'wooms_variables_walker_batch'; 28 30 29 30 /**31 * The init32 */33 31 public static function init() { 34 32 35 //walker36 33 add_action( 'wooms_variables_walker_batch', [__CLASS__, 'walker'] ); 37 34 … … 71 68 ]; 72 69 73 self::set_state( $state ); 70 74 71 } 75 72 … … 81 78 $url = add_query_arg( $state['query_arg'], $url ); 82 79 83 $filters = []; 80 $filters = [ 81 'archived=false' 82 ]; 84 83 85 84 $filters = apply_filters( 'wooms_url_get_variants_filter', $filters ); … … 116 115 $state['count'] += $i; 117 116 $state['query_arg']['offset'] += count( $data['rows'] ); 118 self::set_state( $state ); 117 119 118 120 119 do_action( 'wooms_variations_batch_end' ); … … 124 123 return true; 125 124 } 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__ ); 132 127 return false; 133 128 } … … 142 137 foreach ( $rows as $key => $row ) { 143 138 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__ ); 145 150 continue; 146 151 } 147 148 $i++;149 150 self::update_variation( $row );151 152 152 153 } … … 160 161 public static function set_wait() { 161 162 as_unschedule_all_actions( self::$walker_hook_name ); 162 self::set_state( 'end_timestamp', time() ); 163 163 164 } 164 165 … … 330 331 $variation->set_attributes( $attributes ); 331 332 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 ]); 338 339 339 340 return $variation; … … 350 351 351 352 if ( ! empty( $row['archived'] ) ) { 352 return null;353 return; 353 354 } 354 355 … … 358 359 359 360 $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 ); 361 362 $product_parent = wc_get_product( $product_id ); 362 363 363 364 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; 372 372 } 373 373 … … 376 376 $product_parent->save(); 377 377 378 do_action( 379 'wooms_logger_error', 380 __CLASS__, 381 sprintf( 'Снова сохранили продукт как вариативный %s', $product_id ) 382 ); 378 Helper::log(sprintf( 'Снова сохранили продукт как вариативный %s', $product_id ), __CLASS__); 383 379 } 384 380 … … 433 429 434 430 $variation = apply_filters( 'wooms_variation_save', $variation, $row, $product_id ); 431 $variation = apply_filters( 'wooms_variation_update', $variation, $row, $product_id ); 435 432 436 433 $variation_id = $variation->save(); … … 546 543 */ 547 544 public static function walker_finish() { 548 self::set_state( 'end_timestamp', time() ); 549 self::set_state( 'lock', 0 ); 545 550 546 551 547 do_action( 'wooms_wakler_variations_finish' ); … … 598 594 } 599 595 600 601 public static function is_wait() {602 //check run main walker603 if ( as_next_scheduled_action( 'wooms_products_walker_batch' ) ) {604 return true;605 }606 607 //check end pause608 if ( ! empty( self::get_state( 'end_timestamp' ) ) ) {609 return true;610 }611 612 return false;613 }614 615 616 617 /**618 * display_state619 */620 596 public static function display_state() { 621 597 … … 644 620 645 621 } 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 } 650 625 651 626 $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' ) ); 652 627 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' ) ); 659 629 660 630 ?> … … 767 737 } 768 738 769 770 771 /**772 * get state data773 */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 data793 */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 814 739 /** 815 740 * show wooms_id for variation in admin -
wooms/tags/9.11/includes/Products.php
r2989239 r3061787 5 5 use function WooMS\request; 6 6 use function Testeroid\ddcli; 7 use Error, Throwable, WC_Product ;7 use Error, Throwable, WC_Product, WooMS\Helper; 8 8 9 9 defined( 'ABSPATH' ) || exit; … … 61 61 62 62 $filters = [ 63 // 'pathName~=Диваны',63 'archived=false' 64 64 ]; 65 65 … … 104 104 105 105 function 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; 111 112 } 112 113 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; 132 120 } 133 121 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 } 146 126 } 147 127 … … 223 203 $product_id = 0; 224 204 225 $product_id = get_product_id_by_uuid( $row['id'] );205 $product_id = Helper::get_product_id_by_uuid( $row['id'] ); 226 206 227 207 if ( ! empty( $row['archived'] ) ) { … … 248 228 249 229 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 256 232 return false; 257 233 } … … 264 240 $data_api = $row; 265 241 266 $product->update_meta_data( 'wooms_id_' . $row['id'], 1 );267 268 /**269 * Хук позволяет работать с методами WC_Product270 * Сохраняет в БД все изменения за 1 раз271 * Снижает нагрузку на БД272 *273 * DEPRECATED274 */275 $product = apply_filters( 'wooms_product_save', $product, $data_api, $product_id );276 242 277 243 //save data of source … … 290 256 291 257 $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 295 258 $product->update_meta_data( 'wooms_updated_from_api', $data_api['updated'] ); 296 259 … … 337 300 } 338 301 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 */ 340 310 $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' ); 347 312 348 313 $product = apply_filters( 'wooms_product_update', $product, $row, $data ); … … 350 315 $product_id = $product->save(); 351 316 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__); 357 318 358 319 return $product_id; … … 475 436 'timestamp' => $now, 476 437 'query_arg' => $query_arg_default, 477 'end_timestamp' => 0,478 438 ]; 479 439 … … 484 444 } 485 445 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 506 446 507 447 function render_ui() { 508 printf( '<h2>%s</h2>', 'Каталог ' );448 printf( '<h2>%s</h2>', 'Каталог и базовые продукты' ); 509 449 510 450 $strings = []; … … 516 456 } else { 517 457 $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 ) ) ?? 'Нет данных'; 519 459 printf( 520 460 '<a href="%s" class="button button-primary">Запустить синхронизацию продуктов вручную</a>', … … 524 464 } 525 465 $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 526 467 527 468 foreach ( $strings as $string ) { … … 569 510 $data_meta = get_post_meta( $post->ID, 'wooms_meta', true ); 570 511 $data_updated = get_post_meta( $post->ID, 'wooms_updated', true ); 512 $wooms_updated_timestamp = get_post_meta( $post->ID, 'wooms_updated_timestamp', true ); 571 513 if ( $data_id ) { 572 514 printf( '<div>ID товара в МойСклад: <div><strong>%s</strong></div></div>', $data_id ); … … 583 525 } 584 526 527 if ( $data_updated ) { 528 printf( '<div>Дата последнего обновления из API МойСклад: <strong>%s</strong></div>', $wooms_updated_timestamp ); 529 } 530 585 531 do_action( 'wooms_display_product_metabox', $post->ID ); 586 532 } -
wooms/tags/9.11/includes/ProductsCategories.php
r2989239 r3061787 163 163 } 164 164 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; 166 168 167 169 update_term_meta( $term_id, 'wooms_id', $row['id'] ); -
wooms/tags/9.11/includes/ProductsHiding.php
r2842491 r3061787 2 2 3 3 namespace WooMS\ProductsHider; 4 5 use WooMS\Helper; 4 6 5 7 const HOOK_NAME = 'wooms_schedule_clear_old_products_walker'; … … 43 45 $ids[] = $product_id; 44 46 45 if ($product->get_type() == 'variable') { 46 // $product->set_manage_stock('yes'); 47 } 47 $product->set_status('draft'); 48 48 49 49 $product->set_catalog_visibility('hidden'); 50 50 $product->save(); 51 51 52 do_action( 53 'wooms_logger', 54 __NAMESPACE__, 55 sprintf('Скрытие продукта: %s', $product_id) 56 ); 52 Helper::log(sprintf('Скрытие продукта: %s', $product_id), __NAMESPACE__); 53 57 54 } 58 55 … … 102 99 } 103 100 101 104 102 $args = array( 105 'post_type' => ['product', 'product_variation'], 103 'post_type' => ['product'], 104 'post_status' => 'publish', 106 105 'numberposts' => 30, 107 106 'fields' => 'ids', 107 108 108 'tax_query' => array( 109 109 array( … … 162 162 $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')); 163 163 164 $strings[] = sprintf( 'Журнал обработки: <a href="%s">открыть</a>', admin_url( 'admin.php?page=wc-status&tab=logs&source=WooMS-ProductsHider' ) ); 165 164 166 echo '<h2>Скрытие продуктов</h2>'; 165 167 foreach ($strings as $string) { -
wooms/tags/9.11/includes/Settings.php
r2979725 r3061787 3 3 namespace WooMS; 4 4 5 if ( !defined('ABSPATH')) {5 if ( ! defined( 'ABSPATH' ) ) { 6 6 exit; // Exit if accessed directly 7 7 } … … 10 10 const OPTIONS_PAGE = 'mss-settings'; 11 11 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); 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 /** 21 * Get name of form field by key 22 */ 23 function get_config_name( $key ) { 24 25 return OPTION_KEY . '[' . $key . ']'; 26 } 27 28 function set_config( $key, $value ) { 29 $config = get_option( OPTION_KEY, [] ); 30 $config[ $key ] = $value; 31 return update_option( OPTION_KEY, $config, false ); 24 32 } 25 33 … … 28 36 * Settings 29 37 */ 30 class Settings 31 { 38 class Settings { 32 39 33 40 /** 34 41 * The Init 35 42 */ 36 public static function init() 37 { 43 public static function init() { 38 44 39 45 add_action( … … 54 60 'manage_options', 55 61 'mss-settings', 56 array (__CLASS__, 'display_settings')62 array ( __CLASS__, 'display_settings' ) 57 63 ); 58 64 }, … … 60 66 ); 61 67 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() { 70 76 71 77 $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/', 'Вход в МойСклад' ), 75 82 ]; 76 83 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' ); 95 110 add_settings_field( 96 111 $id = 'woomss_login', 97 112 $title = 'Логин (admin@...)', 98 $callback = array( __CLASS__, 'display_form_login',),113 $callback = array( __CLASS__, 'display_form_login', ), 99 114 $page = 'mss-settings', 100 115 $section = 'woomss_section_login' 101 116 ); 102 117 103 register_setting( 'mss-settings', 'woomss_pass');118 register_setting( 'mss-settings', 'woomss_pass' ); 104 119 add_settings_field( 105 120 $id = 'woomss_pass', 106 121 $title = 'Пароль', 107 $callback = array( __CLASS__, 'display_form_pass'),122 $callback = array( __CLASS__, 'display_form_pass' ), 108 123 $page = 'mss-settings', 109 124 $section = 'woomss_section_login' … … 114 129 * display_form_pass 115 130 */ 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' ) ); 119 133 } 120 134 … … 122 136 * display_form_login 123 137 */ 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>', 'Вводить нужно только логин и пароль здесь. На стороне МойСклад ничего настраивать не нужно.' ); 129 142 } 130 143 … … 132 145 * Settings - Other 133 146 */ 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' ); 139 151 add_settings_field( 140 152 $id = 'wooms_use_uuid', 141 153 $title = 'Использование UUID', 142 $callback = array( __CLASS__, 'display_field_wooms_use_uuid'),154 $callback = array( __CLASS__, 'display_field_wooms_use_uuid' ), 143 155 $page = 'mss-settings', 144 156 $section = 'woomss_section_other' 145 157 ); 146 158 147 register_setting( 'mss-settings', 'wooms_replace_title');159 register_setting( 'mss-settings', 'wooms_replace_title' ); 148 160 add_settings_field( 149 161 $id = 'wooms_replace_title', 150 162 $title = 'Замена заголовка при обновлении', 151 $callback = array( __CLASS__, 'display_wooms_replace_title'),163 $callback = array( __CLASS__, 'display_wooms_replace_title' ), 152 164 $page = 'mss-settings', 153 165 $section = 'woomss_section_other' 154 166 ); 155 167 156 register_setting( 'mss-settings', 'wooms_replace_description');168 register_setting( 'mss-settings', 'wooms_replace_description' ); 157 169 add_settings_field( 158 170 $id = 'wooms_replace_description', 159 171 $title = 'Замена описания при обновлении', 160 $callback = array( __CLASS__, 'display_wooms_replace_desc'),172 $callback = array( __CLASS__, 'display_wooms_replace_desc' ), 161 173 $page = 'mss-settings', 162 174 $section = 'woomss_section_other' … … 167 179 * display_wooms_replace_desc 168 180 */ 169 public static function display_wooms_replace_desc() 170 { 181 public static function display_wooms_replace_desc() { 171 182 172 183 $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 ?> 175 186 <p> 176 187 <small>Если включить опцию, то плагин будет обновлять описание продукта из МойСклад всегда.</small> 177 188 </p> 178 <?php189 <?php 179 190 180 191 } … … 183 194 * display_wooms_replace_title 184 195 */ 185 public static function display_wooms_replace_title() 186 { 196 public static function display_wooms_replace_title() { 187 197 188 198 $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 ?> 191 201 <p> 192 <small>Если включить опцию, то плагин будет обновлять заголовки продукта из МойСклад. Иначе при наличии заголовока он не будет обновлен.</small> 202 <small>Если включить опцию, то плагин будет обновлять заголовки продукта из МойСклад. Иначе при наличии заголовока 203 он не будет обновлен.</small> 193 204 </p> 194 <?php205 <?php 195 206 196 207 } … … 199 210 * display_field_wooms_use_uuid 200 211 */ 201 public static function display_field_wooms_use_uuid() 202 { 212 public static function display_field_wooms_use_uuid() { 203 213 204 214 $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 ?> 207 217 208 218 <p><strong>Если товары не попадают из МойСклад на сайт - попробуйте включить эту опцию.</strong></p> 209 219 <p> 210 <small>По умолчанию используется связь продуктов по артикулу. Это позволяет обеспечить синхронизацию без удаления всех продуктов с сайта при их наличии. Но без артикула 211 товары не будут синхронизироваться. Если товаров на сайте нет, либо их можно удалить без вреда, то можно включить синхронизацию по UUID. В этом случае артикулы 220 <small>По умолчанию используется связь продуктов по артикулу. Это позволяет обеспечить синхронизацию без удаления 221 всех продуктов с сайта при их наличии. Но без артикула 222 товары не будут синхронизироваться. Если товаров на сайте нет, либо их можно удалить без вреда, то можно 223 включить синхронизацию по UUID. В этом случае артикулы 212 224 будут не нужны. <br />При создании записи о продукте произойдет связка по UUID (meta_key = wooms_id) 213 225 </small> 214 226 </p> 215 <?php227 <?php 216 228 217 229 } … … 220 232 * display_settings 221 233 */ 222 public static function display_settings() 223 { 224 225 ?> 234 public static function display_settings() { 235 236 ?> 226 237 <form method="POST" action="options.php"> 227 238 228 239 <h1>Настройки интеграции МойСклад</h1> 229 240 230 <?php do_action( 'wooms_settings_after_header') ?>241 <?php do_action( 'wooms_settings_after_header' ) ?> 231 242 232 243 <?php 233 244 234 settings_fields( 'mss-settings');235 do_settings_sections( 'mss-settings');245 settings_fields( 'mss-settings' ); 246 do_settings_sections( 'mss-settings' ); 236 247 submit_button(); 237 248 ?> … … 239 250 240 251 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" ); 248 256 } 249 257 } -
wooms/tags/9.11/readme.txt
r3010824 r3061787 1 1 === WooMS === 2 2 Contributors: casepress 3 Donate link: https://wpcraft.ru/p roduct/wooms-extra/3 Donate link: https://wpcraft.ru/pay/ 4 4 Tags: moysklad, woocommerce, sync, integration 5 5 Requires at least: 6.0 … … 24 24 * Гибкие настройки 25 25 26 [Руководство по быстрому началу работы](https:// github.com/wpcraft-ru/wooms/wiki/GettingStarted)26 [Руководство по быстрому началу работы](https://wpcraft.ru/wooms/) 27 27 28 28 Исходники для желающих принять участие в разработке: [https://github.com/wpcraft-ru/wooms/](https://github.com/wpcraft-ru/wooms/) … … 77 77 == Changelog == 78 78 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 79 85 = 9.10 = 80 86 - Исправлена ошибка с версией 81 - Обнов дены авто тесты87 - Обновлены авто тесты 82 88 83 89 = 9.9 = -
wooms/tags/9.11/wooms.php
r3010824 r3061787 20 20 * WC tested up to: 8.4.0 21 21 * 22 * Version: 9.1 022 * Version: 9.11 23 23 */ 24 24 … … 26 26 27 27 // Exit if accessed directly 28 defined( 'ABSPATH') || exit;28 defined( 'ABSPATH' ) || exit; 29 29 30 30 /** 31 31 * Add hook for activate plugin 32 32 */ 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 } );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 } ); 40 40 41 41 42 42 require_once __DIR__ . '/includes/functions.php'; 43 43 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){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) { 61 61 $mng_link = '<a href="admin.php?page=moysklad">Управление</a>'; 62 62 $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 } ); 67 67 68 68 … … 70 70 * сообщяем про то что Extra плагин более не актуален 71 71 */ 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');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' ); 75 75 76 76 printf( 77 '<tr class="plugin-update-tr">77 '<tr class="plugin-update-tr"> 78 78 <td colspan="%s" class="plugin-update update-message notice inline notice-warning notice-alt"> 79 79 <div class="update-message"> … … 82 82 </td> 83 83 </tr>', 84 $wp_list_table->get_column_count()84 $wp_list_table->get_column_count() 85 85 ); 86 }, 10, 2 );87 add_filter( 'wooms_xt_load', '__return_false');86 }, 10, 2 ); 87 add_filter( 'wooms_xt_load', '__return_false' ); 88 88 89 89 … … 91 91 * Add GettingStarted link in row meta at pligins list 92 92 */ 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; 93 function 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; 106 105 } 107 106 … … 112 111 * @return void 113 112 */ 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){ 113 function 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 121 function get_api_url( $path ) { 124 122 return $url = 'https://api.moysklad.ru/api/remap/1.2/' . $path; 125 123 } 126 124 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 } 125 function 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 209 function 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 */ 218 add_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 2 2 3 3 namespace WooMS; 4 4 5 /** 5 6 * Tool for MoySklad … … 7 8 class MenuTools { 8 9 9 /**10 * URL action11 */12 public static $url;10 /** 11 * URL action 12 */ 13 public static $url; 13 14 14 /**15 * The Init16 */17 public static function init(){15 /** 16 * The Init 17 */ 18 public static function init() { 18 19 19 self::$url = $_SERVER['REQUEST_URI'];20 self::$url = $_SERVER['REQUEST_URI']; 20 21 21 add_action(22 'admin_menu',23 function () {22 add_action( 23 'admin_menu', 24 function () { 24 25 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 } 36 37 37 }38 );38 } 39 ); 39 40 40 41 41 }42 } 42 43 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 80 63 81 64 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 } 83 86 84 87 -
wooms/trunk/includes/ProductStocks.php
r3010225 r3061787 3 3 namespace WooMS; 4 4 5 use WC_Product; 5 6 use function WooMS\request; 6 7 8 use function WooMS\get_config as get_config; 9 use function WooMS\get_config_name as get_config_name; 7 10 8 11 defined( 'ABSPATH' ) || exit; // Exit if accessed directly … … 27 30 public static function init() { 28 31 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 29 48 add_action( 'wooms_assortment_sync', [ __CLASS__, 'batch_handler' ] ); 30 49 … … 37 56 add_action( 'wooms_variations_batch_end', [ __CLASS__, 'restart_after_batch' ] ); 38 57 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 ); 42 60 add_action( 'wooms_tools_sections', array( __CLASS__, 'display_state' ), 17 ); 43 61 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 ) ) { 55 69 $state = [ 56 70 'count' => 0 … … 74 88 75 89 $products = get_posts( $args ); 76 if ( empty($products) ) { 77 self::set_state( 'finish_timestamp', time() );90 91 if ( empty( $products ) ) { 78 92 return false; 79 93 } 80 94 81 $filters = [];95 $filters_by_id = []; 82 96 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 87 105 $url = 'https://api.moysklad.ru/api/remap/1.2/entity/assortment'; 88 106 … … 101 119 $data = request( $url ); 102 120 121 // var_dump($data); exit; 122 103 123 if ( empty( $data['rows'] ) ) { 104 124 return false; 105 125 } 106 126 107 108 $ids = self::process_rows($data['rows']); 109 if($ids){ 127 $ids = self::process_rows( $data['rows'] ); 128 if ( $ids ) { 110 129 $state['last_ids'] = $ids; 111 130 } 112 131 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 ) { 120 139 121 140 $ids = []; 122 141 foreach ( $rows as $row ) { 123 142 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 ); 125 145 continue; 126 146 } 127 147 128 148 if ( ! $product = wc_get_product( $product_id ) ) { 149 Helper::log_error( 'Не нашли продукт по $product_id', __CLASS__, $row ); 129 150 continue; 130 151 } … … 133 154 134 155 $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 136 157 137 158 /** … … 142 163 $product = apply_filters( 'wooms_stock_product_save', $product, $row ); 143 164 165 144 166 $ids[] = $product->save(); 145 167 } 146 168 147 169 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; 148 278 149 279 } … … 168 298 } 169 299 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 queue229 */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 236 300 237 301 public static function restart_after_batch() { 238 if (as_has_scheduled_action(self::$walker_hook_name)){302 if ( ! self::is_enable() ) { 239 303 return; 240 304 } 241 305 306 if ( as_has_scheduled_action( self::$walker_hook_name ) ) { 307 return; 308 } 309 242 310 as_schedule_single_action( time(), self::$walker_hook_name, [], 'WooMS' ); 243 }244 245 246 247 248 /**249 * check is wait250 */251 public static function is_wait() {252 if ( self::get_state( 'finish_timestamp' ) ) {253 return true;254 }255 256 return false;257 311 } 258 312 … … 279 333 280 334 281 282 283 /**284 * set state data285 */286 335 public static function set_state( $key, $value ) { 287 336 … … 373 422 } 374 423 375 /**376 * Select type stock377 */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 }385 424 386 425 /** 387 426 * Update stock for variation 388 427 */ 389 public static function update_variation( $variation, $data_api ) {428 public static function update_variation( \WC_Product_Variation $variation, $data_api ) { 390 429 if ( self::is_enable() ) { 391 430 $variation->update_meta_data( self::$walker_hook_name, 1 ); … … 393 432 $variation->set_catalog_visibility( 'visible' ); 394 433 $variation->set_stock_status( 'instock' ); 395 $variation->set_manage_stock( 'no');434 $variation->set_manage_stock( false ); 396 435 $variation->set_status( 'publish' ); 397 436 } … … 410 449 $product->set_catalog_visibility( 'visible' ); 411 450 $product->set_stock_status( 'instock' ); 412 $product->set_manage_stock( 'no');451 $product->set_manage_stock( false ); 413 452 $product->set_status( 'publish' ); 414 453 } … … 438 477 ); 439 478 440 register_setting( 'mss-settings', 'wooms_stocks_without_reserve' );441 479 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 }, 445 486 $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 // ); 466 511 467 512 self::add_setting_warehouse_id(); … … 482 527 $url = 'entity/store'; 483 528 $data = request( $url ); 484 if ( empty ( $data['rows'] ) ) {529 if ( empty ( $data['rows'] ) ) { 485 530 echo 'Система не смогла получить список складов из МойСклад'; 486 531 return; … … 547 592 } 548 593 549 /**550 * display_field_wooms_stocks_without_reserve551 */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 }557 594 558 595 /** … … 594 631 } 595 632 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 ) ) ?? 'Нет данных'; 600 635 601 636 $strings[] = sprintf( 'Очередь задач: <a href="%s">открыть</a>', admin_url( 'admin.php?page=wc-status&tab=action-scheduler&s=wooms_assortment_sync&orderby=schedule&order=desc' ) ); 602 637 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' ) ); 609 639 610 640 ?> 611 641 <h2>Остатки</h2> 612 642 <div class="wrap"> 613 <div id="message" class="notice notice-warning"> 614 <?php615 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 620 650 </div> 621 651 -
wooms/trunk/includes/ProductVariable.php
r2989239 r3061787 4 4 5 5 use function WooMS\request; 6 6 7 7 8 … … 13 14 */ 14 15 class ProductVariable { 16 15 17 /** 16 18 * Save state in DB … … 27 29 public static $walker_hook_name = 'wooms_variables_walker_batch'; 28 30 29 30 /**31 * The init32 */33 31 public static function init() { 34 32 35 //walker36 33 add_action( 'wooms_variables_walker_batch', [__CLASS__, 'walker'] ); 37 34 … … 71 68 ]; 72 69 73 self::set_state( $state ); 70 74 71 } 75 72 … … 81 78 $url = add_query_arg( $state['query_arg'], $url ); 82 79 83 $filters = []; 80 $filters = [ 81 'archived=false' 82 ]; 84 83 85 84 $filters = apply_filters( 'wooms_url_get_variants_filter', $filters ); … … 116 115 $state['count'] += $i; 117 116 $state['query_arg']['offset'] += count( $data['rows'] ); 118 self::set_state( $state ); 117 119 118 120 119 do_action( 'wooms_variations_batch_end' ); … … 124 123 return true; 125 124 } 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__ ); 132 127 return false; 133 128 } … … 142 137 foreach ( $rows as $key => $row ) { 143 138 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__ ); 145 150 continue; 146 151 } 147 148 $i++;149 150 self::update_variation( $row );151 152 152 153 } … … 160 161 public static function set_wait() { 161 162 as_unschedule_all_actions( self::$walker_hook_name ); 162 self::set_state( 'end_timestamp', time() ); 163 163 164 } 164 165 … … 330 331 $variation->set_attributes( $attributes ); 331 332 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 ]); 338 339 339 340 return $variation; … … 350 351 351 352 if ( ! empty( $row['archived'] ) ) { 352 return null;353 return; 353 354 } 354 355 … … 358 359 359 360 $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 ); 361 362 $product_parent = wc_get_product( $product_id ); 362 363 363 364 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; 372 372 } 373 373 … … 376 376 $product_parent->save(); 377 377 378 do_action( 379 'wooms_logger_error', 380 __CLASS__, 381 sprintf( 'Снова сохранили продукт как вариативный %s', $product_id ) 382 ); 378 Helper::log(sprintf( 'Снова сохранили продукт как вариативный %s', $product_id ), __CLASS__); 383 379 } 384 380 … … 433 429 434 430 $variation = apply_filters( 'wooms_variation_save', $variation, $row, $product_id ); 431 $variation = apply_filters( 'wooms_variation_update', $variation, $row, $product_id ); 435 432 436 433 $variation_id = $variation->save(); … … 546 543 */ 547 544 public static function walker_finish() { 548 self::set_state( 'end_timestamp', time() ); 549 self::set_state( 'lock', 0 ); 545 550 546 551 547 do_action( 'wooms_wakler_variations_finish' ); … … 598 594 } 599 595 600 601 public static function is_wait() {602 //check run main walker603 if ( as_next_scheduled_action( 'wooms_products_walker_batch' ) ) {604 return true;605 }606 607 //check end pause608 if ( ! empty( self::get_state( 'end_timestamp' ) ) ) {609 return true;610 }611 612 return false;613 }614 615 616 617 /**618 * display_state619 */620 596 public static function display_state() { 621 597 … … 644 620 645 621 } 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 } 650 625 651 626 $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' ) ); 652 627 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' ) ); 659 629 660 630 ?> … … 767 737 } 768 738 769 770 771 /**772 * get state data773 */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 data793 */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 814 739 /** 815 740 * show wooms_id for variation in admin -
wooms/trunk/includes/Products.php
r2989239 r3061787 5 5 use function WooMS\request; 6 6 use function Testeroid\ddcli; 7 use Error, Throwable, WC_Product ;7 use Error, Throwable, WC_Product, WooMS\Helper; 8 8 9 9 defined( 'ABSPATH' ) || exit; … … 61 61 62 62 $filters = [ 63 // 'pathName~=Диваны',63 'archived=false' 64 64 ]; 65 65 … … 104 104 105 105 function 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; 111 112 } 112 113 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; 132 120 } 133 121 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 } 146 126 } 147 127 … … 223 203 $product_id = 0; 224 204 225 $product_id = get_product_id_by_uuid( $row['id'] );205 $product_id = Helper::get_product_id_by_uuid( $row['id'] ); 226 206 227 207 if ( ! empty( $row['archived'] ) ) { … … 248 228 249 229 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 256 232 return false; 257 233 } … … 264 240 $data_api = $row; 265 241 266 $product->update_meta_data( 'wooms_id_' . $row['id'], 1 );267 268 /**269 * Хук позволяет работать с методами WC_Product270 * Сохраняет в БД все изменения за 1 раз271 * Снижает нагрузку на БД272 *273 * DEPRECATED274 */275 $product = apply_filters( 'wooms_product_save', $product, $data_api, $product_id );276 242 277 243 //save data of source … … 290 256 291 257 $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 295 258 $product->update_meta_data( 'wooms_updated_from_api', $data_api['updated'] ); 296 259 … … 337 300 } 338 301 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 */ 340 310 $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' ); 347 312 348 313 $product = apply_filters( 'wooms_product_update', $product, $row, $data ); … … 350 315 $product_id = $product->save(); 351 316 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__); 357 318 358 319 return $product_id; … … 475 436 'timestamp' => $now, 476 437 'query_arg' => $query_arg_default, 477 'end_timestamp' => 0,478 438 ]; 479 439 … … 484 444 } 485 445 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 506 446 507 447 function render_ui() { 508 printf( '<h2>%s</h2>', 'Каталог ' );448 printf( '<h2>%s</h2>', 'Каталог и базовые продукты' ); 509 449 510 450 $strings = []; … … 516 456 } else { 517 457 $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 ) ) ?? 'Нет данных'; 519 459 printf( 520 460 '<a href="%s" class="button button-primary">Запустить синхронизацию продуктов вручную</a>', … … 524 464 } 525 465 $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 526 467 527 468 foreach ( $strings as $string ) { … … 569 510 $data_meta = get_post_meta( $post->ID, 'wooms_meta', true ); 570 511 $data_updated = get_post_meta( $post->ID, 'wooms_updated', true ); 512 $wooms_updated_timestamp = get_post_meta( $post->ID, 'wooms_updated_timestamp', true ); 571 513 if ( $data_id ) { 572 514 printf( '<div>ID товара в МойСклад: <div><strong>%s</strong></div></div>', $data_id ); … … 583 525 } 584 526 527 if ( $data_updated ) { 528 printf( '<div>Дата последнего обновления из API МойСклад: <strong>%s</strong></div>', $wooms_updated_timestamp ); 529 } 530 585 531 do_action( 'wooms_display_product_metabox', $post->ID ); 586 532 } -
wooms/trunk/includes/ProductsCategories.php
r2989239 r3061787 163 163 } 164 164 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; 166 168 167 169 update_term_meta( $term_id, 'wooms_id', $row['id'] ); -
wooms/trunk/includes/ProductsHiding.php
r2842491 r3061787 2 2 3 3 namespace WooMS\ProductsHider; 4 5 use WooMS\Helper; 4 6 5 7 const HOOK_NAME = 'wooms_schedule_clear_old_products_walker'; … … 43 45 $ids[] = $product_id; 44 46 45 if ($product->get_type() == 'variable') { 46 // $product->set_manage_stock('yes'); 47 } 47 $product->set_status('draft'); 48 48 49 49 $product->set_catalog_visibility('hidden'); 50 50 $product->save(); 51 51 52 do_action( 53 'wooms_logger', 54 __NAMESPACE__, 55 sprintf('Скрытие продукта: %s', $product_id) 56 ); 52 Helper::log(sprintf('Скрытие продукта: %s', $product_id), __NAMESPACE__); 53 57 54 } 58 55 … … 102 99 } 103 100 101 104 102 $args = array( 105 'post_type' => ['product', 'product_variation'], 103 'post_type' => ['product'], 104 'post_status' => 'publish', 106 105 'numberposts' => 30, 107 106 'fields' => 'ids', 107 108 108 'tax_query' => array( 109 109 array( … … 162 162 $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')); 163 163 164 $strings[] = sprintf( 'Журнал обработки: <a href="%s">открыть</a>', admin_url( 'admin.php?page=wc-status&tab=logs&source=WooMS-ProductsHider' ) ); 165 164 166 echo '<h2>Скрытие продуктов</h2>'; 165 167 foreach ($strings as $string) { -
wooms/trunk/includes/Settings.php
r2979725 r3061787 3 3 namespace WooMS; 4 4 5 if ( !defined('ABSPATH')) {5 if ( ! defined( 'ABSPATH' ) ) { 6 6 exit; // Exit if accessed directly 7 7 } … … 10 10 const OPTIONS_PAGE = 'mss-settings'; 11 11 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); 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 /** 21 * Get name of form field by key 22 */ 23 function get_config_name( $key ) { 24 25 return OPTION_KEY . '[' . $key . ']'; 26 } 27 28 function set_config( $key, $value ) { 29 $config = get_option( OPTION_KEY, [] ); 30 $config[ $key ] = $value; 31 return update_option( OPTION_KEY, $config, false ); 24 32 } 25 33 … … 28 36 * Settings 29 37 */ 30 class Settings 31 { 38 class Settings { 32 39 33 40 /** 34 41 * The Init 35 42 */ 36 public static function init() 37 { 43 public static function init() { 38 44 39 45 add_action( … … 54 60 'manage_options', 55 61 'mss-settings', 56 array (__CLASS__, 'display_settings')62 array ( __CLASS__, 'display_settings' ) 57 63 ); 58 64 }, … … 60 66 ); 61 67 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() { 70 76 71 77 $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/', 'Вход в МойСклад' ), 75 82 ]; 76 83 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' ); 95 110 add_settings_field( 96 111 $id = 'woomss_login', 97 112 $title = 'Логин (admin@...)', 98 $callback = array( __CLASS__, 'display_form_login',),113 $callback = array( __CLASS__, 'display_form_login', ), 99 114 $page = 'mss-settings', 100 115 $section = 'woomss_section_login' 101 116 ); 102 117 103 register_setting( 'mss-settings', 'woomss_pass');118 register_setting( 'mss-settings', 'woomss_pass' ); 104 119 add_settings_field( 105 120 $id = 'woomss_pass', 106 121 $title = 'Пароль', 107 $callback = array( __CLASS__, 'display_form_pass'),122 $callback = array( __CLASS__, 'display_form_pass' ), 108 123 $page = 'mss-settings', 109 124 $section = 'woomss_section_login' … … 114 129 * display_form_pass 115 130 */ 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' ) ); 119 133 } 120 134 … … 122 136 * display_form_login 123 137 */ 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>', 'Вводить нужно только логин и пароль здесь. На стороне МойСклад ничего настраивать не нужно.' ); 129 142 } 130 143 … … 132 145 * Settings - Other 133 146 */ 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' ); 139 151 add_settings_field( 140 152 $id = 'wooms_use_uuid', 141 153 $title = 'Использование UUID', 142 $callback = array( __CLASS__, 'display_field_wooms_use_uuid'),154 $callback = array( __CLASS__, 'display_field_wooms_use_uuid' ), 143 155 $page = 'mss-settings', 144 156 $section = 'woomss_section_other' 145 157 ); 146 158 147 register_setting( 'mss-settings', 'wooms_replace_title');159 register_setting( 'mss-settings', 'wooms_replace_title' ); 148 160 add_settings_field( 149 161 $id = 'wooms_replace_title', 150 162 $title = 'Замена заголовка при обновлении', 151 $callback = array( __CLASS__, 'display_wooms_replace_title'),163 $callback = array( __CLASS__, 'display_wooms_replace_title' ), 152 164 $page = 'mss-settings', 153 165 $section = 'woomss_section_other' 154 166 ); 155 167 156 register_setting( 'mss-settings', 'wooms_replace_description');168 register_setting( 'mss-settings', 'wooms_replace_description' ); 157 169 add_settings_field( 158 170 $id = 'wooms_replace_description', 159 171 $title = 'Замена описания при обновлении', 160 $callback = array( __CLASS__, 'display_wooms_replace_desc'),172 $callback = array( __CLASS__, 'display_wooms_replace_desc' ), 161 173 $page = 'mss-settings', 162 174 $section = 'woomss_section_other' … … 167 179 * display_wooms_replace_desc 168 180 */ 169 public static function display_wooms_replace_desc() 170 { 181 public static function display_wooms_replace_desc() { 171 182 172 183 $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 ?> 175 186 <p> 176 187 <small>Если включить опцию, то плагин будет обновлять описание продукта из МойСклад всегда.</small> 177 188 </p> 178 <?php189 <?php 179 190 180 191 } … … 183 194 * display_wooms_replace_title 184 195 */ 185 public static function display_wooms_replace_title() 186 { 196 public static function display_wooms_replace_title() { 187 197 188 198 $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 ?> 191 201 <p> 192 <small>Если включить опцию, то плагин будет обновлять заголовки продукта из МойСклад. Иначе при наличии заголовока он не будет обновлен.</small> 202 <small>Если включить опцию, то плагин будет обновлять заголовки продукта из МойСклад. Иначе при наличии заголовока 203 он не будет обновлен.</small> 193 204 </p> 194 <?php205 <?php 195 206 196 207 } … … 199 210 * display_field_wooms_use_uuid 200 211 */ 201 public static function display_field_wooms_use_uuid() 202 { 212 public static function display_field_wooms_use_uuid() { 203 213 204 214 $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 ?> 207 217 208 218 <p><strong>Если товары не попадают из МойСклад на сайт - попробуйте включить эту опцию.</strong></p> 209 219 <p> 210 <small>По умолчанию используется связь продуктов по артикулу. Это позволяет обеспечить синхронизацию без удаления всех продуктов с сайта при их наличии. Но без артикула 211 товары не будут синхронизироваться. Если товаров на сайте нет, либо их можно удалить без вреда, то можно включить синхронизацию по UUID. В этом случае артикулы 220 <small>По умолчанию используется связь продуктов по артикулу. Это позволяет обеспечить синхронизацию без удаления 221 всех продуктов с сайта при их наличии. Но без артикула 222 товары не будут синхронизироваться. Если товаров на сайте нет, либо их можно удалить без вреда, то можно 223 включить синхронизацию по UUID. В этом случае артикулы 212 224 будут не нужны. <br />При создании записи о продукте произойдет связка по UUID (meta_key = wooms_id) 213 225 </small> 214 226 </p> 215 <?php227 <?php 216 228 217 229 } … … 220 232 * display_settings 221 233 */ 222 public static function display_settings() 223 { 224 225 ?> 234 public static function display_settings() { 235 236 ?> 226 237 <form method="POST" action="options.php"> 227 238 228 239 <h1>Настройки интеграции МойСклад</h1> 229 240 230 <?php do_action( 'wooms_settings_after_header') ?>241 <?php do_action( 'wooms_settings_after_header' ) ?> 231 242 232 243 <?php 233 244 234 settings_fields( 'mss-settings');235 do_settings_sections( 'mss-settings');245 settings_fields( 'mss-settings' ); 246 do_settings_sections( 'mss-settings' ); 236 247 submit_button(); 237 248 ?> … … 239 250 240 251 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" ); 248 256 } 249 257 } -
wooms/trunk/readme.txt
r3010824 r3061787 1 1 === WooMS === 2 2 Contributors: casepress 3 Donate link: https://wpcraft.ru/p roduct/wooms-extra/3 Donate link: https://wpcraft.ru/pay/ 4 4 Tags: moysklad, woocommerce, sync, integration 5 5 Requires at least: 6.0 … … 24 24 * Гибкие настройки 25 25 26 [Руководство по быстрому началу работы](https:// github.com/wpcraft-ru/wooms/wiki/GettingStarted)26 [Руководство по быстрому началу работы](https://wpcraft.ru/wooms/) 27 27 28 28 Исходники для желающих принять участие в разработке: [https://github.com/wpcraft-ru/wooms/](https://github.com/wpcraft-ru/wooms/) … … 77 77 == Changelog == 78 78 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 79 85 = 9.10 = 80 86 - Исправлена ошибка с версией 81 - Обнов дены авто тесты87 - Обновлены авто тесты 82 88 83 89 = 9.9 = -
wooms/trunk/wooms.php
r3010824 r3061787 20 20 * WC tested up to: 8.4.0 21 21 * 22 * Version: 9.1 022 * Version: 9.11 23 23 */ 24 24 … … 26 26 27 27 // Exit if accessed directly 28 defined( 'ABSPATH') || exit;28 defined( 'ABSPATH' ) || exit; 29 29 30 30 /** 31 31 * Add hook for activate plugin 32 32 */ 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 } );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 } ); 40 40 41 41 42 42 require_once __DIR__ . '/includes/functions.php'; 43 43 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){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) { 61 61 $mng_link = '<a href="admin.php?page=moysklad">Управление</a>'; 62 62 $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 } ); 67 67 68 68 … … 70 70 * сообщяем про то что Extra плагин более не актуален 71 71 */ 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');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' ); 75 75 76 76 printf( 77 '<tr class="plugin-update-tr">77 '<tr class="plugin-update-tr"> 78 78 <td colspan="%s" class="plugin-update update-message notice inline notice-warning notice-alt"> 79 79 <div class="update-message"> … … 82 82 </td> 83 83 </tr>', 84 $wp_list_table->get_column_count()84 $wp_list_table->get_column_count() 85 85 ); 86 }, 10, 2 );87 add_filter( 'wooms_xt_load', '__return_false');86 }, 10, 2 ); 87 add_filter( 'wooms_xt_load', '__return_false' ); 88 88 89 89 … … 91 91 * Add GettingStarted link in row meta at pligins list 92 92 */ 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; 93 function 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; 106 105 } 107 106 … … 112 111 * @return void 113 112 */ 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){ 113 function 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 121 function get_api_url( $path ) { 124 122 return $url = 'https://api.moysklad.ru/api/remap/1.2/' . $path; 125 123 } 126 124 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 } 125 function 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 209 function 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 */ 218 add_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.