Plugin Directory

Changeset 3392161


Ignore:
Timestamp:
11/08/2025 12:21:10 PM (5 months ago)
Author:
muchatai
Message:

Update to version 2.0.50 from GitHub

Location:
muchat-ai
Files:
4 added
10 edited
1 copied

Legend:

Unmodified
Added
Removed
  • muchat-ai/tags/2.0.50/includes/Api/Controllers/ProductController.php

    r3385145 r3392161  
    4848            // Get required parameters
    4949            $modified_after = $request->get_param('modified_after');
     50            $muchat_modified_after = $request->get_param('muchat_modified_after');
    5051            $order_by = $request->get_param('order_by');
    5152            $order = $request->get_param('order');
     
    5960            $params = [
    6061                'modified_after' => $modified_after,
     62                'muchat_modified_after' => $muchat_modified_after,
    6163                'order_by' => $order_by,
    6264                'order' => $order,
     
    187189
    188190            $modified_after = $request->get_param('modified_after');
     191            $muchat_modified_after = $request->get_param('muchat_modified_after');
    189192
    190193            // Start output buffering to catch any unexpected output
    191194            ob_start();
    192             $result = $this->product_model->get_product_ids($modified_after);
     195            $result = $this->product_model->get_product_ids($modified_after, $muchat_modified_after);
    193196            $unexpected_output = ob_get_clean();
    194197
  • muchat-ai/tags/2.0.50/includes/Api/Routes.php

    r3300525 r3392161  
    44
    55use Muchat\Api\Api\Controllers\ProductController;
     6use Muchat\Api\Api\Controllers\ProductInitController;
    67use Muchat\Api\Api\Controllers\PostController;
    78use Muchat\Api\Api\Controllers\PageController;
     
    2021     */
    2122    private $product_controller;
     23
     24    /**
     25     * @var ProductInitController
     26     */
     27    private $product_init_controller;
    2228
    2329    /**
     
    5561    ) {
    5662        $this->product_controller = $product_controller;
     63        $this->product_init_controller = new ProductInitController();
    5764        $this->post_controller = $post_controller;
    5865        $this->page_controller = $page_controller;
     
    8693                    'path' => '/product-ids',
    8794                    'callback' => [$this->product_controller, 'get_product_ids'],
     95                    'methods' => \WP_REST_Server::CREATABLE
     96                ],
     97                [
     98                    'path' => '/products/initialize-muchat-tracking',
     99                    'callback' => [$this->product_init_controller, 'initialize_products'],
    88100                    'methods' => \WP_REST_Server::CREATABLE
    89101                ],
     
    176188                }
    177189            ],
     190            'muchat_modified_after' => [
     191                'description' => __('Limit results to items with muchat_date_modified after specified date (only price/stock changes).', 'muchat-ai'),
     192                'type' => 'string',
     193                'validate_callback' => function ($param) {
     194                    return strtotime($param) !== false;
     195                }
     196            ],
    178197            'in_stock' => [
    179198                'description' => __('Filter to show only in-stock products (product-specific).', 'muchat-ai'),
  • muchat-ai/tags/2.0.50/includes/Models/Product.php

    r3380443 r3392161  
    1111     *     Optional. Array of parameters.
    1212     *
    13      *     @type int    $skip           Number of items to skip
    14      *     @type int    $take           Number of items to take
    15      *     @type string $modified_after Only include items modified after this date
    16      *     @type string $order_by       Field(s) to order by. Can be a single field or comma-separated list (e.g., "modified,ID")
    17      *     @type string $order          Sort order (ASC or DESC)
    18      *     @type string $in_stock       Whether to include only in-stock products (product-specific)
     13     *     @type int    $skip                  Number of items to skip
     14     *     @type int    $take                  Number of items to take
     15     *     @type string $modified_after        Only include items modified after this date
     16     *     @type string $muchat_modified_after Only include items with muchat modified after this date
     17     *     @type string $order_by              Field(s) to order by. Can be a single field or comma-separated list (e.g., "modified,ID")
     18     *     @type string $order                 Sort order (ASC or DESC)
     19     *     @type string $in_stock              Whether to include only in-stock products (product-specific)
    1920     * }
    2021     * @return array
     
    2930        ];
    3031
    31         // Handle ordering
    32         if (isset($params['order_by'])) {
    33             // Check if order_by is a comma-separated string (e.g. "modified,ID")
    34             if (is_string($params['order_by']) && strpos($params['order_by'], ',') !== false) {
    35                 $orderby_fields = explode(',', $params['order_by']);
    36                 $orderby_array = [];
    37                 foreach ($orderby_fields as $field) {
    38                     $orderby_array[$field] = isset($params['order']) ? strtoupper($params['order']) : 'ASC';
    39                 }
    40 
    41                 // Add ID as secondary sort if not already included
    42                 if (!isset($orderby_array['ID'])) {
    43                     $orderby_array['ID'] = 'ASC';
    44                 }
    45 
    46                 $args['orderby'] = $orderby_array;
    47             } else {
    48                 // Single field ordering - always add ID as secondary sort
    49                 $primary_order = isset($params['order']) ? strtoupper($params['order']) : 'ASC';
    50                 $args['orderby'] = [
    51                     $params['order_by'] => $primary_order,
    52                     'ID' => 'ASC'
    53                 ];
    54             }
    55         } else {
    56             // Default ordering
    57             $args['orderby'] = array('modified' => 'ASC', 'ID' => 'ASC');
    58         }
    59 
    60         // Note: Do NOT set $args['order'] when using array-based orderby
    61         // as it will override the individual sort orders in the array
     32        // Handle ordering - Use custom SQL approach for reliability
     33        $order_by_field = isset($params['order_by']) ? $params['order_by'] : 'modified';
     34        $order_direction = isset($params['order']) ? strtoupper($params['order']) : 'ASC';
     35       
     36        // Validate order direction
     37        if (!in_array($order_direction, ['ASC', 'DESC'])) {
     38            $order_direction = 'ASC';
     39        }
     40       
     41        // Map API field names to WP post fields
     42        $field_map = [
     43            'modified' => 'post_modified',
     44            'date' => 'post_date',
     45            'title' => 'post_title',
     46            'ID' => 'ID'
     47        ];
     48       
     49        $sql_field = isset($field_map[$order_by_field]) ? $field_map[$order_by_field] : 'post_modified';
     50       
     51        // Use a custom orderby filter to ensure correct SQL
     52        add_filter('posts_orderby', function($orderby, $query) use ($sql_field, $order_direction) {
     53            // Only apply to our specific query
     54            if (isset($query->query_vars['muchat_custom_order']) && $query->query_vars['muchat_custom_order'] === true) {
     55                global $wpdb;
     56                return "{$wpdb->posts}.{$sql_field} {$order_direction}, {$wpdb->posts}.ID ASC";
     57            }
     58            return $orderby;
     59        }, 10, 2);
     60       
     61        // Mark this query so our filter can identify it
     62        $args['muchat_custom_order'] = true;
    6263
    6364        // Add date filters if provided
     
    8485        }
    8586
     87        // Add muchat_modified_after filter if provided
     88        if (!empty($params['muchat_modified_after'])) {
     89            try {
     90                // Parse the date as UTC to ensure consistency
     91                $date = new \DateTime($params['muchat_modified_after'], new \DateTimeZone('UTC'));
     92                $formatted_date = $date->format('Y-m-d H:i:s');
     93               
     94                if (!isset($args['meta_query'])) {
     95                    $args['meta_query'] = [];
     96                }
     97               
     98                $args['meta_query'][] = [
     99                    'key' => '_muchat_date_modified',
     100                    'value' => $formatted_date,
     101                    'compare' => '>',
     102                    'type' => 'DATETIME'
     103                ];
     104            } catch (\Exception $e) {
     105                // If date parsing fails, try with strtotime as fallback
     106                $muchat_modified_timestamp = strtotime($params['muchat_modified_after']);
     107                if ($muchat_modified_timestamp) {
     108                    if (!isset($args['meta_query'])) {
     109                        $args['meta_query'] = [];
     110                    }
     111                   
     112                    $args['meta_query'][] = [
     113                        'key' => '_muchat_date_modified',
     114                        'value' => gmdate('Y-m-d H:i:s', $muchat_modified_timestamp),
     115                        'compare' => '>',
     116                        'type' => 'DATETIME'
     117                    ];
     118                }
     119            }
     120        }
     121
    86122        // Product-specific: Add in-stock filter if requested
    87123        if (!empty($params['in_stock']) && $params['in_stock'] === 'true') {
     
    100136        $args['posts_per_page'] = $requested_limit;
    101137        $args['offset'] = $requested_offset;
     138       
     139        // Disable caching for this query to ensure fresh results
     140        $args['cache_results'] = false;
     141        $args['update_post_meta_cache'] = false;
     142        $args['update_post_term_cache'] = false;
     143        $args['no_found_rows'] = false; // We need found_posts for total_count
    102144
    103145        // Execute the final query with pagination
    104146        $query = new \WP_Query($args);
     147       
     148        // Remove the custom orderby filter to avoid affecting other queries
     149        remove_all_filters('posts_orderby', 10);
    105150
    106151        // Get total count from the same query
     
    146191     *
    147192     * @param string|null $modified_after
     193     * @param string|null $muchat_modified_after
    148194     * @return array
    149195     */
    150     public function get_product_ids($modified_after = null)
     196    public function get_product_ids($modified_after = null, $muchat_modified_after = null)
    151197    {
    152198        $args = [
     
    183229        }
    184230
     231        // Add muchat_modified_after filter
     232        if ($muchat_modified_after) {
     233            try {
     234                $date = new \DateTime($muchat_modified_after, new \DateTimeZone('UTC'));
     235                $formatted_date = $date->format('Y-m-d H:i:s');
     236               
     237                $args['meta_query'] = [
     238                    [
     239                        'key' => '_muchat_date_modified',
     240                        'value' => $formatted_date,
     241                        'compare' => '>',
     242                        'type' => 'DATETIME'
     243                    ]
     244                ];
     245            } catch (\Exception $e) {
     246                $muchat_modified_timestamp = strtotime($muchat_modified_after);
     247                if ($muchat_modified_timestamp) {
     248                    $args['meta_query'] = [
     249                        [
     250                            'key' => '_muchat_date_modified',
     251                            'value' => gmdate('Y-m-d H:i:s', $muchat_modified_timestamp),
     252                            'compare' => '>',
     253                            'type' => 'DATETIME'
     254                        ]
     255                    ];
     256                }
     257            }
     258        }
     259
    185260        // Filter to select only ID and post_modified_gmt for performance
    186261        $fields_filter = function ($fields) {
     
    196271
    197272        $products = array_map(function ($post) {
     273            $muchat_modified = \Muchat\Api\Utils\ProductChangeTracker::get_muchat_modified_date($post->ID);
    198274            return [
    199275                'id' => $post->ID,
    200                 'date_modified' => $post->post_modified_gmt
     276                'date_modified' => $post->post_modified_gmt,
     277                'muchat_date_modified' => $muchat_modified
    201278            ];
    202279        }, $query->posts);
     
    233310                    $post_data = get_post($product->get_id());
    234311                    $data['date_modified'] = isset($post_data->post_modified_gmt) ? $post_data->post_modified_gmt : null;
     312                   
     313                    // Add muchat_date_modified (tracks only price/stock changes)
     314                    $muchat_modified = \Muchat\Api\Utils\ProductChangeTracker::get_muchat_modified_date($product->get_id());
     315                    $data['muchat_date_modified'] = $muchat_modified;
    235316                    break;
    236317                case 'description':
  • muchat-ai/tags/2.0.50/muchat-ai.php

    r3385145 r3392161  
    55 * Plugin URI: https://mu.chat
    66 * Description: Muchat, a powerful tool for customer support using artificial intelligence
    7  * Version: 2.0.49
     7 * Version: 2.0.50
    88 * Author: Muchat
    99 * Text Domain: muchat-ai
     
    2727
    2828// Define plugin constants with unique prefix
    29 define('MUCHAT_AI_CHATBOT_PLUGIN_VERSION', '2.0.49');
     29define('MUCHAT_AI_CHATBOT_PLUGIN_VERSION', '2.0.50');
    3030// define('MUCHAT_AI_CHATBOT_CACHE_DURATION', HOUR_IN_SECONDS);
    3131define('MUCHAT_AI_CHATBOT_PLUGIN_FILE', __FILE__);
     
    118118}
    119119
     120// Initialize all plugin components on plugins_loaded hook for reliability
     121function muchat_ai_chatbot_initialize()
     122{
     123    // Run the main plugin
     124    muchat_ai_chatbot_run_plugin();
     125
     126    // Initialize product change tracker for WooCommerce
     127    if (class_exists('WooCommerce')) {
     128        new \Muchat\Api\Utils\ProductChangeTracker();
     129    }
     130}
     131add_action('plugins_loaded', 'muchat_ai_chatbot_initialize');
     132
    120133// Hook for plugin activation
    121134register_activation_hook(__FILE__, function () {
     
    143156}
    144157
    145 // Run the plugin
    146 muchat_ai_chatbot_run_plugin();
     158// Run the plugin - This direct call is removed and handled by the hook now.
     159// muchat_ai_chatbot_run_plugin();
  • muchat-ai/tags/2.0.50/readme.txt

    r3385145 r3392161  
    44Requires at least: 5.0
    55Tested up to: 6.8
    6 Stable tag: 2.0.49
    76Requires PHP: 7.3
     7Stable tag: 2.0.50
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    7676== Changelog ==
    7777
     78= 2.0.50 =
     79* Feat: Add `muchat_date_modified` field to products for precise tracking of price/stock changes.
     80* Feat: Add `muchat_modified_after` filter to products API endpoint.
     81* Fix: Ensure variation changes update the parent product's `muchat_date_modified`.
     82* Fix: Plugin initialization now uses `plugins_loaded` hook for better compatibility.
     83
    7884= 2.0.49 =
     85* Fix: Complete rewrite of ordering logic using custom SQL approach to ensure ASC/DESC ordering works correctly across all WordPress environments.
     86* Fix: Resolved issue where order parameter was being ignored, causing identical results regardless of sort direction.
     87* Fix: Disabled query caching to ensure fresh results are always returned.
     88* Enhancement: Added proper SQL field mapping for all order_by options (modified, date, title, ID).
    7989* Fix: Improved API response reliability by cleaning output buffers before processing.
    8090
  • muchat-ai/trunk/includes/Api/Controllers/ProductController.php

    r3385145 r3392161  
    4848            // Get required parameters
    4949            $modified_after = $request->get_param('modified_after');
     50            $muchat_modified_after = $request->get_param('muchat_modified_after');
    5051            $order_by = $request->get_param('order_by');
    5152            $order = $request->get_param('order');
     
    5960            $params = [
    6061                'modified_after' => $modified_after,
     62                'muchat_modified_after' => $muchat_modified_after,
    6163                'order_by' => $order_by,
    6264                'order' => $order,
     
    187189
    188190            $modified_after = $request->get_param('modified_after');
     191            $muchat_modified_after = $request->get_param('muchat_modified_after');
    189192
    190193            // Start output buffering to catch any unexpected output
    191194            ob_start();
    192             $result = $this->product_model->get_product_ids($modified_after);
     195            $result = $this->product_model->get_product_ids($modified_after, $muchat_modified_after);
    193196            $unexpected_output = ob_get_clean();
    194197
  • muchat-ai/trunk/includes/Api/Routes.php

    r3300525 r3392161  
    44
    55use Muchat\Api\Api\Controllers\ProductController;
     6use Muchat\Api\Api\Controllers\ProductInitController;
    67use Muchat\Api\Api\Controllers\PostController;
    78use Muchat\Api\Api\Controllers\PageController;
     
    2021     */
    2122    private $product_controller;
     23
     24    /**
     25     * @var ProductInitController
     26     */
     27    private $product_init_controller;
    2228
    2329    /**
     
    5561    ) {
    5662        $this->product_controller = $product_controller;
     63        $this->product_init_controller = new ProductInitController();
    5764        $this->post_controller = $post_controller;
    5865        $this->page_controller = $page_controller;
     
    8693                    'path' => '/product-ids',
    8794                    'callback' => [$this->product_controller, 'get_product_ids'],
     95                    'methods' => \WP_REST_Server::CREATABLE
     96                ],
     97                [
     98                    'path' => '/products/initialize-muchat-tracking',
     99                    'callback' => [$this->product_init_controller, 'initialize_products'],
    88100                    'methods' => \WP_REST_Server::CREATABLE
    89101                ],
     
    176188                }
    177189            ],
     190            'muchat_modified_after' => [
     191                'description' => __('Limit results to items with muchat_date_modified after specified date (only price/stock changes).', 'muchat-ai'),
     192                'type' => 'string',
     193                'validate_callback' => function ($param) {
     194                    return strtotime($param) !== false;
     195                }
     196            ],
    178197            'in_stock' => [
    179198                'description' => __('Filter to show only in-stock products (product-specific).', 'muchat-ai'),
  • muchat-ai/trunk/includes/Models/Product.php

    r3380443 r3392161  
    1111     *     Optional. Array of parameters.
    1212     *
    13      *     @type int    $skip           Number of items to skip
    14      *     @type int    $take           Number of items to take
    15      *     @type string $modified_after Only include items modified after this date
    16      *     @type string $order_by       Field(s) to order by. Can be a single field or comma-separated list (e.g., "modified,ID")
    17      *     @type string $order          Sort order (ASC or DESC)
    18      *     @type string $in_stock       Whether to include only in-stock products (product-specific)
     13     *     @type int    $skip                  Number of items to skip
     14     *     @type int    $take                  Number of items to take
     15     *     @type string $modified_after        Only include items modified after this date
     16     *     @type string $muchat_modified_after Only include items with muchat modified after this date
     17     *     @type string $order_by              Field(s) to order by. Can be a single field or comma-separated list (e.g., "modified,ID")
     18     *     @type string $order                 Sort order (ASC or DESC)
     19     *     @type string $in_stock              Whether to include only in-stock products (product-specific)
    1920     * }
    2021     * @return array
     
    2930        ];
    3031
    31         // Handle ordering
    32         if (isset($params['order_by'])) {
    33             // Check if order_by is a comma-separated string (e.g. "modified,ID")
    34             if (is_string($params['order_by']) && strpos($params['order_by'], ',') !== false) {
    35                 $orderby_fields = explode(',', $params['order_by']);
    36                 $orderby_array = [];
    37                 foreach ($orderby_fields as $field) {
    38                     $orderby_array[$field] = isset($params['order']) ? strtoupper($params['order']) : 'ASC';
    39                 }
    40 
    41                 // Add ID as secondary sort if not already included
    42                 if (!isset($orderby_array['ID'])) {
    43                     $orderby_array['ID'] = 'ASC';
    44                 }
    45 
    46                 $args['orderby'] = $orderby_array;
    47             } else {
    48                 // Single field ordering - always add ID as secondary sort
    49                 $primary_order = isset($params['order']) ? strtoupper($params['order']) : 'ASC';
    50                 $args['orderby'] = [
    51                     $params['order_by'] => $primary_order,
    52                     'ID' => 'ASC'
    53                 ];
    54             }
    55         } else {
    56             // Default ordering
    57             $args['orderby'] = array('modified' => 'ASC', 'ID' => 'ASC');
    58         }
    59 
    60         // Note: Do NOT set $args['order'] when using array-based orderby
    61         // as it will override the individual sort orders in the array
     32        // Handle ordering - Use custom SQL approach for reliability
     33        $order_by_field = isset($params['order_by']) ? $params['order_by'] : 'modified';
     34        $order_direction = isset($params['order']) ? strtoupper($params['order']) : 'ASC';
     35       
     36        // Validate order direction
     37        if (!in_array($order_direction, ['ASC', 'DESC'])) {
     38            $order_direction = 'ASC';
     39        }
     40       
     41        // Map API field names to WP post fields
     42        $field_map = [
     43            'modified' => 'post_modified',
     44            'date' => 'post_date',
     45            'title' => 'post_title',
     46            'ID' => 'ID'
     47        ];
     48       
     49        $sql_field = isset($field_map[$order_by_field]) ? $field_map[$order_by_field] : 'post_modified';
     50       
     51        // Use a custom orderby filter to ensure correct SQL
     52        add_filter('posts_orderby', function($orderby, $query) use ($sql_field, $order_direction) {
     53            // Only apply to our specific query
     54            if (isset($query->query_vars['muchat_custom_order']) && $query->query_vars['muchat_custom_order'] === true) {
     55                global $wpdb;
     56                return "{$wpdb->posts}.{$sql_field} {$order_direction}, {$wpdb->posts}.ID ASC";
     57            }
     58            return $orderby;
     59        }, 10, 2);
     60       
     61        // Mark this query so our filter can identify it
     62        $args['muchat_custom_order'] = true;
    6263
    6364        // Add date filters if provided
     
    8485        }
    8586
     87        // Add muchat_modified_after filter if provided
     88        if (!empty($params['muchat_modified_after'])) {
     89            try {
     90                // Parse the date as UTC to ensure consistency
     91                $date = new \DateTime($params['muchat_modified_after'], new \DateTimeZone('UTC'));
     92                $formatted_date = $date->format('Y-m-d H:i:s');
     93               
     94                if (!isset($args['meta_query'])) {
     95                    $args['meta_query'] = [];
     96                }
     97               
     98                $args['meta_query'][] = [
     99                    'key' => '_muchat_date_modified',
     100                    'value' => $formatted_date,
     101                    'compare' => '>',
     102                    'type' => 'DATETIME'
     103                ];
     104            } catch (\Exception $e) {
     105                // If date parsing fails, try with strtotime as fallback
     106                $muchat_modified_timestamp = strtotime($params['muchat_modified_after']);
     107                if ($muchat_modified_timestamp) {
     108                    if (!isset($args['meta_query'])) {
     109                        $args['meta_query'] = [];
     110                    }
     111                   
     112                    $args['meta_query'][] = [
     113                        'key' => '_muchat_date_modified',
     114                        'value' => gmdate('Y-m-d H:i:s', $muchat_modified_timestamp),
     115                        'compare' => '>',
     116                        'type' => 'DATETIME'
     117                    ];
     118                }
     119            }
     120        }
     121
    86122        // Product-specific: Add in-stock filter if requested
    87123        if (!empty($params['in_stock']) && $params['in_stock'] === 'true') {
     
    100136        $args['posts_per_page'] = $requested_limit;
    101137        $args['offset'] = $requested_offset;
     138       
     139        // Disable caching for this query to ensure fresh results
     140        $args['cache_results'] = false;
     141        $args['update_post_meta_cache'] = false;
     142        $args['update_post_term_cache'] = false;
     143        $args['no_found_rows'] = false; // We need found_posts for total_count
    102144
    103145        // Execute the final query with pagination
    104146        $query = new \WP_Query($args);
     147       
     148        // Remove the custom orderby filter to avoid affecting other queries
     149        remove_all_filters('posts_orderby', 10);
    105150
    106151        // Get total count from the same query
     
    146191     *
    147192     * @param string|null $modified_after
     193     * @param string|null $muchat_modified_after
    148194     * @return array
    149195     */
    150     public function get_product_ids($modified_after = null)
     196    public function get_product_ids($modified_after = null, $muchat_modified_after = null)
    151197    {
    152198        $args = [
     
    183229        }
    184230
     231        // Add muchat_modified_after filter
     232        if ($muchat_modified_after) {
     233            try {
     234                $date = new \DateTime($muchat_modified_after, new \DateTimeZone('UTC'));
     235                $formatted_date = $date->format('Y-m-d H:i:s');
     236               
     237                $args['meta_query'] = [
     238                    [
     239                        'key' => '_muchat_date_modified',
     240                        'value' => $formatted_date,
     241                        'compare' => '>',
     242                        'type' => 'DATETIME'
     243                    ]
     244                ];
     245            } catch (\Exception $e) {
     246                $muchat_modified_timestamp = strtotime($muchat_modified_after);
     247                if ($muchat_modified_timestamp) {
     248                    $args['meta_query'] = [
     249                        [
     250                            'key' => '_muchat_date_modified',
     251                            'value' => gmdate('Y-m-d H:i:s', $muchat_modified_timestamp),
     252                            'compare' => '>',
     253                            'type' => 'DATETIME'
     254                        ]
     255                    ];
     256                }
     257            }
     258        }
     259
    185260        // Filter to select only ID and post_modified_gmt for performance
    186261        $fields_filter = function ($fields) {
     
    196271
    197272        $products = array_map(function ($post) {
     273            $muchat_modified = \Muchat\Api\Utils\ProductChangeTracker::get_muchat_modified_date($post->ID);
    198274            return [
    199275                'id' => $post->ID,
    200                 'date_modified' => $post->post_modified_gmt
     276                'date_modified' => $post->post_modified_gmt,
     277                'muchat_date_modified' => $muchat_modified
    201278            ];
    202279        }, $query->posts);
     
    233310                    $post_data = get_post($product->get_id());
    234311                    $data['date_modified'] = isset($post_data->post_modified_gmt) ? $post_data->post_modified_gmt : null;
     312                   
     313                    // Add muchat_date_modified (tracks only price/stock changes)
     314                    $muchat_modified = \Muchat\Api\Utils\ProductChangeTracker::get_muchat_modified_date($product->get_id());
     315                    $data['muchat_date_modified'] = $muchat_modified;
    235316                    break;
    236317                case 'description':
  • muchat-ai/trunk/muchat-ai.php

    r3385145 r3392161  
    55 * Plugin URI: https://mu.chat
    66 * Description: Muchat, a powerful tool for customer support using artificial intelligence
    7  * Version: 2.0.49
     7 * Version: 2.0.50
    88 * Author: Muchat
    99 * Text Domain: muchat-ai
     
    2727
    2828// Define plugin constants with unique prefix
    29 define('MUCHAT_AI_CHATBOT_PLUGIN_VERSION', '2.0.49');
     29define('MUCHAT_AI_CHATBOT_PLUGIN_VERSION', '2.0.50');
    3030// define('MUCHAT_AI_CHATBOT_CACHE_DURATION', HOUR_IN_SECONDS);
    3131define('MUCHAT_AI_CHATBOT_PLUGIN_FILE', __FILE__);
     
    118118}
    119119
     120// Initialize all plugin components on plugins_loaded hook for reliability
     121function muchat_ai_chatbot_initialize()
     122{
     123    // Run the main plugin
     124    muchat_ai_chatbot_run_plugin();
     125
     126    // Initialize product change tracker for WooCommerce
     127    if (class_exists('WooCommerce')) {
     128        new \Muchat\Api\Utils\ProductChangeTracker();
     129    }
     130}
     131add_action('plugins_loaded', 'muchat_ai_chatbot_initialize');
     132
    120133// Hook for plugin activation
    121134register_activation_hook(__FILE__, function () {
     
    143156}
    144157
    145 // Run the plugin
    146 muchat_ai_chatbot_run_plugin();
     158// Run the plugin - This direct call is removed and handled by the hook now.
     159// muchat_ai_chatbot_run_plugin();
  • muchat-ai/trunk/readme.txt

    r3385145 r3392161  
    44Requires at least: 5.0
    55Tested up to: 6.8
    6 Stable tag: 2.0.49
    76Requires PHP: 7.3
     7Stable tag: 2.0.50
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    7676== Changelog ==
    7777
     78= 2.0.50 =
     79* Feat: Add `muchat_date_modified` field to products for precise tracking of price/stock changes.
     80* Feat: Add `muchat_modified_after` filter to products API endpoint.
     81* Fix: Ensure variation changes update the parent product's `muchat_date_modified`.
     82* Fix: Plugin initialization now uses `plugins_loaded` hook for better compatibility.
     83
    7884= 2.0.49 =
     85* Fix: Complete rewrite of ordering logic using custom SQL approach to ensure ASC/DESC ordering works correctly across all WordPress environments.
     86* Fix: Resolved issue where order parameter was being ignored, causing identical results regardless of sort direction.
     87* Fix: Disabled query caching to ensure fresh results are always returned.
     88* Enhancement: Added proper SQL field mapping for all order_by options (modified, date, title, ID).
    7989* Fix: Improved API response reliability by cleaning output buffers before processing.
    8090
Note: See TracChangeset for help on using the changeset viewer.