Plugin Directory

Changeset 3395106


Ignore:
Timestamp:
11/13/2025 02:43:56 PM (5 months ago)
Author:
shelfplanner
Message:

2.8.2

  • Even more improvements in security and logging functionalities
Location:
shelf-planner/trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • shelf-planner/trunk/block.json

    r3393802 r3395106  
    33    "apiVersion": 3,
    44    "name": "extension/shelf-planner",
    5     "version": "2.8.1",
     5    "version": "2.8.2",
    66    "title": "Stock Management for WooCommerce",
    77    "category": "widgets",
  • shelf-planner/trunk/includes/shelf_planner_connector.php

    r3393802 r3395106  
    337337        function add_product_stock($data)
    338338        {
     339            $this->debug("add_product_stock call parameters:" . json_encode($data->get_json_params()));
    339340            $product = wc_get_product($data['ProductId']);
    340341            if (!$product) {
     
    352353        function update_product_stock($data)
    353354        {
     355            $this->debug("update_product_stock call parameters:" . json_encode($data->get_json_params()));
    354356            $product = wc_get_product($data['ProductId']);
    355357            if (!$product) {
     
    379381        {
    380382            // Validate request auth
    381             $this->debug("GetCategoryList call parameters:" . json_encode($data->get_json_params()));
     383            $this->debug("get_categories_list call parameters:" . json_encode($data->get_json_params()));
    382384            $taxonomy = 'product_cat';
    383385            $orderby = 'name';
     
    436438        {
    437439            // Validate request auth
    438             $this->debug("GetProductList call parameters:" . json_encode($data->get_json_params()));
     440            $this->debug("get_products_id call parameters:" . json_encode($data->get_json_params()));
    439441            global $wpdb;
    440442
     
    473475        {
    474476            // Validate request auth
    475             $this->debug("GetOrderList call parameters:" . json_encode($data->get_json_params()));
     477            $this->debug("get_orders_id call parameters:" . json_encode($data->get_json_params()));
    476478            global $wpdb;
    477479
     
    518520        }
    519521
    520         function get_orders_detail($request)
    521         {
    522             $this->debug("GetOrderDetail call");
    523             $params = $request->get_params(); // Ottieni i parametri passati nella richiesta POST
     522        function get_orders_detail($data)
     523        {
     524            $this->debug("get_orders_detail call parameters:" . json_encode($data->get_json_params()));
     525            $params = $data->get_params(); // Ottieni i parametri passati nella richiesta POST
    524526            $tmpOrders = [];
    525527            foreach ($params['IDS'] as $order_id) {
     
    616618        function get_products_detail($data)
    617619        {
    618             $this->debug("GetProductDetail call parameters:" . json_encode($data->get_json_params()));
     620            $this->debug("get_products_detail call parameters:" . json_encode($data->get_json_params()));
    619621            $ar_return = [];
    620622            foreach ($data['IDS'] as $product_id) {
     
    673675        }
    674676
     677        function ping($data)
     678        {
     679            return "pong";
     680        }
     681
     682        function validate_request_auth_website_url($data)
     683        {
     684            // Verify WebsiteUrl validity
     685            if ($this->get_website_url() != $data['WebsiteUrl']) {
     686                $this->warning("ERROR SITE: doesn't match ");
     687                return false;
     688            }
     689
     690            return true;
     691        }
     692
     693        function validate_request_auth_website_url_server_key($data)
     694        {
     695            // Verify WebsiteUrl validity
     696            if (!$this->validate_request_auth_website_url($data)) {
     697                return false;
     698            }
     699
     700            // Verify ServerKey validity
     701            if ($this->get_server_key() != $data['ServerKey']) {
     702                $this->warning("ERROR SERVER: doesn't match ");
     703                return false;
     704            }
     705
     706            return true;
     707        }
     708
     709        function validate_request_auth($data)
     710        {
     711            // Verify WebsiteUrl and ServerKey validity
     712            if (!$this->validate_request_auth_website_url_server_key($data)) {
     713                return false;
     714            }
     715
     716            // Verify LicenseKey validity
     717            if ($this->get_license_key() != $data['LicenseKey']) {
     718                $this->warning("ERROR LICENSE doesn't match ");
     719                return false;
     720            }
     721
     722            return true;
     723        }
     724
     725        function setup_connector($data)
     726        {
     727            // Set licenseKey
     728            $this->set_license_key($data['LicenseKey']);
     729        }
     730
     731        function connector_product_update($product_id, $product)
     732        {
     733            if (!$this->has_license_key()) {
     734                return;
     735            }
     736
     737            $updating_product_id = 'update_product_' . $product_id;
     738            if (false === ($updating_product = get_transient($updating_product_id))) {
     739                set_transient($updating_product_id, $product_id, 2); // change 2 seconds if not enough
     740                $this->debug('PRODUCT UPDATED! PRODUCT_ID: ' . $product_id);
     741                $this->send_product_update_sync_request($product_id);
     742            }
     743        }
     744
     745        function connector_order_completed($order_id)
     746        {
     747            if (!$this->has_license_key()) {
     748                return;
     749            }
     750
     751            $updating_order_id = 'update_order_' . $order_id;
     752            if (false === ($updating_order = get_transient($updating_order_id))) {
     753                set_transient($updating_order_id, $order_id, 2); // change 2 seconds if not enough
     754                $this->debug('ORDER COMPLETED! ORDER_ID: ' . $order_id);
     755                $this->send_order_completed_sync_request($order_id);
     756            }
     757        }
     758
     759        /**
     760         * Logs messages if WP_DEBUG is enabled.
     761         *
     762         * @param mixed  $data  Data to log.
     763         * @param string $level Log level (debug, info, warning, error).
     764         */
     765        public function log($data, $level = 'info')
     766        {
     767            $log_enabled = get_option($this->config->get_domain() . '_enable_logs', 'checked');
     768            if ('checked' == $log_enabled) {
     769                $message = $data;
     770                if (strpos($message, 'serverKey') !== false || strpos($message, 'ServerKey') !== false) {
     771                    $message = preg_replace('/"[Ss]erver[Kk]ey":\s*"[^"]*"/', '"ServerKey":"ANON"', $message);
     772                }
     773                if (strpos($message, 'licenseKey') !== false || strpos($message, 'LicenseKey') !== false) {
     774                    $message = preg_replace('/"[Ll]icense[Kk]ey":\s*"[^"]*"/', '"LicenseKey":"ANON"', $message);
     775                }
     776                $log_file = $this->get_log_file_path(gmdate('Y-m-d'), true);
     777                $message = gmdate('[Y.m.d H:i:s]') . ' [' . strtoupper($level) . '] ' . $message . PHP_EOL;
     778                file_put_contents($log_file, $message, FILE_APPEND);
     779            }
     780        }
     781
    675782        function get_logs($data)
    676783        {
    677             $logs_filename = $data["LogsDate"] . ".log";
    678             $log_file_path = $this->config->get_log_path() . $logs_filename;
    679 
    680             if (file_exists($log_file_path)) {
     784            $logs_filename = $data["LogsDate"] . '.log';
     785            $log_file = $this->get_log_file_path($data["LogsDate"]);
     786
     787            if (file_exists($log_file)) {
    681788                global $wp_filesystem;
    682789                // create a file interaction object, if it is not already created
     
    686793                }
    687794
    688                 $contents = $wp_filesystem->get_contents($log_file_path);
     795                $contents = $wp_filesystem->get_contents($log_file);
    689796                if (!$contents) {
    690797                    return "Log file read error for date: " . $data["LogsDate"];
     
    700807        }
    701808
    702         function ping($data)
    703         {
    704             return "pong";
    705         }
    706 
    707         function validate_request_auth_website_url($data)
    708         {
    709             // Verify WebsiteUrl validity
    710             if ($this->get_website_url() != $data['WebsiteUrl']) {
    711                 $this->warning("ERROR SITE: doesn't match ");
    712                 return false;
    713             }
    714 
    715             return true;
    716         }
    717 
    718         function validate_request_auth_website_url_server_key($data)
    719         {
    720             // Verify WebsiteUrl validity
    721             if (!$this->validate_request_auth_website_url($data)) {
    722                 return false;
    723             }
    724 
    725             // Verify ServerKey validity
    726             if ($this->get_server_key() != $data['ServerKey']) {
    727                 $this->warning("ERROR SERVER: doesn't match ");
    728                 return false;
    729             }
    730 
    731             return true;
    732         }
    733 
    734         function validate_request_auth($data)
    735         {
    736             // Verify WebsiteUrl and ServerKey validity
    737             if (!$this->validate_request_auth_website_url_server_key($data)) {
    738                 return false;
    739             }
    740 
    741             // Verify LicenseKey validity
    742             if ($this->get_license_key() != $data['LicenseKey']) {
    743                 $this->warning("ERROR LICENSE doesn't match ");
    744                 return false;
    745             }
    746 
    747             return true;
    748         }
    749 
    750         function setup_connector($data)
    751         {
    752             // Set licenseKey
    753             $this->set_license_key($data['LicenseKey']);
    754         }
    755 
    756         function connector_product_update($product_id, $product)
    757         {
    758             if (!$this->has_license_key()) {
    759                 return;
    760             }
    761 
    762             $updating_product_id = 'update_product_' . $product_id;
    763             if (false === ($updating_product = get_transient($updating_product_id))) {
    764                 set_transient($updating_product_id, $product_id, 2); // change 2 seconds if not enough
    765                 $this->debug('PRODUCT UPDATED! PRODUCT_ID: ' . $product_id);
    766                 $this->send_product_update_sync_request($product_id);
    767             }
    768         }
    769 
    770         function connector_order_completed($order_id)
    771         {
    772             if (!$this->has_license_key()) {
    773                 return;
    774             }
    775 
    776             $updating_order_id = 'update_order_' . $order_id;
    777             if (false === ($updating_order = get_transient($updating_order_id))) {
    778                 set_transient($updating_order_id, $order_id, 2); // change 2 seconds if not enough
    779                 $this->debug('ORDER COMPLETED! ORDER_ID: ' . $order_id);
    780                 $this->send_order_completed_sync_request($order_id);
    781             }
    782         }
    783 
    784         /**
    785          * Logs messages if WP_DEBUG is enabled.
    786          *
    787          * @param mixed  $data  Data to log.
    788          * @param string $level Log level (debug, info, warning, error).
    789          */
    790         public function log($data, $level = 'info')
    791         {
    792             $log_enabled = get_option($this->config->get_domain() . '_enable_logs', 'checked');
    793             if ('checked' == $log_enabled) {
    794                 $log_file = $this->config->get_log_path() . gmdate('Y-m-d') . '.log';
    795 
    796                 $message = $data;
    797 
    798                 if (strpos($message, 'serverKey') !== false || strpos($message, 'ServerKey') !== false) {
    799                     $message = preg_replace('/"[Ss]erver[Kk]ey":\s*"[^"]*"/', '"ServerKey":"ANON"', $message);
    800                 }
    801                 if (strpos($message, 'licenseKey') !== false || strpos($message, 'LicenseKey') !== false) {
    802                     $message = preg_replace('/"[Ll]icense[Kk]ey":\s*"[^"]*"/', '"LicenseKey":"ANON"', $message);
    803                 }
    804                 $message = gmdate('[d.m.Y H:i:s]') . ' [' . strtoupper($level) . '] ' . $message . PHP_EOL;
    805                 file_put_contents($log_file, $message, FILE_APPEND);
    806             }
     809        public function get_log_file_path($log_date, $create_if_not_exists = false)
     810        {
     811            $log_files_dictionary = get_option($this->config->get_domain() . '_logs_dictionary');
     812
     813            if (
     814                !$create_if_not_exists &&
     815                (!isset($log_files_dictionary) || !is_array($log_files_dictionary) || !isset($log_files_dictionary[$log_date]))
     816            ) {
     817                return null;
     818            }
     819
     820            if ($create_if_not_exists && (!isset($log_files_dictionary) || !is_array($log_files_dictionary))) {
     821                $log_files_dictionary = array();
     822            }
     823
     824            if (!isset($log_files_dictionary[$log_date])) {
     825
     826                $log_files_dictionary[$log_date] = $this->config->get_log_path() . wp_generate_uuid4() . '.log';
     827                update_option($this->config->get_domain() . '_logs_dictionary', $log_files_dictionary);
     828            }
     829
     830            return $log_files_dictionary[$log_date];
    807831        }
    808832
  • shelf-planner/trunk/readme.txt

    r3393802 r3395106  
    44Tested up to: 6.8
    55Requires PHP: 8.0
    6 Stable tag: 2.8.1
     6Stable tag: 2.8.2
    77Tags: Inventory Management,ABC Analysis,Demand Forecasting,Replenishment,Purchasing
    88License: GPLv2 or later
     
    1717== Main Features ==
    1818
     19- **Inventory Management** - Bridge the gap between demand and supply planning with data-driven insights.
    1920- **AI Demand forecasting** - Predict future sales with machine learning - no spreadsheets required.
    20 - **Sales Forecasting** - Get weekly, monthly, and seasonal sales forecasts to plan inventory and promotions with confidence.
     21- **Sales Forecasting** - Leverage powerful AI algorithms for demand forecasting, drawing insights from past sales and seasonal patterns.
    2122- **Automated replenishment** - Get instant order proposals tailored to your store’s demand.
    2223- **Stock Projections** - Plan ahead with forecasts that account for incoming stock and transfers.
     
    2930- **WPML & Multi-currency Ready** - Perfect for international stores with multi-language and currency support.
    3031
    31 ####Automate Stock Replenishment
     32###Inventory Management
     33- Don't take the stockout risk and automate your stock management with Shelf Planner.
     34- Make more sales with higher product availability by ordering the right quantities before it's too late
     35
     36###Automate Stock Replenishment
    3237- Get live order proposals for all your products based on your customer's demand.
    3338- Order Proposals based on true customer demand.
    3439
    35 ####Avoid Lost Sales and stock-outs
     40###Avoid Lost Sales and stock-outs
    3641- Avoid lost sales and missed opportunities by understanding what to order, when.
    3742- Get alerts so you don't lose sales due to stock-outs.
    3843- Understand where your business is going and take better decisions when managing your stock.
    3944
    40 ####Automate your purchasing processes
     45###Automate your purchasing processes
    4146- Get order proposals based on true customer demand and create purchase orders directly from the extension.
    4247- Automatically update your store's stock with the built in Purchase Order tracking
    4348
    44 ####Boost Profitability of your store
     49###Boost Profitability of your store
    4550- Track and monitor the costs and profits of your products and see the impact on your store’s profitability.
    4651- See both your gross margin targets and achieved net margins
    4752
    48 ####Pricing & Free Trial
     53###Pricing & Free Trial
    4954- **Free 3-Month Trial:** Test all features with no commitment.
    5055- **Flexible Plans:** Scale up as your business grows.
     
    131136== Changelog ==
    132137
     138= 2.8.2 =
     139- Even more improvements in security and logging functionalities — mostly to survive another day in a PHP world.
     140
    133141= 2.8.1 =
    134 * Additional improvements in security and logging functionalities
     142- Additional improvements in security and logging functionalities
    135143
    136144= 2.8.0 =
    137 * Improvement in security and logging functionalities
    138 * Added support for website with strict security settings on http verbs
     145- Improvement in security and logging functionalities
     146- Added support for website with strict security settings on http verbs
    139147
    140148= 2.7.0 =
  • shelf-planner/trunk/shelf-planner.php

    r3393802 r3395106  
    1010 * Description:         AI-driven Stock Management, Demand Forecasting, Replenishment and Order Management for WooCommerce, all in one powerful tool.
    1111 *
    12  * Version:             2.8.1
     12 * Version:             2.8.2
    1313 * Author:              Shelf Planner
    1414 * Author URI:          https://www.shelfplanner.com
     
    2626
    2727if (!defined('SPC_WP__VERSION')) {
    28     define('SPC_WP__VERSION', '2.8.1');
     28    define('SPC_WP__VERSION', '2.8.2');
    2929}
    3030
Note: See TracChangeset for help on using the changeset viewer.