Version Description
- Improved error messages
- Add regex pattern validation before performing a search
- Fixed bug causing some searches to be identified as regex when they are not, leading to errors
- Fixed a bug that could cause the first file in every search chunk from being ignored
Download this release
Release Info
Developer | Clorith |
Plugin | String locator |
Version | 2.1.1 |
Comparing to | |
See all releases |
Code changes from version 2.1.0 to 2.1.1
- readme.txt +12 -1
- string-locator.php +102 -56
readme.txt
CHANGED
@@ -6,7 +6,7 @@ Donate link: https://www.paypal.me/clorith
|
|
6 |
Tags: theme, plugin, text, search, find, editor, syntax, highlight
|
7 |
Requires at least: 3.6
|
8 |
Tested up to: 4.7
|
9 |
-
Stable tag: 2.1.
|
10 |
License: GPLv2 or later
|
11 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
12 |
|
@@ -43,6 +43,11 @@ Although it will do it's best at detecting incorrect usage of the commonly used
|
|
43 |
|
44 |
As of version 1.6, the plugin will check your site health after performing an edit. If the site is returning a site breaking error code, we'll revert to the previous version of the file.
|
45 |
|
|
|
|
|
|
|
|
|
|
|
46 |
|
47 |
== Screenshots ==
|
48 |
|
@@ -51,6 +56,12 @@ As of version 1.6, the plugin will check your site health after performing an ed
|
|
51 |
3. Smart-Scan has detected an inconsistency in the use of braces
|
52 |
|
53 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
= 2.1.0 =
|
55 |
* Add support for configurations with infinite execution times
|
56 |
* Better code handling on RTL sites
|
6 |
Tags: theme, plugin, text, search, find, editor, syntax, highlight
|
7 |
Requires at least: 3.6
|
8 |
Tested up to: 4.7
|
9 |
+
Stable tag: 2.1.1
|
10 |
License: GPLv2 or later
|
11 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
12 |
|
43 |
|
44 |
As of version 1.6, the plugin will check your site health after performing an edit. If the site is returning a site breaking error code, we'll revert to the previous version of the file.
|
45 |
|
46 |
+
= My search is failing and I am told that my search is an invalid pattern =
|
47 |
+
This error is only related to regex searches, and is based off how PHP reads your regex string.
|
48 |
+
|
49 |
+
When writing your search string, make sure to wrap your search in forward slashes (`/`), directly followed by any modifiers like case insensitive (`i`) that you may want to use.
|
50 |
+
|
51 |
|
52 |
== Screenshots ==
|
53 |
|
56 |
3. Smart-Scan has detected an inconsistency in the use of braces
|
57 |
|
58 |
== Changelog ==
|
59 |
+
= 2.1.1 =
|
60 |
+
* Improved error messages
|
61 |
+
* Add regex pattern validation before performing a search
|
62 |
+
* Fixed bug causing some searches to be identified as regex when they are not, leading to errors
|
63 |
+
* Fixed a bug that could cause the first file in every search chunk from being ignored
|
64 |
+
|
65 |
= 2.1.0 =
|
66 |
* Add support for configurations with infinite execution times
|
67 |
* Better code handling on RTL sites
|
string-locator.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: String Locator
|
4 |
* Plugin URI: http://www.clorith.net/wordpress-string-locator/
|
5 |
* Description: Scan through theme and plugin files looking for text strings
|
6 |
-
* Version: 2.1.
|
7 |
* Author: Clorith
|
8 |
* Author URI: http://www.clorith.net
|
9 |
* Text Domain: string-locator
|
@@ -38,7 +38,7 @@ class String_Locator
|
|
38 |
* @var string $plugin_url The URL to the plugins directory
|
39 |
*/
|
40 |
public $string_locator_language = '';
|
41 |
-
public $version = '2.1.
|
42 |
public $notice = array();
|
43 |
public $failed_edit = false;
|
44 |
private $plugin_url = '';
|
@@ -50,25 +50,25 @@ class String_Locator
|
|
50 |
private $start_execution_timer = 0;
|
51 |
private $max_memory_consumption = 0;
|
52 |
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
/**
|
59 |
* Define class variables requiring expressions
|
60 |
*/
|
61 |
$this->plugin_url = plugin_dir_url( __FILE__ );
|
62 |
-
|
63 |
-
|
64 |
|
65 |
-
|
66 |
-
|
67 |
|
68 |
-
|
69 |
|
70 |
add_action( 'admin_menu', array( $this, 'populate_menu' ) );
|
71 |
-
|
72 |
|
73 |
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ), 11 );
|
74 |
|
@@ -77,12 +77,12 @@ class String_Locator
|
|
77 |
add_action( 'admin_init', array( $this, 'editor_save' ) );
|
78 |
add_action( 'admin_notices', array( $this, 'admin_notice' ) );
|
79 |
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
|
84 |
-
|
85 |
-
|
86 |
|
87 |
/**
|
88 |
* Sets up the memory limit variables
|
@@ -165,10 +165,10 @@ class String_Locator
|
|
165 |
*/
|
166 |
function get_plugins_options( $current = null ) {
|
167 |
$options = sprintf(
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
);
|
173 |
|
174 |
$string_locate_plugins = get_plugins();
|
@@ -308,14 +308,57 @@ class String_Locator
|
|
308 |
$file_data = unserialize( get_option( 'string-locator-search-files-' . $chunk ) );
|
309 |
|
310 |
if ( ! isset( $file_data[ $filenum ] ) ) {
|
311 |
-
wp_send_json_error(
|
|
|
|
|
|
|
|
|
|
|
312 |
}
|
313 |
|
314 |
if ( $this->nearing_execution_limit() ) {
|
315 |
-
wp_send_json_error(
|
|
|
|
|
|
|
|
|
|
|
|
|
316 |
}
|
317 |
if ( $this->nearing_memory_limit() ) {
|
318 |
-
wp_send_json_error(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
319 |
}
|
320 |
|
321 |
while ( ! $this->nearing_execution_limit() && ! $this->nearing_memory_limit() && isset( $file_data[ $filenum ]) ) {
|
@@ -334,6 +377,7 @@ class String_Locator
|
|
334 |
if ( ! isset( $file_data[ $filenum ] ) ) {
|
335 |
$chunk ++;
|
336 |
$file_data = unserialize( get_option( 'string-locator-search-files-' . $chunk ) );
|
|
|
337 |
}
|
338 |
|
339 |
$file_name = explode( "/", $file_data[ $filenum ] );
|
@@ -352,8 +396,7 @@ class String_Locator
|
|
352 |
/*
|
353 |
* Scan the file and look for our string
|
354 |
*/
|
355 |
-
|
356 |
-
$search_results = $this->scan_file( $file_data[ $filenum ], $scan_data->search, $file_data[ $filenum ], $scan_data->scan_path->type, '', ( isset( $scan_data->regex ) ? $scan_data->regex : false ) );
|
357 |
|
358 |
$response['last_file'] = $file_data[ $filenum ];
|
359 |
$response['filenum'] = $filenum;
|
@@ -702,23 +745,23 @@ class String_Locator
|
|
702 |
) );
|
703 |
}
|
704 |
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
|
723 |
function populate_network_menu()
|
724 |
{
|
@@ -731,11 +774,11 @@ class String_Locator
|
|
731 |
add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function, 'dashicons-edit' );
|
732 |
}
|
733 |
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
/**
|
740 |
* Don't load anything if the user can't edit themes any way
|
741 |
*/
|
@@ -755,7 +798,7 @@ class String_Locator
|
|
755 |
else {
|
756 |
include_once( dirname( __FILE__ ) . '/options.php' );
|
757 |
}
|
758 |
-
|
759 |
|
760 |
/**
|
761 |
* @param string $start Start delimited
|
@@ -1006,14 +1049,17 @@ class String_Locator
|
|
1006 |
$editurl = $this->create_edit_link( $path, $linenum );
|
1007 |
|
1008 |
$path_string = sprintf(
|
1009 |
-
|
1010 |
-
|
1011 |
-
|
1012 |
);
|
1013 |
|
1014 |
$output[] = array(
|
1015 |
'ID' => $match_count,
|
1016 |
-
'linenum' =>
|
|
|
|
|
|
|
1017 |
'path' => $path,
|
1018 |
'filename' => $path_string,
|
1019 |
'filename_raw' => $relativepath,
|
@@ -1115,8 +1161,8 @@ class String_Locator
|
|
1115 |
$files = array();
|
1116 |
|
1117 |
$paths = new RecursiveIteratorIterator(
|
1118 |
-
|
1119 |
-
|
1120 |
);
|
1121 |
|
1122 |
foreach ( $paths AS $name => $location ) {
|
3 |
* Plugin Name: String Locator
|
4 |
* Plugin URI: http://www.clorith.net/wordpress-string-locator/
|
5 |
* Description: Scan through theme and plugin files looking for text strings
|
6 |
+
* Version: 2.1.1
|
7 |
* Author: Clorith
|
8 |
* Author URI: http://www.clorith.net
|
9 |
* Text Domain: string-locator
|
38 |
* @var string $plugin_url The URL to the plugins directory
|
39 |
*/
|
40 |
public $string_locator_language = '';
|
41 |
+
public $version = '2.1.1';
|
42 |
public $notice = array();
|
43 |
public $failed_edit = false;
|
44 |
private $plugin_url = '';
|
50 |
private $start_execution_timer = 0;
|
51 |
private $max_memory_consumption = 0;
|
52 |
|
53 |
+
/**
|
54 |
+
* Construct the plugin
|
55 |
+
*/
|
56 |
+
function __construct()
|
57 |
+
{
|
58 |
/**
|
59 |
* Define class variables requiring expressions
|
60 |
*/
|
61 |
$this->plugin_url = plugin_dir_url( __FILE__ );
|
62 |
+
$this->path_to_use = ( is_multisite() ? 'network/admin.php' : 'tools.php' );
|
63 |
+
$this->excerpt_length = apply_filters( 'string_locator_excerpt_length', 25 );
|
64 |
|
65 |
+
$this->max_execution_time = ini_get( 'max_execution_time' );
|
66 |
+
$this->start_execution_timer = microtime( true );
|
67 |
|
68 |
+
$this->set_memory_limit();
|
69 |
|
70 |
add_action( 'admin_menu', array( $this, 'populate_menu' ) );
|
71 |
+
add_action( 'network_admin_menu', array( $this, 'populate_network_menu' ) );
|
72 |
|
73 |
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ), 11 );
|
74 |
|
77 |
add_action( 'admin_init', array( $this, 'editor_save' ) );
|
78 |
add_action( 'admin_notices', array( $this, 'admin_notice' ) );
|
79 |
|
80 |
+
add_action( 'wp_ajax_string-locator-get-directory-structure', array( $this, 'ajax_get_directory_structure' ) );
|
81 |
+
add_action( 'wp_ajax_string-locator-search', array( $this, 'ajax_file_search' ) );
|
82 |
+
add_action( 'wp_ajax_string-locator-clean', array( $this, 'ajax_clean_search' ) );
|
83 |
|
84 |
+
add_filter( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 2 );
|
85 |
+
}
|
86 |
|
87 |
/**
|
88 |
* Sets up the memory limit variables
|
165 |
*/
|
166 |
function get_plugins_options( $current = null ) {
|
167 |
$options = sprintf(
|
168 |
+
'<option value="%s" %s>— %s —</option>',
|
169 |
+
'p--',
|
170 |
+
( $current == 'p--' ? 'selected="selected"' : '' ),
|
171 |
+
esc_html( __( 'All plugins', 'string-locator' ) )
|
172 |
);
|
173 |
|
174 |
$string_locate_plugins = get_plugins();
|
308 |
$file_data = unserialize( get_option( 'string-locator-search-files-' . $chunk ) );
|
309 |
|
310 |
if ( ! isset( $file_data[ $filenum ] ) ) {
|
311 |
+
wp_send_json_error(
|
312 |
+
sprintf(
|
313 |
+
__( 'The file-number, %d, that was sent could not be found.', 'string-locator' ),
|
314 |
+
$filenum
|
315 |
+
)
|
316 |
+
);
|
317 |
}
|
318 |
|
319 |
if ( $this->nearing_execution_limit() ) {
|
320 |
+
wp_send_json_error(
|
321 |
+
sprintf(
|
322 |
+
__( 'The maximum time your server allows a script to run (%d) is too low for the plugin to run as intended, at startup %d seconds have passed', 'string-locator' ),
|
323 |
+
$this->max_execution_time,
|
324 |
+
$this->nearing_execution_limit()
|
325 |
+
)
|
326 |
+
);
|
327 |
}
|
328 |
if ( $this->nearing_memory_limit() ) {
|
329 |
+
wp_send_json_error(
|
330 |
+
sprintf(
|
331 |
+
__( 'The memory limit is about to be exceeded before the search has started, this could be an early indicator that your site may soon struggle as well, unfortunately this means the plugin is unable to perform any searches. Current memory consumption: %d of %d bytes', 'string-locator' ),
|
332 |
+
$this->nearing_memory_limit(),
|
333 |
+
$this->max_memory_consumption
|
334 |
+
)
|
335 |
+
);
|
336 |
+
}
|
337 |
+
|
338 |
+
$is_regex = false;
|
339 |
+
if ( isset( $scan_data->regex ) ) {
|
340 |
+
if ( is_bool( $scan_data->regex ) ) {
|
341 |
+
$is_regex = $scan_data->regex;
|
342 |
+
}
|
343 |
+
else {
|
344 |
+
if ( 'false' == $scan_data->regex ) {
|
345 |
+
$is_regex = false;
|
346 |
+
}
|
347 |
+
else {
|
348 |
+
$is_regex = true;
|
349 |
+
}
|
350 |
+
}
|
351 |
+
}
|
352 |
+
|
353 |
+
if ( $is_regex ) {
|
354 |
+
if ( false === @preg_match( $scan_data->search, '' ) ) {
|
355 |
+
wp_send_json_error(
|
356 |
+
sprintf(
|
357 |
+
__( 'Your search string, <strong>%s</strong>, is not a valid pattern, and the search has been aborted.', 'string-locator' ),
|
358 |
+
esc_html( $scan_data->search )
|
359 |
+
)
|
360 |
+
);
|
361 |
+
}
|
362 |
}
|
363 |
|
364 |
while ( ! $this->nearing_execution_limit() && ! $this->nearing_memory_limit() && isset( $file_data[ $filenum ]) ) {
|
377 |
if ( ! isset( $file_data[ $filenum ] ) ) {
|
378 |
$chunk ++;
|
379 |
$file_data = unserialize( get_option( 'string-locator-search-files-' . $chunk ) );
|
380 |
+
continue;
|
381 |
}
|
382 |
|
383 |
$file_name = explode( "/", $file_data[ $filenum ] );
|
396 |
/*
|
397 |
* Scan the file and look for our string
|
398 |
*/
|
399 |
+
$search_results = $this->scan_file( $file_data[ $filenum ], $scan_data->search, $file_data[ $filenum ], $scan_data->scan_path->type, '', $is_regex );
|
|
|
400 |
|
401 |
$response['last_file'] = $file_data[ $filenum ];
|
402 |
$response['filenum'] = $filenum;
|
745 |
) );
|
746 |
}
|
747 |
|
748 |
+
/**
|
749 |
+
* Add our plugin to the 'Tools' menu
|
750 |
+
*/
|
751 |
+
function populate_menu()
|
752 |
+
{
|
753 |
+
if ( is_multisite() ) {
|
754 |
+
return;
|
755 |
+
}
|
756 |
+
$page_title = __( 'String Locator', 'string-locator' );
|
757 |
+
$menu_title = __( 'String Locator', 'string-locator' );
|
758 |
+
$capability = 'edit_themes';
|
759 |
+
$parent_slug = 'tools.php';
|
760 |
+
$menu_slug = 'string-locator';
|
761 |
+
$function = array( $this, 'options_page' );
|
762 |
+
|
763 |
+
add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $function );
|
764 |
+
}
|
765 |
|
766 |
function populate_network_menu()
|
767 |
{
|
774 |
add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function, 'dashicons-edit' );
|
775 |
}
|
776 |
|
777 |
+
/**
|
778 |
+
* Function for including the actual plugin Admin UI page
|
779 |
+
*/
|
780 |
+
function options_page()
|
781 |
+
{
|
782 |
/**
|
783 |
* Don't load anything if the user can't edit themes any way
|
784 |
*/
|
798 |
else {
|
799 |
include_once( dirname( __FILE__ ) . '/options.php' );
|
800 |
}
|
801 |
+
}
|
802 |
|
803 |
/**
|
804 |
* @param string $start Start delimited
|
1049 |
$editurl = $this->create_edit_link( $path, $linenum );
|
1050 |
|
1051 |
$path_string = sprintf(
|
1052 |
+
'<a href="%s">%s</a>',
|
1053 |
+
esc_url( $editurl ),
|
1054 |
+
esc_html( $relativepath )
|
1055 |
);
|
1056 |
|
1057 |
$output[] = array(
|
1058 |
'ID' => $match_count,
|
1059 |
+
'linenum' => sprintf(
|
1060 |
+
'[%s]',
|
1061 |
+
esc_html__( 'Filename matches search', 'string-locator' )
|
1062 |
+
),
|
1063 |
'path' => $path,
|
1064 |
'filename' => $path_string,
|
1065 |
'filename_raw' => $relativepath,
|
1161 |
$files = array();
|
1162 |
|
1163 |
$paths = new RecursiveIteratorIterator(
|
1164 |
+
new RecursiveDirectoryIterator( $path ),
|
1165 |
+
RecursiveIteratorIterator::SELF_FIRST
|
1166 |
);
|
1167 |
|
1168 |
foreach ( $paths AS $name => $location ) {
|