Changeset 3380105
- Timestamp:
- 10/17/2025 12:40:30 PM (3 months ago)
- Location:
- fast-woo-order-lookup
- Files:
-
- 8 edited
- 1 copied
-
tags/1.2.0 (copied) (copied from fast-woo-order-lookup/trunk)
-
tags/1.2.0/changelog.txt (modified) (1 diff)
-
tags/1.2.0/fast-woo-order-lookup.php (modified) (19 diffs)
-
tags/1.2.0/languages/fast-woo-order-lookup.pot (modified) (4 diffs)
-
tags/1.2.0/readme.txt (modified) (6 diffs)
-
trunk/changelog.txt (modified) (1 diff)
-
trunk/fast-woo-order-lookup.php (modified) (19 diffs)
-
trunk/languages/fast-woo-order-lookup.pot (modified) (4 diffs)
-
trunk/readme.txt (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
fast-woo-order-lookup/tags/1.2.0/changelog.txt
r3299021 r3380105 1 = 1.1.10 = July 3, 2025 = 2 3 Less aggressive logging, WooCommerce 9.9.5. 4 5 = 1.1.8 = May 22, 2025 = 6 7 Support 9.9.0. 8 9 = 1.1.7 = April 25, 2025 = 10 11 Fix memory leak in logging. 12 13 = 1.1.6 = April 11, 2025 = 14 15 Fix memory leak in logging. 16 17 = 1.1.5 April 9, 2025 = 18 19 Improve Site Health Info. 20 21 = 1.1.4 April 5, 2025 = 22 23 Handle a COUNT(*) query in support of pagination. 24 1 25 = 1.1.3 October 7, 2024 = 2 26 -
fast-woo-order-lookup/tags/1.2.0/fast-woo-order-lookup.php
r3368869 r3380105 12 12 * Plugin URI: https://plumislandmedia.net/wordpress-plugins/fast-woo-order-lookup/ 13 13 * Description: Look up orders faster in large WooCommerce stores with many orders. 14 * Version: 1. 1.1114 * Version: 1.2.0 15 15 * Requires PHP: 5.6 16 16 * Requires at least: 5.8 17 * Tested up to: 6.8 17 * Tested up to: 6.8.3 18 18 * WC requires at least: 4.0 19 19 * WC tested up to: 9.1.4 … … 38 38 use WC_Order; 39 39 40 if ( ! defined( 'ABSPATH' )) {40 if (!defined('ABSPATH')) { 41 41 exit; 42 42 } … … 44 44 const FAST_WOO_ORDER_LOOKUP_METAKEY_CACHE = 'fast_woo_order_lookup_metakey_cache'; 45 45 46 class FastWooOrderLookup { 46 class FastWooOrderLookup 47 { 47 48 48 49 private static $instance = null; … … 60 61 * @return void 61 62 */ 62 public static function declare_hpos_compatible() { 63 if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) { 64 \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true ); 65 } 66 } 67 68 public static function woocommerce_changing_order( $order_id, $order ) { 69 $instance = self::getInstance(); 70 $instance->orders_to_update[ $order_id ] = 1; 71 } 72 73 public static function woocommerce_deleting_order( $order_id ) { 74 $instance = self::getInstance(); 75 $instance->orders_to_update[ $order_id ] = 1; 76 } 77 78 public static function woocommerce_order_object_updated_props( $order, $props ) { 79 $instance = self::getInstance(); 80 $order_id = $order->get_id(); 81 $instance->orders_to_update[ $order_id ] = 1; 82 } 83 84 public static function update_post_meta( $meta_id, $object_id, $meta_key, $_meta_value ) { 63 public static function declare_hpos_compatible() 64 { 65 if (class_exists(\Automattic\WooCommerce\Utilities\FeaturesUtil::class)) { 66 \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('custom_order_tables', __FILE__, true); 67 } 68 } 69 70 public static function woocommerce_changing_order($order_id, $order) 71 { 85 72 $instance = self::getInstance(); 86 if ( $instance->textdex->is_order_meta_key( $meta_key ) ) { 87 $instance->orders_to_update[ $object_id ] = 1; 88 } 89 } 90 91 public static function textdex_batch_action() { 73 $instance->orders_to_update[$order_id] = 1; 74 } 75 76 public static function woocommerce_deleting_order($order_id) 77 { 78 $instance = self::getInstance(); 79 $instance->orders_to_update[$order_id] = 1; 80 } 81 82 public static function woocommerce_order_object_updated_props($order, $props) 83 { 84 $instance = self::getInstance(); 85 $order_id = $order->get_id(); 86 $instance->orders_to_update[$order_id] = 1; 87 } 88 89 public static function update_post_meta($meta_id, $object_id, $meta_key, $_meta_value) 90 { 91 $instance = self::getInstance(); 92 if ($instance->textdex->is_order_meta_key($meta_key)) { 93 $instance->orders_to_update[$object_id] = 1; 94 } 95 } 96 97 public static function textdex_batch_action() 98 { 92 99 $instance = self::getInstance(); 93 100 $instance->textdex->load_batch(); … … 98 105 * @return FastWooOrderLookup 99 106 */ 100 public static function getInstance() { 101 if ( self::$instance == null ) { 107 public static function getInstance() 108 { 109 if (self::$instance == null) { 102 110 self::$instance = new FastWooOrderLookup(); 103 111 } … … 109 117 * Configure this plugin to intercept metadata searches for WooCommerce orders. 110 118 */ 111 private function __construct() { 112 require_once( plugin_dir_path( __FILE__ ) . 'code/class-textdex.php' ); 119 private function __construct() 120 { 121 require_once(plugin_dir_path(__FILE__) . 'code/class-textdex.php'); 113 122 $this->textdex = new Textdex(); 114 123 $this->textdex->activate(); 115 124 $this->textdex->load_textdex(); 116 125 117 if ( $this->textdex->is_ready()) {126 if ($this->textdex->is_ready()) { 118 127 /* Query manipulation */ 119 add_filter( 'woocommerce_shop_order_search_fields', array( $this, 'filter_search_fields' ));120 add_filter( 'woocommerce_shop_subscription_search_fields', array( $this, 'filter_search_fields' ));121 add_filter( 'woocommerce_shop_order_search_results', array( $this, 'filter_search_results' ), 10, 3);122 add_filter( 'woocommerce_shop_subscription_search_results', array(123 $this,124 'filter_search_results'125 ), 10, 3 );126 add_filter( 'woocommerce_order_query_args', array( $this, 'woocommerce_order_query_args' ));127 add_filter( 'woocommerce_order_query', array( $this, 'woocommerce_order_query' ), 10, 2);128 } 129 add_filter( 'postmeta_form_keys', array( $this, 'postmeta_get_order_custom_field_names' ), 10, 2);130 131 require_once( plugin_dir_path( __FILE__ ) . 'code/class-textdex.php');128 add_filter('woocommerce_shop_order_search_fields', array($this, 'filter_search_fields')); 129 add_filter('woocommerce_shop_subscription_search_fields', array($this, 'filter_search_fields')); 130 add_filter('woocommerce_shop_order_search_results', array($this, 'filter_search_results'), 10, 3); 131 add_filter('woocommerce_shop_subscription_search_results', array( 132 $this, 133 'filter_search_results' 134 ), 10, 3); 135 add_filter('woocommerce_order_query_args', array($this, 'woocommerce_order_query_args')); 136 add_filter('woocommerce_order_query', array($this, 'woocommerce_order_query'), 10, 2); 137 } 138 add_filter('postmeta_form_keys', array($this, 'postmeta_get_order_custom_field_names'), 10, 2); 139 140 require_once(plugin_dir_path(__FILE__) . 'code/class-textdex.php'); 132 141 $this->textdex = new Textdex(); 133 142 $this->textdex->activate(); 134 143 $this->textdex->load_textdex(); 135 144 136 add_action( 'admin_notices', array( $this, 'show_status' ), 10, 0 ); 137 add_action( 'shutdown', array( $this, 'update_textdex' ), 1, 0 ); 138 add_filter( 'plugin_row_meta', array( $this, 'filter_plugin_row_meta' ), 10, 2 ); 139 } 140 141 public function show_status() { 145 add_action('admin_notices', array($this, 'show_status'), 10, 0); 146 add_action('shutdown', array($this, 'update_textdex'), 1, 0); 147 add_filter('plugin_row_meta', array($this, 'filter_plugin_row_meta'), 10, 2); 148 } 149 150 public function show_status() 151 { 142 152 143 153 $error = $this->textdex->get_load_error(); 144 if ( $error) {145 $ms1 = __( 'Fast Woo Order Lookup indexing failed.', 'fast-woo-order-lookup');146 $ms2 = __( 'This happens with some WooCommerce plugins the author did not anticipate.', 'fast-woo-order-lookup');147 $ms3 = __( 'Please create a', 'fast-woo-order-lookup');148 $ms4 = __( 'support topic', 'fast-woo-order-lookup');149 $ms5 = __( 'and paste your', 'fast-woo-order-lookup');150 $ms6 = __( 'Site Health - Info', 'fast-woo-order-lookup');151 $ms7 = __( 'contents into it. Then', 'fast-woo-order-lookup');152 $ms8 = __( 'deactivate', 'fast-woo-order-lookup');153 $ms9 = __( 'the plugin.', 'fast-woo-order-lookup');154 if ($error) { 155 $ms1 = __('Fast Woo Order Lookup indexing failed.', 'fast-woo-order-lookup'); 156 $ms2 = __('This happens with some WooCommerce plugins the author did not anticipate.', 'fast-woo-order-lookup'); 157 $ms3 = __('Please create a', 'fast-woo-order-lookup'); 158 $ms4 = __('support topic', 'fast-woo-order-lookup'); 159 $ms5 = __('and paste your', 'fast-woo-order-lookup'); 160 $ms6 = __('Site Health - Info', 'fast-woo-order-lookup'); 161 $ms7 = __('contents into it. Then', 'fast-woo-order-lookup'); 162 $ms8 = __('deactivate', 'fast-woo-order-lookup'); 163 $ms9 = __('the plugin.', 'fast-woo-order-lookup'); 154 164 155 165 … … 157 167 <div class="notice notice-error"> 158 168 <p> 159 <?php echo esc_html( $ms1); ?>160 <?php echo esc_html( $ms2); ?>161 <?php echo esc_html( $ms3); ?>169 <?php echo esc_html($ms1); ?> 170 <?php echo esc_html($ms2); ?> 171 <?php echo esc_html($ms3); ?> 162 172 <a href="https://wordpress.org/support/plugin/fast-woo-order-lookup/" 163 target="_blank"><?php echo esc_html( $ms4); ?></a>164 <?php echo esc_html( $ms5); ?>165 <a href="/wp-admin/site-health.php?tab=debug" target="_blank"><?php echo esc_html( $ms6); ?></a>166 <?php echo esc_html( $ms7); ?>167 <a href=/wp-admin/plugins.php"><?php echo esc_html( $ms8); ?></a>168 <?php echo esc_html( $ms9); ?>173 target="_blank"><?php echo esc_html($ms4); ?></a> 174 <?php echo esc_html($ms5); ?> 175 <a href="/wp-admin/site-health.php?tab=debug" target="_blank"><?php echo esc_html($ms6); ?></a> 176 <?php echo esc_html($ms7); ?> 177 <a href=/wp-admin/plugins.php"><?php echo esc_html($ms8); ?></a> 178 <?php echo esc_html($ms9); ?> 169 179 </p></div> 170 180 <?php 171 } else if ( ! $this->textdex->is_ready( 10 )) {172 $sa1 = __( 'See the', 'fast-woo-order-lookup');173 $sa2 = __( 'Scheduled Actions status page', 'fast-woo-order-lookup');174 $sa3 = __( 'for details.', 'fast-woo-order-lookup');181 } else if (!$this->textdex->is_ready(10)) { 182 $sa1 = __('See the', 'fast-woo-order-lookup'); 183 $sa2 = __('Scheduled Actions status page', 'fast-woo-order-lookup'); 184 $sa3 = __('for details.', 'fast-woo-order-lookup'); 175 185 $frac = $this->textdex->fraction_complete(); 176 if ( $frac < 0.01) {177 $ms1 = __( 'Fast Woo Order Lookup indexing begins soon.', 'fast-woo-order-lookup');186 if ($frac < 0.01) { 187 $ms1 = __('Fast Woo Order Lookup indexing begins soon.', 'fast-woo-order-lookup'); 178 188 $ms2 = ''; 179 189 } else { 180 $percent = number_format( 100 * $this->textdex->fraction_complete(), 1);181 $ms1 = __( 'Fast Woo Order Lookup indexing still in progress.', 'fast-woo-order-lookup');190 $percent = number_format(100 * $this->textdex->fraction_complete(), 1); 191 $ms1 = __('Fast Woo Order Lookup indexing still in progress.', 'fast-woo-order-lookup'); 182 192 /* translators: 1: percent 12.3 */ 183 $ms2 = __( '%1$s%% complete.', 'fast-woo-order-lookup');184 $ms2 = sprintf( $ms2, $percent);193 $ms2 = __('%1$s%% complete.', 'fast-woo-order-lookup'); 194 $ms2 = sprintf($ms2, $percent); 185 195 } 186 196 ?> 187 197 <div class="notice notice-info"> 188 198 <p> 189 <?php echo esc_html( $ms1); ?>190 <?php echo esc_html( $ms2); ?>191 <?php echo esc_html( $sa1); ?>192 <a href="admin.php?page=wc-status&tab=action-scheduler&s=fast_woo_order_lookup_textdex_action&status=pending"><?php echo esc_html( $sa2); ?></a>193 <?php echo esc_html( $sa3); ?>199 <?php echo esc_html($ms1); ?> 200 <?php echo esc_html($ms2); ?> 201 <?php echo esc_html($sa1); ?> 202 <a href="admin.php?page=wc-status&tab=action-scheduler&s=fast_woo_order_lookup_textdex_action&status=pending"><?php echo esc_html($sa2); ?></a> 203 <?php echo esc_html($sa3); ?> 194 204 </p></div> 195 205 <?php … … 202 212 * @return void 203 213 */ 204 public function update_textdex() {205 if ( count( $this->orders_to_update ) > 0 ){206 $this->update_meta_keys( array_keys( $this->orders_to_update ) );207 $this-> textdex->update( array_keys( $this->orders_to_update ));208 }209 }210 214 public function update_textdex() 215 { 216 if (count($this->orders_to_update) > 0) { 217 $this->update_meta_keys(array_keys($this->orders_to_update)); 218 $this->textdex->update(array_keys($this->orders_to_update)); 219 } 220 } 211 221 212 222 /** … … 219 229 * @return array 220 230 */ 221 public function filter_search_fields( $search_fields ) { 222 if ( ! $this->textdex->is_ready() ) { 231 public function filter_search_fields($search_fields) 232 { 233 if (!$this->textdex->is_ready()) { 223 234 return $search_fields; 224 235 } 225 236 /* Hook to mung the queries. */ 226 237 $this->filtering = true; 227 add_filter( 'query', array( $this, 'standard_query' ), 1);238 add_filter('query', array($this, 'standard_query'), 1); 228 239 229 240 return $search_fields; … … 241 252 * @return array 242 253 */ 243 public function filter_search_results( $order_ids, $term, $search_fields ) { 244 245 if ( $this->filtering ) { 254 public function filter_search_results($order_ids, $term, $search_fields) 255 { 256 257 if ($this->filtering) { 246 258 /* Discontinue filtering queries after the metadata search */ 247 remove_filter( 'query', array( $this, 'standard_query' ), 1);259 remove_filter('query', array($this, 'standard_query'), 1); 248 260 $this->filtering = false; 249 261 } … … 261 273 * @return string 262 274 */ 263 public function standard_query( $query ) { 264 265 if ( ! $this->term ) { 266 $splits = explode( 'LIKE \'%', $query, 2 ); 267 if ( 2 !== count( $splits ) ) { 275 public function standard_query($query) 276 { 277 278 if (!$this->term) { 279 $splits = explode('LIKE \'%', $query, 2); 280 if (2 !== count($splits)) { 268 281 return $query; 269 282 } 270 $splits = explode( '%\'', $splits[1]);271 if ( 2 !== count( $splits )) {283 $splits = explode('%\'', $splits[1]); 284 if (2 !== count($splits)) { 272 285 return $query; 273 286 } 274 $this->term = $splits[0];275 $this->trigram_clause = $this->textdex->trigram_clause( $this->term);287 $this->term = $splits[0]; 288 $this->trigram_clause = $this->textdex->trigram_clause($this->term); 276 289 } 277 290 $newQuery = $query; 278 $munged = false;279 if ( str_contains( $newQuery, 'woocommerce_order_items as order_item' )) {280 $newQuery = str_replace( 'WHERE order_item_name LIKE', 'WHERE order_id IN (' . $this->trigram_clause . ') AND order_item_name LIKE', $newQuery);281 $munged = true;282 } else if ( str_contains( $newQuery, 'SELECT DISTINCT os.order_id FROM wp_wc_order_stats os' )) {291 $munged = false; 292 if (str_contains($newQuery, 'woocommerce_order_items as order_item')) { 293 $newQuery = str_replace('WHERE order_item_name LIKE', 'WHERE order_id IN (' . $this->trigram_clause . ') AND order_item_name LIKE', $newQuery); 294 $munged = true; 295 } else if (str_contains($newQuery, 'SELECT DISTINCT os.order_id FROM wp_wc_order_stats os')) { 283 296 /* empty, intentionally */ 284 297 } else { 285 $newQuery = str_replace( 'postmeta p1 WHERE ', 'postmeta p1 WHERE post_id IN (' . $this->trigram_clause . ') AND ', $newQuery);286 $munged = true;287 } 288 $munged && $this->textdex->capture_query( $newQuery, 'search', false);298 $newQuery = str_replace('postmeta p1 WHERE ', 'postmeta p1 WHERE post_id IN (' . $this->trigram_clause . ') AND ', $newQuery); 299 $munged = true; 300 } 301 $munged && $this->textdex->capture_query($newQuery, 'search', false); 289 302 290 303 return $newQuery; … … 300 313 * @return mixed 301 314 */ 302 public function woocommerce_order_query_args( $args ) { 303 $its_search = array_key_exists( 's', $args ) && is_string( $args['s'] ) && strlen( $args['s'] ) > 0; 304 $its_order_id_search = array_key_exists( 'search_filter', $args ) && 'order_id' === $args ['search_filter']; 305 if ( $its_search && ! $its_order_id_search && $this->textdex->is_ready() ) { 306 $this->term = $args['s']; 307 $this->trigram_clause = $this->textdex->trigram_clause( $this->term ); 315 public function woocommerce_order_query_args($args) 316 { 317 $its_search = array_key_exists('s', $args) && is_string($args['s']) && strlen($args['s']) > 0; 318 $its_order_id_search = array_key_exists('search_filter', $args) && 'order_id' === $args ['search_filter']; 319 if ($its_search && !$its_order_id_search && $this->textdex->is_ready()) { 320 $this->term = $args['s']; 321 $this->trigram_clause = $this->textdex->trigram_clause($this->term); 308 322 309 323 /* Hook to mung the queries. */ 310 324 $this->filtering = true; 311 add_filter( 'query', array( $this, 'hpos_query' ), 1);325 add_filter('query', array($this, 'hpos_query'), 1); 312 326 } 313 327 … … 325 339 * @return mixed 326 340 */ 327 public function woocommerce_order_query( $results, $args ) { 328 if ( $this->filtering ) { 341 public function woocommerce_order_query($results, $args) 342 { 343 if ($this->filtering) { 329 344 /* Discontinue filtering queries after the search */ 330 remove_filter( 'query', array( $this, 'hpos_query' ), 1);345 remove_filter('query', array($this, 'hpos_query'), 1); 331 346 $this->filtering = false; 332 347 } … … 348 363 * @return string 349 364 */ 350 public function hpos_query( $query ) { 365 public function hpos_query($query) 366 { 351 367 global $wpdb; 352 $orders = $wpdb->prefix . 'wc_orders';368 $orders = $wpdb->prefix . 'wc_orders'; 353 369 $orderitems = $wpdb->prefix . 'woocommerce_order_items'; 354 370 355 371 /* Skip modifying the FULLTEXT search option choice. */ 356 if ( str_contains( $query, 'IN BOOLEAN MODE' )) {372 if (str_contains($query, 'IN BOOLEAN MODE')) { 357 373 return $query; 358 374 } 359 if ( str_contains( $query, "$orderitems AS search_query_items ON search_query_items.order_id = $orders.id WHERE 1=1 AND") ||360 str_contains( $query, "SELECT $orders.id FROM $orders WHERE 1=1 AND") ||361 str_contains( $query, "SELECT COUNT(*) FROM $orders WHERE 1=1 AND") ||362 str_contains( $query, "SELECT COUNT(DISTINCT $orders.id) FROM $orders WHERE 1=1 AND")375 if (str_contains($query, "$orderitems AS search_query_items ON search_query_items.order_id = $orders.id WHERE 1=1 AND") || 376 str_contains($query, "SELECT $orders.id FROM $orders WHERE 1=1 AND") || 377 str_contains($query, "SELECT COUNT(*) FROM $orders WHERE 1=1 AND") || 378 str_contains($query, "SELECT COUNT(DISTINCT $orders.id) FROM $orders WHERE 1=1 AND") 363 379 ) { 364 $query = str_replace( 'WHERE 1=1 AND', "WHERE 1=1 AND $orders.id IN (" . $this->trigram_clause . ") AND ", $query);365 $this->textdex->capture_query( $query, 'search', false);380 $query = str_replace('WHERE 1=1 AND', "WHERE 1=1 AND $orders.id IN (" . $this->trigram_clause . ") AND ", $query); 381 $this->textdex->capture_query($query, 'search', false); 366 382 367 383 } … … 382 398 * @return array|null 383 399 */ 384 public function postmeta_get_order_custom_field_names( $keys, $order ) { 385 if ( ! @is_a( $order, WC_Order::class ) ) { 400 public function postmeta_get_order_custom_field_names($keys, $order) 401 { 402 if (!@is_a($order, WC_Order::class)) { 386 403 return $keys; 387 404 } 388 405 389 require_once( plugin_dir_path( __FILE__ ) . 'code/class-custom-fields.php');406 require_once(plugin_dir_path(__FILE__) . 'code/class-custom-fields.php'); 390 407 $cust = new Custom_Fields(); 391 408 … … 400 417 $changed = false; 401 418 foreach ( $orders as $order_id ) { 402 $order = wc_get_order( $order_id ); 403 $metas = wc_get_container()->get( OrdersTableDataStoreMeta::class )->read_meta( $order ); 404 foreach ( $metas as $meta ) { 405 $meta_key = $meta->meta_key; 406 if ( ! str_starts_with( $meta_key, '_' ) ) { 407 if ( ! in_array( $meta_key, $cached_keys ) ) { 408 $changed = true; 409 $cached_keys [] = $meta_key; 419 if ( $order_id ) { 420 $order = wc_get_order( $order_id ); 421 if ( $order instanceof WC_Order ) { 422 $metas = wc_get_container()->get( OrdersTableDataStoreMeta::class )->read_meta( $order ); 423 foreach ( $metas as $meta ) { 424 $meta_key = $meta->meta_key; 425 if ( ! str_starts_with( $meta_key, '_' ) ) { 426 if ( ! in_array( $meta_key, $cached_keys ) ) { 427 $changed = true; 428 $cached_keys [] = $meta_key; 429 } 430 } 410 431 } 411 432 } … … 425 446 * @return array<int, string> Updated array of the plugin's metadata. 426 447 */ 427 public function filter_plugin_row_meta( array $plugin_meta, $plugin_file ) { 428 if ( FAST_WOO_ORDER_LOOKUP_PLUGIN_BASE !== $plugin_file ) { 448 public function filter_plugin_row_meta(array $plugin_meta, $plugin_file) 449 { 450 if (FAST_WOO_ORDER_LOOKUP_PLUGIN_BASE !== $plugin_file) { 429 451 return $plugin_meta; 430 452 } 431 453 432 454 $plugin_meta[] = sprintf( 433 '<a href="%1$s"><span class="dashicons dashicons-star-filled" aria-hidden="true" style="font-size:14px;line-height:1.3"></span>%2$s</a>',434 'https://github.com/sponsors/OllieJones',435 esc_html_x( 'Sponsor', 'verb', 'index-wp-users-for-speed')455 '<a href="%1$s"><span class="dashicons dashicons-star-filled" aria-hidden="true" style="font-size:14px;line-height:1.3"></span>%2$s</a>', 456 'https://github.com/sponsors/OllieJones', 457 esc_html_x('Sponsor', 'verb', 'index-wp-users-for-speed') 436 458 ); 437 459 … … 443 465 444 466 // Plugin name 445 const FAST_WOO_ORDER_LOOKUP_NAME = 'Fast Woo Order Lookup';467 const FAST_WOO_ORDER_LOOKUP_NAME = 'Fast Woo Order Lookup'; 446 468 447 469 // Plugin version 448 const FAST_WOO_ORDER_LOOKUP_VERSION = '1.1.11';470 const FAST_WOO_ORDER_LOOKUP_VERSION = '1.2.0'; 449 471 450 472 // Plugin Root File 451 const FAST_WOO_ORDER_LOOKUP_PLUGIN_FILE = __FILE__;473 const FAST_WOO_ORDER_LOOKUP_PLUGIN_FILE = __FILE__; 452 474 453 475 // Plugin base 454 define( 'FAST_WOO_ORDER_LOOKUP_PLUGIN_BASE', plugin_basename( FAST_WOO_ORDER_LOOKUP_PLUGIN_FILE ));476 define('FAST_WOO_ORDER_LOOKUP_PLUGIN_BASE', plugin_basename(FAST_WOO_ORDER_LOOKUP_PLUGIN_FILE)); 455 477 456 478 // Plugin slug 457 define( 'FAST_WOO_ORDER_LOOKUP_SLUG', explode( DIRECTORY_SEPARATOR, FAST_WOO_ORDER_LOOKUP_PLUGIN_BASE )[0]);479 define('FAST_WOO_ORDER_LOOKUP_SLUG', explode(DIRECTORY_SEPARATOR, FAST_WOO_ORDER_LOOKUP_PLUGIN_BASE)[0]); 458 480 459 481 // Plugin Folder Path 460 define( 'FAST_WOO_ORDER_LOOKUP_PLUGIN_DIR', plugin_dir_path( FAST_WOO_ORDER_LOOKUP_PLUGIN_FILE ));482 define('FAST_WOO_ORDER_LOOKUP_PLUGIN_DIR', plugin_dir_path(FAST_WOO_ORDER_LOOKUP_PLUGIN_FILE)); 461 483 462 484 // Plugin Folder URL 463 define( 'FAST_WOO_ORDER_LOOKUP_PLUGIN_URL', plugin_dir_url( FAST_WOO_ORDER_LOOKUP_PLUGIN_FILE ));464 465 466 register_activation_hook( __FILE__, 'Fast_Woo_Order_Lookup\activate');467 register_deactivation_hook( __FILE__, 'Fast_Woo_Order_Lookup\deactivate');468 469 add_action( 'before_woocommerce_init', array( 'Fast_Woo_Order_Lookup\FastWooOrderLookup', 'declare_hpos_compatible' ));470 471 add_action( 'admin_init', function() {485 define('FAST_WOO_ORDER_LOOKUP_PLUGIN_URL', plugin_dir_url(FAST_WOO_ORDER_LOOKUP_PLUGIN_FILE)); 486 487 488 register_activation_hook(__FILE__, 'Fast_Woo_Order_Lookup\activate'); 489 register_deactivation_hook(__FILE__, 'Fast_Woo_Order_Lookup\deactivate'); 490 491 add_action('before_woocommerce_init', array('Fast_Woo_Order_Lookup\FastWooOrderLookup', 'declare_hpos_compatible')); 492 493 add_action('admin_init', function () { 472 494 FastWooOrderLookup::getInstance(); 473 }, 10, 0 );495 }, 10, 0); 474 496 475 497 /* Hook anything that changes an order object */ 476 add_action( 'woocommerce_new_order',477 array( 'Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_changing_order' ), 10, 2);478 add_action( 'woocommerce_update_order',479 array( 'Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_changing_order' ), 10, 2);480 add_action( 'woocommerce_order_object_updated_props',481 array( 'Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_order_object_updated_props' ), 10, 2);498 add_action('woocommerce_new_order', 499 array('Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_changing_order'), 10, 2); 500 add_action('woocommerce_update_order', 501 array('Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_changing_order'), 10, 2); 502 add_action('woocommerce_order_object_updated_props', 503 array('Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_order_object_updated_props'), 10, 2); 482 504 /* Hook changes to order status. */ 483 add_action( 'woocommerce_delete_order',484 array( 'Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_deleting_order' ));485 add_action( 'woocommerce_trash_order',486 array( 'Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_deleting_order' ));487 add_action( 'woocommerce_untrash_order',488 array( 'Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_deleting_order' ));489 add_action( 'woocommerce_cancelled_order',490 array( 'Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_deleting_order' ));491 add_action( 'update_post_meta',492 array( 'Fast_Woo_Order_Lookup\FastWooOrderLookup', 'update_post_meta' ), 10, 4);505 add_action('woocommerce_delete_order', 506 array('Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_deleting_order')); 507 add_action('woocommerce_trash_order', 508 array('Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_deleting_order')); 509 add_action('woocommerce_untrash_order', 510 array('Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_deleting_order')); 511 add_action('woocommerce_cancelled_order', 512 array('Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_deleting_order')); 513 add_action('update_post_meta', 514 array('Fast_Woo_Order_Lookup\FastWooOrderLookup', 'update_post_meta'), 10, 4); 493 515 494 516 /* ActionScheduler action for loading textdex. */ 495 add_action( 'fast_woo_order_lookup_textdex_action', 496 array( 'Fast_Woo_Order_Lookup\FastWooOrderLookup', 'textdex_batch_action' ) ); 497 498 function activate() { 499 register_uninstall_hook( __FILE__, 'Fast_Woo_Order_Lookup\uninstall' ); 500 require_once( plugin_dir_path( __FILE__ ) . 'code/class-textdex.php' ); 517 add_action('fast_woo_order_lookup_textdex_action', 518 array('Fast_Woo_Order_Lookup\FastWooOrderLookup', 'textdex_batch_action')); 519 520 function activate() 521 { 522 register_uninstall_hook(__FILE__, 'Fast_Woo_Order_Lookup\uninstall'); 523 require_once(plugin_dir_path(__FILE__) . 'code/class-textdex.php'); 501 524 $textdex = new Textdex(); 502 525 $textdex->activate(); … … 506 529 } 507 530 508 function deactivate() { 509 510 require_once( plugin_dir_path( __FILE__ ) . 'code/class-textdex.php' ); 531 function deactivate() 532 { 533 534 require_once(plugin_dir_path(__FILE__) . 'code/class-textdex.php'); 511 535 $textdex = new Textdex(); 512 536 $textdex->deactivate(); 513 delete_transient( FAST_WOO_ORDER_LOOKUP_METAKEY_CACHE);537 delete_transient(FAST_WOO_ORDER_LOOKUP_METAKEY_CACHE); 514 538 } 515 539 516 function uninstall() { 540 function uninstall() 541 { 517 542 518 543 } -
fast-woo-order-lookup/tags/1.2.0/languages/fast-woo-order-lookup.pot
r3368869 r3380105 3 3 msgid "" 4 4 msgstr "" 5 "Project-Id-Version: Fast Woo Order Lookup 1. 1.11\n"5 "Project-Id-Version: Fast Woo Order Lookup 1.2.0\n" 6 6 "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/fast-woo-order-lookup\n" 7 7 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" … … 10 10 "Content-Type: text/plain; charset=UTF-8\n" 11 11 "Content-Transfer-Encoding: 8bit\n" 12 "POT-Creation-Date: 2025- 09-25T18:53:53-04:00\n"12 "POT-Creation-Date: 2025-10-17T08:33:40-04:00\n" 13 13 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 14 14 "X-Generator: WP-CLI 2.9.0\n" … … 16 16 17 17 #. Plugin Name of the plugin 18 #: code/class-textdex.php:6 8118 #: code/class-textdex.php:693 19 19 msgid "Fast Woo Order Lookup" 20 20 msgstr "" … … 36 36 msgstr "" 37 37 38 #: code/class-textdex.php:6 0138 #: code/class-textdex.php:613 39 39 msgid "Operation" 40 40 msgstr "" 41 41 42 #: code/class-textdex.php:6 5742 #: code/class-textdex.php:669 43 43 msgid "Explanation" 44 44 msgstr "" 45 45 46 #: code/class-textdex.php:6 5846 #: code/class-textdex.php:670 47 47 msgid "Errors sometimes occur while the plugin is creating its index table. Variations in database server make and version, and your WordPress version when you created it cause these. The plugin author will add suppot for your variation if you open a support topic." 48 48 msgstr "" 49 49 50 #: code/class-textdex.php:6 5950 #: code/class-textdex.php:671 51 51 msgid "And sometimes some types of orders cannot be found. Search for the failing orders and return here to capture useful troubleshooting information." 52 52 msgstr "" 53 53 54 #: code/class-textdex.php:6 6454 #: code/class-textdex.php:676 55 55 msgid "Request" 56 56 msgstr "" 57 57 58 #: code/class-textdex.php:6 6559 #: code/class-textdex.php:6 6758 #: code/class-textdex.php:677 59 #: code/class-textdex.php:679 60 60 msgid "Please create a support topic at" 61 61 msgstr "" 62 62 63 #: code/class-textdex.php:6 6663 #: code/class-textdex.php:678 64 64 msgid "Click [Copy Site Info To Clipboard] then paste your site info into the topic." 65 65 msgstr "" 66 66 67 #: code/class-textdex.php:6 6867 #: code/class-textdex.php:680 68 68 msgid "and paste this site info (all of it please) into the topic. We will take a look." 69 69 msgstr "" 70 70 71 #: code/class-textdex.php:6 7271 #: code/class-textdex.php:684 72 72 msgid "WooCommerce Features" 73 73 msgstr "" 74 74 75 #: code/class-textdex.php:6 7675 #: code/class-textdex.php:688 76 76 msgid "Trigram Table" 77 77 msgstr "" 78 78 79 #: fast-woo-order-lookup.php:1 4579 #: fast-woo-order-lookup.php:155 80 80 msgid "Fast Woo Order Lookup indexing failed." 81 81 msgstr "" 82 82 83 #: fast-woo-order-lookup.php:1 4683 #: fast-woo-order-lookup.php:156 84 84 msgid "This happens with some WooCommerce plugins the author did not anticipate." 85 85 msgstr "" 86 86 87 #: fast-woo-order-lookup.php:1 4787 #: fast-woo-order-lookup.php:157 88 88 msgid "Please create a" 89 89 msgstr "" 90 90 91 #: fast-woo-order-lookup.php:1 4891 #: fast-woo-order-lookup.php:158 92 92 msgid "support topic" 93 93 msgstr "" 94 94 95 #: fast-woo-order-lookup.php:1 4995 #: fast-woo-order-lookup.php:159 96 96 msgid "and paste your" 97 97 msgstr "" 98 98 99 #: fast-woo-order-lookup.php:1 5099 #: fast-woo-order-lookup.php:160 100 100 msgid "Site Health - Info" 101 101 msgstr "" 102 102 103 #: fast-woo-order-lookup.php:1 51103 #: fast-woo-order-lookup.php:161 104 104 msgid "contents into it. Then" 105 105 msgstr "" 106 106 107 #: fast-woo-order-lookup.php:1 52107 #: fast-woo-order-lookup.php:162 108 108 msgid "deactivate" 109 109 msgstr "" 110 110 111 #: fast-woo-order-lookup.php:1 53111 #: fast-woo-order-lookup.php:163 112 112 msgid "the plugin." 113 113 msgstr "" 114 114 115 #: fast-woo-order-lookup.php:1 72115 #: fast-woo-order-lookup.php:182 116 116 msgid "See the" 117 117 msgstr "" 118 118 119 #: fast-woo-order-lookup.php:1 73119 #: fast-woo-order-lookup.php:183 120 120 msgid "Scheduled Actions status page" 121 121 msgstr "" 122 122 123 #: fast-woo-order-lookup.php:1 74123 #: fast-woo-order-lookup.php:184 124 124 msgid "for details." 125 125 msgstr "" 126 126 127 #: fast-woo-order-lookup.php:1 77127 #: fast-woo-order-lookup.php:187 128 128 msgid "Fast Woo Order Lookup indexing begins soon." 129 129 msgstr "" 130 130 131 #: fast-woo-order-lookup.php:1 81131 #: fast-woo-order-lookup.php:191 132 132 msgid "Fast Woo Order Lookup indexing still in progress." 133 133 msgstr "" 134 134 135 135 #. translators: 1: percent 12.3 136 #: fast-woo-order-lookup.php:1 83136 #: fast-woo-order-lookup.php:193 137 137 msgid "%1$s%% complete." 138 138 msgstr "" -
fast-woo-order-lookup/tags/1.2.0/readme.txt
r3368869 r3380105 5 5 Tags: woocommerce, search, orders, database, performance 6 6 Requires at least: 5.9 7 Tested up to: 6.8. 17 Tested up to: 6.8.3 8 8 Requires PHP: 5.6 9 9 WC requires at least: 8.0 10 10 WC tested up to: 10.2.1 11 Stable tag: 1. 1.1111 Stable tag: 1.2.0 12 12 Requires Plugins: woocommerce 13 13 License: GPLv2 … … 27 27 The downside: the trigram table takes database space and takes time to generate. 28 28 29 The orders page itself contains a slow query to look up meta_keys. This fixes that query's performance too .29 The orders page itself contains a slow query to look up meta_keys. This fixes that query's performance too, using a cache of available values. 30 30 31 31 <h4>If you have problems</h4> … … 58 58 Build a [trigram lookup table](https://www.plumislandmedia.net/wordpress-plugins/fast-woo-order-lookup/#how-does-it-work-trigrams), maintain it, and use it for the queries. 59 59 60 = How much space does the trigram lookup tabletake? =60 = How much space does the lookup table -- `wp_fwol` -- take? = 61 61 62 It takes about 5-10KiB per order, as MariaDB / MySQL database storage, counting both data and indexes. So, if your site has a million orders, the table will take something like 5-10 GiB. 62 It takes about 5-10KiB per order, as MariaDB / MySQL database storage, counting both data and indexes. So, if your site has a million orders, the table will take something like 5-10 GiB. The rows of the table are each quite small, just three letters and an order ID. And there are many of those rows for each order. 63 64 The table, named with an abbreviation for "Fast Woo Order Lookup", contains the trigram lookups. It has a terse name to keep queries short. It is dropped automatically if you deactivate the plugin. 65 66 = Can it get so large this plugin becomes useless or counterproductive? = 67 68 **No, unless your database tablespace is too small for it.** 69 70 This answer uses the [Big **O**](https://en.wikipedia.org/wiki/Big_O_notation) conceptual way of understanding program performance. 71 72 The table is organized by its primary key so this plugin can search for orders with **O**(log n) computational complexity. That means if searching 100 orders takes two seconds, then searching 1000 takes about three seconds and 10,000 about four. So it will work at large scale. And without this plugin the complexity of the order search in WooCommerce is a quite unpleasant **O**(n). Ten times as many orders take ten times as long to search. So, 100 times as many take 100 times as long. Used at large scale that gets nasty. It burns server electricity. Just as importantly, it wastes users' time. 73 74 That's true even if you use a nice search plugin like [Relevanssi](https://wordpress.org/plugins/relevanssi/) to help your customers search for products. The author does that. It works. But not on orders. 75 76 This plugin improves order search performance by using a better algorithm. It's the InnoDB team we have to thank for this in MariaDB and MySQL. Legendary. (See, Dr. Knuth? Somebody read your book!) 77 78 If your hosting service is such a cheapskate you don't have the tablespace for the table, that might be a reason to avoid this plugin. 63 79 64 80 = How long does it take to generate trigram lookup table? = … … 81 97 2. Deactivate, then activate the plugin. This rebuilds the lookup table. 82 98 83 = What is this wp_fwol table created by the plugin? =84 85 This table, named with an abbreviation for "Fast Woo Order Lookup", contains the trigram lookups. It has a terse name to keep queries short. It is dropped automatically if you deactivate the plugin.86 87 99 = My store only has a few hundred orders. Do I need this plugin ? = 88 100 89 This plugin addresses database performance problems that only show themselves on stores with many t ens of thousands of orders. If your store is smaller than that you probably don't need it.101 This plugin addresses database performance problems that only show themselves on stores with many thousands of orders. If your store is smaller than that you probably don't need it. 90 102 91 103 Wise owners of rapidly growing stores return regularly to examine their site performance. If your site is still small, it's better to wait until you actually need performance-enhancing plugins and other features. Installing them "just in case" is ineffective. … … 109 121 * It improves indexing performance by skipping gaps in order numbers. 110 122 111 ## Changelog 123 == Upgrade Notice == 124 125 Recent versions correct intermittent problems generating the index and maintaining the postmeta key cache. 126 127 Thanks to my loyal users for bringing these problems to my attention! 128 129 == Changelog == 130 131 = 1.2.0 = October 17, 2025 132 133 Correct an intermittent problem maintaining the postmeta key cache. Props tp slservice33 on w.org. 112 134 113 135 = 1.1.11 = September 24, 2025 = … … 115 137 WooCommerce 10.2.1, indexing defect fixed, gap skipping when indexing. Props to StefT1 on GitHub. 116 138 117 = 1.1.10 = July 3, 2025 =118 119 Less aggressive logging, WooCommerce 9.9.5.120 121 = 1.1.8 = May 22, 2025 =122 123 Support 9.9.0.124 125 = 1.1.7 = April 25, 2025 =126 127 Fix memory leak in logging.128 129 = 1.1.6 = April 11, 2025 =130 131 Fix memory leak in logging.132 133 = 1.1.5 April 9, 2025 =134 135 Improve Site Health Info.136 137 = 1.1.4 April 5, 2025 =138 139 Handle a COUNT(*) query in support of pagination.140 -
fast-woo-order-lookup/trunk/changelog.txt
r3299021 r3380105 1 = 1.1.10 = July 3, 2025 = 2 3 Less aggressive logging, WooCommerce 9.9.5. 4 5 = 1.1.8 = May 22, 2025 = 6 7 Support 9.9.0. 8 9 = 1.1.7 = April 25, 2025 = 10 11 Fix memory leak in logging. 12 13 = 1.1.6 = April 11, 2025 = 14 15 Fix memory leak in logging. 16 17 = 1.1.5 April 9, 2025 = 18 19 Improve Site Health Info. 20 21 = 1.1.4 April 5, 2025 = 22 23 Handle a COUNT(*) query in support of pagination. 24 1 25 = 1.1.3 October 7, 2024 = 2 26 -
fast-woo-order-lookup/trunk/fast-woo-order-lookup.php
r3368869 r3380105 12 12 * Plugin URI: https://plumislandmedia.net/wordpress-plugins/fast-woo-order-lookup/ 13 13 * Description: Look up orders faster in large WooCommerce stores with many orders. 14 * Version: 1. 1.1114 * Version: 1.2.0 15 15 * Requires PHP: 5.6 16 16 * Requires at least: 5.8 17 * Tested up to: 6.8 17 * Tested up to: 6.8.3 18 18 * WC requires at least: 4.0 19 19 * WC tested up to: 9.1.4 … … 38 38 use WC_Order; 39 39 40 if ( ! defined( 'ABSPATH' )) {40 if (!defined('ABSPATH')) { 41 41 exit; 42 42 } … … 44 44 const FAST_WOO_ORDER_LOOKUP_METAKEY_CACHE = 'fast_woo_order_lookup_metakey_cache'; 45 45 46 class FastWooOrderLookup { 46 class FastWooOrderLookup 47 { 47 48 48 49 private static $instance = null; … … 60 61 * @return void 61 62 */ 62 public static function declare_hpos_compatible() { 63 if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) { 64 \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true ); 65 } 66 } 67 68 public static function woocommerce_changing_order( $order_id, $order ) { 69 $instance = self::getInstance(); 70 $instance->orders_to_update[ $order_id ] = 1; 71 } 72 73 public static function woocommerce_deleting_order( $order_id ) { 74 $instance = self::getInstance(); 75 $instance->orders_to_update[ $order_id ] = 1; 76 } 77 78 public static function woocommerce_order_object_updated_props( $order, $props ) { 79 $instance = self::getInstance(); 80 $order_id = $order->get_id(); 81 $instance->orders_to_update[ $order_id ] = 1; 82 } 83 84 public static function update_post_meta( $meta_id, $object_id, $meta_key, $_meta_value ) { 63 public static function declare_hpos_compatible() 64 { 65 if (class_exists(\Automattic\WooCommerce\Utilities\FeaturesUtil::class)) { 66 \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('custom_order_tables', __FILE__, true); 67 } 68 } 69 70 public static function woocommerce_changing_order($order_id, $order) 71 { 85 72 $instance = self::getInstance(); 86 if ( $instance->textdex->is_order_meta_key( $meta_key ) ) { 87 $instance->orders_to_update[ $object_id ] = 1; 88 } 89 } 90 91 public static function textdex_batch_action() { 73 $instance->orders_to_update[$order_id] = 1; 74 } 75 76 public static function woocommerce_deleting_order($order_id) 77 { 78 $instance = self::getInstance(); 79 $instance->orders_to_update[$order_id] = 1; 80 } 81 82 public static function woocommerce_order_object_updated_props($order, $props) 83 { 84 $instance = self::getInstance(); 85 $order_id = $order->get_id(); 86 $instance->orders_to_update[$order_id] = 1; 87 } 88 89 public static function update_post_meta($meta_id, $object_id, $meta_key, $_meta_value) 90 { 91 $instance = self::getInstance(); 92 if ($instance->textdex->is_order_meta_key($meta_key)) { 93 $instance->orders_to_update[$object_id] = 1; 94 } 95 } 96 97 public static function textdex_batch_action() 98 { 92 99 $instance = self::getInstance(); 93 100 $instance->textdex->load_batch(); … … 98 105 * @return FastWooOrderLookup 99 106 */ 100 public static function getInstance() { 101 if ( self::$instance == null ) { 107 public static function getInstance() 108 { 109 if (self::$instance == null) { 102 110 self::$instance = new FastWooOrderLookup(); 103 111 } … … 109 117 * Configure this plugin to intercept metadata searches for WooCommerce orders. 110 118 */ 111 private function __construct() { 112 require_once( plugin_dir_path( __FILE__ ) . 'code/class-textdex.php' ); 119 private function __construct() 120 { 121 require_once(plugin_dir_path(__FILE__) . 'code/class-textdex.php'); 113 122 $this->textdex = new Textdex(); 114 123 $this->textdex->activate(); 115 124 $this->textdex->load_textdex(); 116 125 117 if ( $this->textdex->is_ready()) {126 if ($this->textdex->is_ready()) { 118 127 /* Query manipulation */ 119 add_filter( 'woocommerce_shop_order_search_fields', array( $this, 'filter_search_fields' ));120 add_filter( 'woocommerce_shop_subscription_search_fields', array( $this, 'filter_search_fields' ));121 add_filter( 'woocommerce_shop_order_search_results', array( $this, 'filter_search_results' ), 10, 3);122 add_filter( 'woocommerce_shop_subscription_search_results', array(123 $this,124 'filter_search_results'125 ), 10, 3 );126 add_filter( 'woocommerce_order_query_args', array( $this, 'woocommerce_order_query_args' ));127 add_filter( 'woocommerce_order_query', array( $this, 'woocommerce_order_query' ), 10, 2);128 } 129 add_filter( 'postmeta_form_keys', array( $this, 'postmeta_get_order_custom_field_names' ), 10, 2);130 131 require_once( plugin_dir_path( __FILE__ ) . 'code/class-textdex.php');128 add_filter('woocommerce_shop_order_search_fields', array($this, 'filter_search_fields')); 129 add_filter('woocommerce_shop_subscription_search_fields', array($this, 'filter_search_fields')); 130 add_filter('woocommerce_shop_order_search_results', array($this, 'filter_search_results'), 10, 3); 131 add_filter('woocommerce_shop_subscription_search_results', array( 132 $this, 133 'filter_search_results' 134 ), 10, 3); 135 add_filter('woocommerce_order_query_args', array($this, 'woocommerce_order_query_args')); 136 add_filter('woocommerce_order_query', array($this, 'woocommerce_order_query'), 10, 2); 137 } 138 add_filter('postmeta_form_keys', array($this, 'postmeta_get_order_custom_field_names'), 10, 2); 139 140 require_once(plugin_dir_path(__FILE__) . 'code/class-textdex.php'); 132 141 $this->textdex = new Textdex(); 133 142 $this->textdex->activate(); 134 143 $this->textdex->load_textdex(); 135 144 136 add_action( 'admin_notices', array( $this, 'show_status' ), 10, 0 ); 137 add_action( 'shutdown', array( $this, 'update_textdex' ), 1, 0 ); 138 add_filter( 'plugin_row_meta', array( $this, 'filter_plugin_row_meta' ), 10, 2 ); 139 } 140 141 public function show_status() { 145 add_action('admin_notices', array($this, 'show_status'), 10, 0); 146 add_action('shutdown', array($this, 'update_textdex'), 1, 0); 147 add_filter('plugin_row_meta', array($this, 'filter_plugin_row_meta'), 10, 2); 148 } 149 150 public function show_status() 151 { 142 152 143 153 $error = $this->textdex->get_load_error(); 144 if ( $error) {145 $ms1 = __( 'Fast Woo Order Lookup indexing failed.', 'fast-woo-order-lookup');146 $ms2 = __( 'This happens with some WooCommerce plugins the author did not anticipate.', 'fast-woo-order-lookup');147 $ms3 = __( 'Please create a', 'fast-woo-order-lookup');148 $ms4 = __( 'support topic', 'fast-woo-order-lookup');149 $ms5 = __( 'and paste your', 'fast-woo-order-lookup');150 $ms6 = __( 'Site Health - Info', 'fast-woo-order-lookup');151 $ms7 = __( 'contents into it. Then', 'fast-woo-order-lookup');152 $ms8 = __( 'deactivate', 'fast-woo-order-lookup');153 $ms9 = __( 'the plugin.', 'fast-woo-order-lookup');154 if ($error) { 155 $ms1 = __('Fast Woo Order Lookup indexing failed.', 'fast-woo-order-lookup'); 156 $ms2 = __('This happens with some WooCommerce plugins the author did not anticipate.', 'fast-woo-order-lookup'); 157 $ms3 = __('Please create a', 'fast-woo-order-lookup'); 158 $ms4 = __('support topic', 'fast-woo-order-lookup'); 159 $ms5 = __('and paste your', 'fast-woo-order-lookup'); 160 $ms6 = __('Site Health - Info', 'fast-woo-order-lookup'); 161 $ms7 = __('contents into it. Then', 'fast-woo-order-lookup'); 162 $ms8 = __('deactivate', 'fast-woo-order-lookup'); 163 $ms9 = __('the plugin.', 'fast-woo-order-lookup'); 154 164 155 165 … … 157 167 <div class="notice notice-error"> 158 168 <p> 159 <?php echo esc_html( $ms1); ?>160 <?php echo esc_html( $ms2); ?>161 <?php echo esc_html( $ms3); ?>169 <?php echo esc_html($ms1); ?> 170 <?php echo esc_html($ms2); ?> 171 <?php echo esc_html($ms3); ?> 162 172 <a href="https://wordpress.org/support/plugin/fast-woo-order-lookup/" 163 target="_blank"><?php echo esc_html( $ms4); ?></a>164 <?php echo esc_html( $ms5); ?>165 <a href="/wp-admin/site-health.php?tab=debug" target="_blank"><?php echo esc_html( $ms6); ?></a>166 <?php echo esc_html( $ms7); ?>167 <a href=/wp-admin/plugins.php"><?php echo esc_html( $ms8); ?></a>168 <?php echo esc_html( $ms9); ?>173 target="_blank"><?php echo esc_html($ms4); ?></a> 174 <?php echo esc_html($ms5); ?> 175 <a href="/wp-admin/site-health.php?tab=debug" target="_blank"><?php echo esc_html($ms6); ?></a> 176 <?php echo esc_html($ms7); ?> 177 <a href=/wp-admin/plugins.php"><?php echo esc_html($ms8); ?></a> 178 <?php echo esc_html($ms9); ?> 169 179 </p></div> 170 180 <?php 171 } else if ( ! $this->textdex->is_ready( 10 )) {172 $sa1 = __( 'See the', 'fast-woo-order-lookup');173 $sa2 = __( 'Scheduled Actions status page', 'fast-woo-order-lookup');174 $sa3 = __( 'for details.', 'fast-woo-order-lookup');181 } else if (!$this->textdex->is_ready(10)) { 182 $sa1 = __('See the', 'fast-woo-order-lookup'); 183 $sa2 = __('Scheduled Actions status page', 'fast-woo-order-lookup'); 184 $sa3 = __('for details.', 'fast-woo-order-lookup'); 175 185 $frac = $this->textdex->fraction_complete(); 176 if ( $frac < 0.01) {177 $ms1 = __( 'Fast Woo Order Lookup indexing begins soon.', 'fast-woo-order-lookup');186 if ($frac < 0.01) { 187 $ms1 = __('Fast Woo Order Lookup indexing begins soon.', 'fast-woo-order-lookup'); 178 188 $ms2 = ''; 179 189 } else { 180 $percent = number_format( 100 * $this->textdex->fraction_complete(), 1);181 $ms1 = __( 'Fast Woo Order Lookup indexing still in progress.', 'fast-woo-order-lookup');190 $percent = number_format(100 * $this->textdex->fraction_complete(), 1); 191 $ms1 = __('Fast Woo Order Lookup indexing still in progress.', 'fast-woo-order-lookup'); 182 192 /* translators: 1: percent 12.3 */ 183 $ms2 = __( '%1$s%% complete.', 'fast-woo-order-lookup');184 $ms2 = sprintf( $ms2, $percent);193 $ms2 = __('%1$s%% complete.', 'fast-woo-order-lookup'); 194 $ms2 = sprintf($ms2, $percent); 185 195 } 186 196 ?> 187 197 <div class="notice notice-info"> 188 198 <p> 189 <?php echo esc_html( $ms1); ?>190 <?php echo esc_html( $ms2); ?>191 <?php echo esc_html( $sa1); ?>192 <a href="admin.php?page=wc-status&tab=action-scheduler&s=fast_woo_order_lookup_textdex_action&status=pending"><?php echo esc_html( $sa2); ?></a>193 <?php echo esc_html( $sa3); ?>199 <?php echo esc_html($ms1); ?> 200 <?php echo esc_html($ms2); ?> 201 <?php echo esc_html($sa1); ?> 202 <a href="admin.php?page=wc-status&tab=action-scheduler&s=fast_woo_order_lookup_textdex_action&status=pending"><?php echo esc_html($sa2); ?></a> 203 <?php echo esc_html($sa3); ?> 194 204 </p></div> 195 205 <?php … … 202 212 * @return void 203 213 */ 204 public function update_textdex() {205 if ( count( $this->orders_to_update ) > 0 ){206 $this->update_meta_keys( array_keys( $this->orders_to_update ) );207 $this-> textdex->update( array_keys( $this->orders_to_update ));208 }209 }210 214 public function update_textdex() 215 { 216 if (count($this->orders_to_update) > 0) { 217 $this->update_meta_keys(array_keys($this->orders_to_update)); 218 $this->textdex->update(array_keys($this->orders_to_update)); 219 } 220 } 211 221 212 222 /** … … 219 229 * @return array 220 230 */ 221 public function filter_search_fields( $search_fields ) { 222 if ( ! $this->textdex->is_ready() ) { 231 public function filter_search_fields($search_fields) 232 { 233 if (!$this->textdex->is_ready()) { 223 234 return $search_fields; 224 235 } 225 236 /* Hook to mung the queries. */ 226 237 $this->filtering = true; 227 add_filter( 'query', array( $this, 'standard_query' ), 1);238 add_filter('query', array($this, 'standard_query'), 1); 228 239 229 240 return $search_fields; … … 241 252 * @return array 242 253 */ 243 public function filter_search_results( $order_ids, $term, $search_fields ) { 244 245 if ( $this->filtering ) { 254 public function filter_search_results($order_ids, $term, $search_fields) 255 { 256 257 if ($this->filtering) { 246 258 /* Discontinue filtering queries after the metadata search */ 247 remove_filter( 'query', array( $this, 'standard_query' ), 1);259 remove_filter('query', array($this, 'standard_query'), 1); 248 260 $this->filtering = false; 249 261 } … … 261 273 * @return string 262 274 */ 263 public function standard_query( $query ) { 264 265 if ( ! $this->term ) { 266 $splits = explode( 'LIKE \'%', $query, 2 ); 267 if ( 2 !== count( $splits ) ) { 275 public function standard_query($query) 276 { 277 278 if (!$this->term) { 279 $splits = explode('LIKE \'%', $query, 2); 280 if (2 !== count($splits)) { 268 281 return $query; 269 282 } 270 $splits = explode( '%\'', $splits[1]);271 if ( 2 !== count( $splits )) {283 $splits = explode('%\'', $splits[1]); 284 if (2 !== count($splits)) { 272 285 return $query; 273 286 } 274 $this->term = $splits[0];275 $this->trigram_clause = $this->textdex->trigram_clause( $this->term);287 $this->term = $splits[0]; 288 $this->trigram_clause = $this->textdex->trigram_clause($this->term); 276 289 } 277 290 $newQuery = $query; 278 $munged = false;279 if ( str_contains( $newQuery, 'woocommerce_order_items as order_item' )) {280 $newQuery = str_replace( 'WHERE order_item_name LIKE', 'WHERE order_id IN (' . $this->trigram_clause . ') AND order_item_name LIKE', $newQuery);281 $munged = true;282 } else if ( str_contains( $newQuery, 'SELECT DISTINCT os.order_id FROM wp_wc_order_stats os' )) {291 $munged = false; 292 if (str_contains($newQuery, 'woocommerce_order_items as order_item')) { 293 $newQuery = str_replace('WHERE order_item_name LIKE', 'WHERE order_id IN (' . $this->trigram_clause . ') AND order_item_name LIKE', $newQuery); 294 $munged = true; 295 } else if (str_contains($newQuery, 'SELECT DISTINCT os.order_id FROM wp_wc_order_stats os')) { 283 296 /* empty, intentionally */ 284 297 } else { 285 $newQuery = str_replace( 'postmeta p1 WHERE ', 'postmeta p1 WHERE post_id IN (' . $this->trigram_clause . ') AND ', $newQuery);286 $munged = true;287 } 288 $munged && $this->textdex->capture_query( $newQuery, 'search', false);298 $newQuery = str_replace('postmeta p1 WHERE ', 'postmeta p1 WHERE post_id IN (' . $this->trigram_clause . ') AND ', $newQuery); 299 $munged = true; 300 } 301 $munged && $this->textdex->capture_query($newQuery, 'search', false); 289 302 290 303 return $newQuery; … … 300 313 * @return mixed 301 314 */ 302 public function woocommerce_order_query_args( $args ) { 303 $its_search = array_key_exists( 's', $args ) && is_string( $args['s'] ) && strlen( $args['s'] ) > 0; 304 $its_order_id_search = array_key_exists( 'search_filter', $args ) && 'order_id' === $args ['search_filter']; 305 if ( $its_search && ! $its_order_id_search && $this->textdex->is_ready() ) { 306 $this->term = $args['s']; 307 $this->trigram_clause = $this->textdex->trigram_clause( $this->term ); 315 public function woocommerce_order_query_args($args) 316 { 317 $its_search = array_key_exists('s', $args) && is_string($args['s']) && strlen($args['s']) > 0; 318 $its_order_id_search = array_key_exists('search_filter', $args) && 'order_id' === $args ['search_filter']; 319 if ($its_search && !$its_order_id_search && $this->textdex->is_ready()) { 320 $this->term = $args['s']; 321 $this->trigram_clause = $this->textdex->trigram_clause($this->term); 308 322 309 323 /* Hook to mung the queries. */ 310 324 $this->filtering = true; 311 add_filter( 'query', array( $this, 'hpos_query' ), 1);325 add_filter('query', array($this, 'hpos_query'), 1); 312 326 } 313 327 … … 325 339 * @return mixed 326 340 */ 327 public function woocommerce_order_query( $results, $args ) { 328 if ( $this->filtering ) { 341 public function woocommerce_order_query($results, $args) 342 { 343 if ($this->filtering) { 329 344 /* Discontinue filtering queries after the search */ 330 remove_filter( 'query', array( $this, 'hpos_query' ), 1);345 remove_filter('query', array($this, 'hpos_query'), 1); 331 346 $this->filtering = false; 332 347 } … … 348 363 * @return string 349 364 */ 350 public function hpos_query( $query ) { 365 public function hpos_query($query) 366 { 351 367 global $wpdb; 352 $orders = $wpdb->prefix . 'wc_orders';368 $orders = $wpdb->prefix . 'wc_orders'; 353 369 $orderitems = $wpdb->prefix . 'woocommerce_order_items'; 354 370 355 371 /* Skip modifying the FULLTEXT search option choice. */ 356 if ( str_contains( $query, 'IN BOOLEAN MODE' )) {372 if (str_contains($query, 'IN BOOLEAN MODE')) { 357 373 return $query; 358 374 } 359 if ( str_contains( $query, "$orderitems AS search_query_items ON search_query_items.order_id = $orders.id WHERE 1=1 AND") ||360 str_contains( $query, "SELECT $orders.id FROM $orders WHERE 1=1 AND") ||361 str_contains( $query, "SELECT COUNT(*) FROM $orders WHERE 1=1 AND") ||362 str_contains( $query, "SELECT COUNT(DISTINCT $orders.id) FROM $orders WHERE 1=1 AND")375 if (str_contains($query, "$orderitems AS search_query_items ON search_query_items.order_id = $orders.id WHERE 1=1 AND") || 376 str_contains($query, "SELECT $orders.id FROM $orders WHERE 1=1 AND") || 377 str_contains($query, "SELECT COUNT(*) FROM $orders WHERE 1=1 AND") || 378 str_contains($query, "SELECT COUNT(DISTINCT $orders.id) FROM $orders WHERE 1=1 AND") 363 379 ) { 364 $query = str_replace( 'WHERE 1=1 AND', "WHERE 1=1 AND $orders.id IN (" . $this->trigram_clause . ") AND ", $query);365 $this->textdex->capture_query( $query, 'search', false);380 $query = str_replace('WHERE 1=1 AND', "WHERE 1=1 AND $orders.id IN (" . $this->trigram_clause . ") AND ", $query); 381 $this->textdex->capture_query($query, 'search', false); 366 382 367 383 } … … 382 398 * @return array|null 383 399 */ 384 public function postmeta_get_order_custom_field_names( $keys, $order ) { 385 if ( ! @is_a( $order, WC_Order::class ) ) { 400 public function postmeta_get_order_custom_field_names($keys, $order) 401 { 402 if (!@is_a($order, WC_Order::class)) { 386 403 return $keys; 387 404 } 388 405 389 require_once( plugin_dir_path( __FILE__ ) . 'code/class-custom-fields.php');406 require_once(plugin_dir_path(__FILE__) . 'code/class-custom-fields.php'); 390 407 $cust = new Custom_Fields(); 391 408 … … 400 417 $changed = false; 401 418 foreach ( $orders as $order_id ) { 402 $order = wc_get_order( $order_id ); 403 $metas = wc_get_container()->get( OrdersTableDataStoreMeta::class )->read_meta( $order ); 404 foreach ( $metas as $meta ) { 405 $meta_key = $meta->meta_key; 406 if ( ! str_starts_with( $meta_key, '_' ) ) { 407 if ( ! in_array( $meta_key, $cached_keys ) ) { 408 $changed = true; 409 $cached_keys [] = $meta_key; 419 if ( $order_id ) { 420 $order = wc_get_order( $order_id ); 421 if ( $order instanceof WC_Order ) { 422 $metas = wc_get_container()->get( OrdersTableDataStoreMeta::class )->read_meta( $order ); 423 foreach ( $metas as $meta ) { 424 $meta_key = $meta->meta_key; 425 if ( ! str_starts_with( $meta_key, '_' ) ) { 426 if ( ! in_array( $meta_key, $cached_keys ) ) { 427 $changed = true; 428 $cached_keys [] = $meta_key; 429 } 430 } 410 431 } 411 432 } … … 425 446 * @return array<int, string> Updated array of the plugin's metadata. 426 447 */ 427 public function filter_plugin_row_meta( array $plugin_meta, $plugin_file ) { 428 if ( FAST_WOO_ORDER_LOOKUP_PLUGIN_BASE !== $plugin_file ) { 448 public function filter_plugin_row_meta(array $plugin_meta, $plugin_file) 449 { 450 if (FAST_WOO_ORDER_LOOKUP_PLUGIN_BASE !== $plugin_file) { 429 451 return $plugin_meta; 430 452 } 431 453 432 454 $plugin_meta[] = sprintf( 433 '<a href="%1$s"><span class="dashicons dashicons-star-filled" aria-hidden="true" style="font-size:14px;line-height:1.3"></span>%2$s</a>',434 'https://github.com/sponsors/OllieJones',435 esc_html_x( 'Sponsor', 'verb', 'index-wp-users-for-speed')455 '<a href="%1$s"><span class="dashicons dashicons-star-filled" aria-hidden="true" style="font-size:14px;line-height:1.3"></span>%2$s</a>', 456 'https://github.com/sponsors/OllieJones', 457 esc_html_x('Sponsor', 'verb', 'index-wp-users-for-speed') 436 458 ); 437 459 … … 443 465 444 466 // Plugin name 445 const FAST_WOO_ORDER_LOOKUP_NAME = 'Fast Woo Order Lookup';467 const FAST_WOO_ORDER_LOOKUP_NAME = 'Fast Woo Order Lookup'; 446 468 447 469 // Plugin version 448 const FAST_WOO_ORDER_LOOKUP_VERSION = '1.1.11';470 const FAST_WOO_ORDER_LOOKUP_VERSION = '1.2.0'; 449 471 450 472 // Plugin Root File 451 const FAST_WOO_ORDER_LOOKUP_PLUGIN_FILE = __FILE__;473 const FAST_WOO_ORDER_LOOKUP_PLUGIN_FILE = __FILE__; 452 474 453 475 // Plugin base 454 define( 'FAST_WOO_ORDER_LOOKUP_PLUGIN_BASE', plugin_basename( FAST_WOO_ORDER_LOOKUP_PLUGIN_FILE ));476 define('FAST_WOO_ORDER_LOOKUP_PLUGIN_BASE', plugin_basename(FAST_WOO_ORDER_LOOKUP_PLUGIN_FILE)); 455 477 456 478 // Plugin slug 457 define( 'FAST_WOO_ORDER_LOOKUP_SLUG', explode( DIRECTORY_SEPARATOR, FAST_WOO_ORDER_LOOKUP_PLUGIN_BASE )[0]);479 define('FAST_WOO_ORDER_LOOKUP_SLUG', explode(DIRECTORY_SEPARATOR, FAST_WOO_ORDER_LOOKUP_PLUGIN_BASE)[0]); 458 480 459 481 // Plugin Folder Path 460 define( 'FAST_WOO_ORDER_LOOKUP_PLUGIN_DIR', plugin_dir_path( FAST_WOO_ORDER_LOOKUP_PLUGIN_FILE ));482 define('FAST_WOO_ORDER_LOOKUP_PLUGIN_DIR', plugin_dir_path(FAST_WOO_ORDER_LOOKUP_PLUGIN_FILE)); 461 483 462 484 // Plugin Folder URL 463 define( 'FAST_WOO_ORDER_LOOKUP_PLUGIN_URL', plugin_dir_url( FAST_WOO_ORDER_LOOKUP_PLUGIN_FILE ));464 465 466 register_activation_hook( __FILE__, 'Fast_Woo_Order_Lookup\activate');467 register_deactivation_hook( __FILE__, 'Fast_Woo_Order_Lookup\deactivate');468 469 add_action( 'before_woocommerce_init', array( 'Fast_Woo_Order_Lookup\FastWooOrderLookup', 'declare_hpos_compatible' ));470 471 add_action( 'admin_init', function() {485 define('FAST_WOO_ORDER_LOOKUP_PLUGIN_URL', plugin_dir_url(FAST_WOO_ORDER_LOOKUP_PLUGIN_FILE)); 486 487 488 register_activation_hook(__FILE__, 'Fast_Woo_Order_Lookup\activate'); 489 register_deactivation_hook(__FILE__, 'Fast_Woo_Order_Lookup\deactivate'); 490 491 add_action('before_woocommerce_init', array('Fast_Woo_Order_Lookup\FastWooOrderLookup', 'declare_hpos_compatible')); 492 493 add_action('admin_init', function () { 472 494 FastWooOrderLookup::getInstance(); 473 }, 10, 0 );495 }, 10, 0); 474 496 475 497 /* Hook anything that changes an order object */ 476 add_action( 'woocommerce_new_order',477 array( 'Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_changing_order' ), 10, 2);478 add_action( 'woocommerce_update_order',479 array( 'Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_changing_order' ), 10, 2);480 add_action( 'woocommerce_order_object_updated_props',481 array( 'Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_order_object_updated_props' ), 10, 2);498 add_action('woocommerce_new_order', 499 array('Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_changing_order'), 10, 2); 500 add_action('woocommerce_update_order', 501 array('Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_changing_order'), 10, 2); 502 add_action('woocommerce_order_object_updated_props', 503 array('Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_order_object_updated_props'), 10, 2); 482 504 /* Hook changes to order status. */ 483 add_action( 'woocommerce_delete_order',484 array( 'Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_deleting_order' ));485 add_action( 'woocommerce_trash_order',486 array( 'Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_deleting_order' ));487 add_action( 'woocommerce_untrash_order',488 array( 'Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_deleting_order' ));489 add_action( 'woocommerce_cancelled_order',490 array( 'Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_deleting_order' ));491 add_action( 'update_post_meta',492 array( 'Fast_Woo_Order_Lookup\FastWooOrderLookup', 'update_post_meta' ), 10, 4);505 add_action('woocommerce_delete_order', 506 array('Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_deleting_order')); 507 add_action('woocommerce_trash_order', 508 array('Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_deleting_order')); 509 add_action('woocommerce_untrash_order', 510 array('Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_deleting_order')); 511 add_action('woocommerce_cancelled_order', 512 array('Fast_Woo_Order_Lookup\FastWooOrderLookup', 'woocommerce_deleting_order')); 513 add_action('update_post_meta', 514 array('Fast_Woo_Order_Lookup\FastWooOrderLookup', 'update_post_meta'), 10, 4); 493 515 494 516 /* ActionScheduler action for loading textdex. */ 495 add_action( 'fast_woo_order_lookup_textdex_action', 496 array( 'Fast_Woo_Order_Lookup\FastWooOrderLookup', 'textdex_batch_action' ) ); 497 498 function activate() { 499 register_uninstall_hook( __FILE__, 'Fast_Woo_Order_Lookup\uninstall' ); 500 require_once( plugin_dir_path( __FILE__ ) . 'code/class-textdex.php' ); 517 add_action('fast_woo_order_lookup_textdex_action', 518 array('Fast_Woo_Order_Lookup\FastWooOrderLookup', 'textdex_batch_action')); 519 520 function activate() 521 { 522 register_uninstall_hook(__FILE__, 'Fast_Woo_Order_Lookup\uninstall'); 523 require_once(plugin_dir_path(__FILE__) . 'code/class-textdex.php'); 501 524 $textdex = new Textdex(); 502 525 $textdex->activate(); … … 506 529 } 507 530 508 function deactivate() { 509 510 require_once( plugin_dir_path( __FILE__ ) . 'code/class-textdex.php' ); 531 function deactivate() 532 { 533 534 require_once(plugin_dir_path(__FILE__) . 'code/class-textdex.php'); 511 535 $textdex = new Textdex(); 512 536 $textdex->deactivate(); 513 delete_transient( FAST_WOO_ORDER_LOOKUP_METAKEY_CACHE);537 delete_transient(FAST_WOO_ORDER_LOOKUP_METAKEY_CACHE); 514 538 } 515 539 516 function uninstall() { 540 function uninstall() 541 { 517 542 518 543 } -
fast-woo-order-lookup/trunk/languages/fast-woo-order-lookup.pot
r3368869 r3380105 3 3 msgid "" 4 4 msgstr "" 5 "Project-Id-Version: Fast Woo Order Lookup 1. 1.11\n"5 "Project-Id-Version: Fast Woo Order Lookup 1.2.0\n" 6 6 "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/fast-woo-order-lookup\n" 7 7 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" … … 10 10 "Content-Type: text/plain; charset=UTF-8\n" 11 11 "Content-Transfer-Encoding: 8bit\n" 12 "POT-Creation-Date: 2025- 09-25T18:53:53-04:00\n"12 "POT-Creation-Date: 2025-10-17T08:33:40-04:00\n" 13 13 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 14 14 "X-Generator: WP-CLI 2.9.0\n" … … 16 16 17 17 #. Plugin Name of the plugin 18 #: code/class-textdex.php:6 8118 #: code/class-textdex.php:693 19 19 msgid "Fast Woo Order Lookup" 20 20 msgstr "" … … 36 36 msgstr "" 37 37 38 #: code/class-textdex.php:6 0138 #: code/class-textdex.php:613 39 39 msgid "Operation" 40 40 msgstr "" 41 41 42 #: code/class-textdex.php:6 5742 #: code/class-textdex.php:669 43 43 msgid "Explanation" 44 44 msgstr "" 45 45 46 #: code/class-textdex.php:6 5846 #: code/class-textdex.php:670 47 47 msgid "Errors sometimes occur while the plugin is creating its index table. Variations in database server make and version, and your WordPress version when you created it cause these. The plugin author will add suppot for your variation if you open a support topic." 48 48 msgstr "" 49 49 50 #: code/class-textdex.php:6 5950 #: code/class-textdex.php:671 51 51 msgid "And sometimes some types of orders cannot be found. Search for the failing orders and return here to capture useful troubleshooting information." 52 52 msgstr "" 53 53 54 #: code/class-textdex.php:6 6454 #: code/class-textdex.php:676 55 55 msgid "Request" 56 56 msgstr "" 57 57 58 #: code/class-textdex.php:6 6559 #: code/class-textdex.php:6 6758 #: code/class-textdex.php:677 59 #: code/class-textdex.php:679 60 60 msgid "Please create a support topic at" 61 61 msgstr "" 62 62 63 #: code/class-textdex.php:6 6663 #: code/class-textdex.php:678 64 64 msgid "Click [Copy Site Info To Clipboard] then paste your site info into the topic." 65 65 msgstr "" 66 66 67 #: code/class-textdex.php:6 6867 #: code/class-textdex.php:680 68 68 msgid "and paste this site info (all of it please) into the topic. We will take a look." 69 69 msgstr "" 70 70 71 #: code/class-textdex.php:6 7271 #: code/class-textdex.php:684 72 72 msgid "WooCommerce Features" 73 73 msgstr "" 74 74 75 #: code/class-textdex.php:6 7675 #: code/class-textdex.php:688 76 76 msgid "Trigram Table" 77 77 msgstr "" 78 78 79 #: fast-woo-order-lookup.php:1 4579 #: fast-woo-order-lookup.php:155 80 80 msgid "Fast Woo Order Lookup indexing failed." 81 81 msgstr "" 82 82 83 #: fast-woo-order-lookup.php:1 4683 #: fast-woo-order-lookup.php:156 84 84 msgid "This happens with some WooCommerce plugins the author did not anticipate." 85 85 msgstr "" 86 86 87 #: fast-woo-order-lookup.php:1 4787 #: fast-woo-order-lookup.php:157 88 88 msgid "Please create a" 89 89 msgstr "" 90 90 91 #: fast-woo-order-lookup.php:1 4891 #: fast-woo-order-lookup.php:158 92 92 msgid "support topic" 93 93 msgstr "" 94 94 95 #: fast-woo-order-lookup.php:1 4995 #: fast-woo-order-lookup.php:159 96 96 msgid "and paste your" 97 97 msgstr "" 98 98 99 #: fast-woo-order-lookup.php:1 5099 #: fast-woo-order-lookup.php:160 100 100 msgid "Site Health - Info" 101 101 msgstr "" 102 102 103 #: fast-woo-order-lookup.php:1 51103 #: fast-woo-order-lookup.php:161 104 104 msgid "contents into it. Then" 105 105 msgstr "" 106 106 107 #: fast-woo-order-lookup.php:1 52107 #: fast-woo-order-lookup.php:162 108 108 msgid "deactivate" 109 109 msgstr "" 110 110 111 #: fast-woo-order-lookup.php:1 53111 #: fast-woo-order-lookup.php:163 112 112 msgid "the plugin." 113 113 msgstr "" 114 114 115 #: fast-woo-order-lookup.php:1 72115 #: fast-woo-order-lookup.php:182 116 116 msgid "See the" 117 117 msgstr "" 118 118 119 #: fast-woo-order-lookup.php:1 73119 #: fast-woo-order-lookup.php:183 120 120 msgid "Scheduled Actions status page" 121 121 msgstr "" 122 122 123 #: fast-woo-order-lookup.php:1 74123 #: fast-woo-order-lookup.php:184 124 124 msgid "for details." 125 125 msgstr "" 126 126 127 #: fast-woo-order-lookup.php:1 77127 #: fast-woo-order-lookup.php:187 128 128 msgid "Fast Woo Order Lookup indexing begins soon." 129 129 msgstr "" 130 130 131 #: fast-woo-order-lookup.php:1 81131 #: fast-woo-order-lookup.php:191 132 132 msgid "Fast Woo Order Lookup indexing still in progress." 133 133 msgstr "" 134 134 135 135 #. translators: 1: percent 12.3 136 #: fast-woo-order-lookup.php:1 83136 #: fast-woo-order-lookup.php:193 137 137 msgid "%1$s%% complete." 138 138 msgstr "" -
fast-woo-order-lookup/trunk/readme.txt
r3368869 r3380105 5 5 Tags: woocommerce, search, orders, database, performance 6 6 Requires at least: 5.9 7 Tested up to: 6.8. 17 Tested up to: 6.8.3 8 8 Requires PHP: 5.6 9 9 WC requires at least: 8.0 10 10 WC tested up to: 10.2.1 11 Stable tag: 1. 1.1111 Stable tag: 1.2.0 12 12 Requires Plugins: woocommerce 13 13 License: GPLv2 … … 27 27 The downside: the trigram table takes database space and takes time to generate. 28 28 29 The orders page itself contains a slow query to look up meta_keys. This fixes that query's performance too .29 The orders page itself contains a slow query to look up meta_keys. This fixes that query's performance too, using a cache of available values. 30 30 31 31 <h4>If you have problems</h4> … … 58 58 Build a [trigram lookup table](https://www.plumislandmedia.net/wordpress-plugins/fast-woo-order-lookup/#how-does-it-work-trigrams), maintain it, and use it for the queries. 59 59 60 = How much space does the trigram lookup tabletake? =60 = How much space does the lookup table -- `wp_fwol` -- take? = 61 61 62 It takes about 5-10KiB per order, as MariaDB / MySQL database storage, counting both data and indexes. So, if your site has a million orders, the table will take something like 5-10 GiB. 62 It takes about 5-10KiB per order, as MariaDB / MySQL database storage, counting both data and indexes. So, if your site has a million orders, the table will take something like 5-10 GiB. The rows of the table are each quite small, just three letters and an order ID. And there are many of those rows for each order. 63 64 The table, named with an abbreviation for "Fast Woo Order Lookup", contains the trigram lookups. It has a terse name to keep queries short. It is dropped automatically if you deactivate the plugin. 65 66 = Can it get so large this plugin becomes useless or counterproductive? = 67 68 **No, unless your database tablespace is too small for it.** 69 70 This answer uses the [Big **O**](https://en.wikipedia.org/wiki/Big_O_notation) conceptual way of understanding program performance. 71 72 The table is organized by its primary key so this plugin can search for orders with **O**(log n) computational complexity. That means if searching 100 orders takes two seconds, then searching 1000 takes about three seconds and 10,000 about four. So it will work at large scale. And without this plugin the complexity of the order search in WooCommerce is a quite unpleasant **O**(n). Ten times as many orders take ten times as long to search. So, 100 times as many take 100 times as long. Used at large scale that gets nasty. It burns server electricity. Just as importantly, it wastes users' time. 73 74 That's true even if you use a nice search plugin like [Relevanssi](https://wordpress.org/plugins/relevanssi/) to help your customers search for products. The author does that. It works. But not on orders. 75 76 This plugin improves order search performance by using a better algorithm. It's the InnoDB team we have to thank for this in MariaDB and MySQL. Legendary. (See, Dr. Knuth? Somebody read your book!) 77 78 If your hosting service is such a cheapskate you don't have the tablespace for the table, that might be a reason to avoid this plugin. 63 79 64 80 = How long does it take to generate trigram lookup table? = … … 81 97 2. Deactivate, then activate the plugin. This rebuilds the lookup table. 82 98 83 = What is this wp_fwol table created by the plugin? =84 85 This table, named with an abbreviation for "Fast Woo Order Lookup", contains the trigram lookups. It has a terse name to keep queries short. It is dropped automatically if you deactivate the plugin.86 87 99 = My store only has a few hundred orders. Do I need this plugin ? = 88 100 89 This plugin addresses database performance problems that only show themselves on stores with many t ens of thousands of orders. If your store is smaller than that you probably don't need it.101 This plugin addresses database performance problems that only show themselves on stores with many thousands of orders. If your store is smaller than that you probably don't need it. 90 102 91 103 Wise owners of rapidly growing stores return regularly to examine their site performance. If your site is still small, it's better to wait until you actually need performance-enhancing plugins and other features. Installing them "just in case" is ineffective. … … 109 121 * It improves indexing performance by skipping gaps in order numbers. 110 122 111 ## Changelog 123 == Upgrade Notice == 124 125 Recent versions correct intermittent problems generating the index and maintaining the postmeta key cache. 126 127 Thanks to my loyal users for bringing these problems to my attention! 128 129 == Changelog == 130 131 = 1.2.0 = October 17, 2025 132 133 Correct an intermittent problem maintaining the postmeta key cache. Props tp slservice33 on w.org. 112 134 113 135 = 1.1.11 = September 24, 2025 = … … 115 137 WooCommerce 10.2.1, indexing defect fixed, gap skipping when indexing. Props to StefT1 on GitHub. 116 138 117 = 1.1.10 = July 3, 2025 =118 119 Less aggressive logging, WooCommerce 9.9.5.120 121 = 1.1.8 = May 22, 2025 =122 123 Support 9.9.0.124 125 = 1.1.7 = April 25, 2025 =126 127 Fix memory leak in logging.128 129 = 1.1.6 = April 11, 2025 =130 131 Fix memory leak in logging.132 133 = 1.1.5 April 9, 2025 =134 135 Improve Site Health Info.136 137 = 1.1.4 April 5, 2025 =138 139 Handle a COUNT(*) query in support of pagination.140
Note: See TracChangeset
for help on using the changeset viewer.