String locator - Version 2.1.0

Version Description

  • Add support for configurations with infinite execution times
  • Better code handling on RTL sites
  • Exclude archive files, that we can't modify any way, from searches
  • Display file path in the editor to identify which file is being modified
  • Add support for RegEx string searches
Download this release

Release Info

Developer Clorith
Plugin Icon 128x128 String locator
Version 2.1.0
Comparing to
See all releases

Code changes from version 2.0.3 to 2.1.0

editor.php CHANGED
@@ -182,6 +182,20 @@
182
  }
183
  ?>
184
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
  <?php if ( ! empty( $function_help ) ) { ?>
186
  <div class="string-locator-details">
187
 
182
  }
183
  ?>
184
 
185
+ <div class="string-locator-details">
186
+ <div class="string-locator-theme-details">
187
+ <h2><?php esc_html_e( 'File information', 'string-locator' ); ?></h2>
188
+
189
+ <p>
190
+ <?php esc_html_e( 'File location:', 'string-locator' ); ?>
191
+ <br />
192
+ <span class="string-locator-italics">
193
+ <?php echo esc_html( str_replace( ABSPATH, '', $file ) ); ?>
194
+ </span>
195
+ </p>
196
+ </div>
197
+ </div>
198
+
199
  <?php if ( ! empty( $function_help ) ) { ?>
200
  <div class="string-locator-details">
201
 
languages/string-locator-de_DE.po DELETED
@@ -1,198 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: String Locator\n"
4
- "POT-Creation-Date: 2015-08-23 19:38+0200\n"
5
- "PO-Revision-Date: 2015-08-23 19:38+0200\n"
6
- "Last-Translator: pixolin <pixolin@gmx.com>\n"
7
- "Language-Team: pixolin <pixolin@gmx.com>\n"
8
- "Language: de_DE\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "X-Generator: Poedit 1.8.4\n"
13
- "X-Poedit-Basepath: ..\n"
14
- "X-Poedit-WPHeader: string-locator.php\n"
15
- "X-Poedit-SourceCharset: UTF-8\n"
16
- "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;"
17
- "esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;_n_noop:1,2;"
18
- "_nx_noop:3c,1,2;__ngettext_noop:1,2\n"
19
- "Plural-Forms: nplurals=2; plural=(n != 1);\n"
20
- "X-Poedit-SearchPath-0: .\n"
21
- "X-Poedit-SearchPathExcluded-0: *.js\n"
22
-
23
- #: editor.php:68
24
- msgid "String Locator - Code Editor"
25
- msgstr "String-Locator - Code-Editor"
26
-
27
- #: editor.php:69
28
- msgid "Return to search results"
29
- msgstr "Zu Suchergebnissen zurückkehren"
30
-
31
- #: editor.php:82
32
- msgid "By"
33
- msgstr "Von"
34
-
35
- #: editor.php:94
36
- msgid ""
37
- "Enable a smart-scan of your code to help detect bracket mismatches before "
38
- "saving."
39
- msgstr ""
40
- "Aktiviere eine intelligente Code-Suche, um fehlenden Klammern vor dem "
41
- "Speichern aufzuspüren."
42
-
43
- #: editor.php:110
44
- msgid "Save changes"
45
- msgstr "Änderungen speichern"
46
-
47
- #: editor.php:163
48
- msgid "WordPress Functions"
49
- msgstr "WordPress-Funktionen"
50
-
51
- #. Plugin Name of the plugin/theme
52
- #: options.php:12 string-locator.php:200 string-locator.php:201
53
- #: string-locator.php:212 string-locator.php:213
54
- msgid "String Locator"
55
- msgstr "String Locator"
56
-
57
- #: options.php:16
58
- msgid "Search through"
59
- msgstr "Durchsuche"
60
-
61
- #: options.php:18
62
- msgid "Core"
63
- msgstr "Core"
64
-
65
- #: options.php:19
66
- msgid "The whole WordPress directory"
67
- msgstr "das gesamte WordPress-Verzeichnis"
68
-
69
- #: options.php:21
70
- msgid "Themes"
71
- msgstr "Themes"
72
-
73
- #: options.php:22
74
- msgid "All themes"
75
- msgstr "Alle Themes"
76
-
77
- #: options.php:37
78
- msgid "Plugins"
79
- msgstr "Plugins"
80
-
81
- #: options.php:38
82
- msgid "All plugins"
83
- msgstr "Alle Plugins"
84
-
85
- #: options.php:54
86
- msgid "Search string"
87
- msgstr "Zeichenkette suchen"
88
-
89
- #: options.php:58
90
- msgid "Search"
91
- msgstr "Suche"
92
-
93
- #: options.php:59
94
- msgid "Restore last search"
95
- msgstr "Wiederherstellen der letzten Suche"
96
-
97
- #: string-locator.php:286
98
- msgid ""
99
- "The file could not be written to, please check file permissions or edit it "
100
- "manually."
101
- msgstr ""
102
- "An der Datei konnten keine Änderungen vorgenommen werden. Bitte prüfe die "
103
- "Datei-Berechtigungen oder ändere die Datei von Hand."
104
-
105
- #: string-locator.php:307
106
- #, php-format
107
- msgid ""
108
- "There is an inconsistency in the opening and closing braces, { and }, of "
109
- "your file on line %s"
110
- msgstr ""
111
- "Beim Öffnen und Schließen geschwungener Klammern { und } gibt es "
112
- "Unstimmigkeiten in Zeile %s deiner Datei."
113
-
114
- #: string-locator.php:325
115
- #, php-format
116
- msgid ""
117
- "There is an inconsistency in the opening and closing braces, [ and ], of "
118
- "your file on line %s"
119
- msgstr ""
120
- "Beim Öffnen und Schließen eckiger Klammern [ und ] gibt es Unstimmigkeiten "
121
- "in Zeile %s deiner Datei."
122
-
123
- #: string-locator.php:343
124
- #, php-format
125
- msgid ""
126
- "There is an inconsistency in the opening and closing braces, ( and ), of "
127
- "your file on line %s"
128
- msgstr ""
129
- "Beim Öffnen und Schließen von runden Klammern ( und ) gibt es "
130
- "Unstimmigkeiten in Zeile %s deiner Datei."
131
-
132
- #: string-locator.php:374
133
- msgid ""
134
- "A 500 server error was detected on your site after updating your file. We "
135
- "have restored the previous version of the file for you."
136
- msgstr ""
137
- "Auf deiner Website ist nach dem Aktualisieren der Datei ein Serverfehler 500 "
138
- "aufgetreten. Die vorherige Version der Datei wurde wiederhergestellt."
139
-
140
- #: string-locator.php:380
141
- msgid "The file has been saved"
142
- msgstr "Die Datei wurde gespeichert"
143
-
144
- #: string-locator.php:526
145
- msgid "Could not read file: "
146
- msgstr "Datei konnte nicht gelesen werden:"
147
-
148
- #: table-controller.php:13
149
- msgid "String"
150
- msgstr "Zeichenkette"
151
-
152
- #: table-controller.php:14
153
- msgid "File"
154
- msgstr "Datei"
155
-
156
- #: table-controller.php:15
157
- msgid "Line number"
158
- msgstr ""
159
-
160
- #: table-controller.php:30
161
- msgid "Your string was not present in any of the available files."
162
- msgstr "Deine Zeichenkette war in keiner der vorhandenen Datei enthalten. "
163
-
164
- #: table-controller.php:74
165
- msgid "Edit"
166
- msgstr ""
167
-
168
- #. Plugin URI of the plugin/theme
169
- msgid "http://www.clorith.net/wordpress-string-locator/"
170
- msgstr ""
171
-
172
- #. Description of the plugin/theme
173
- msgid "Scan through theme and plugin files looking for text strings"
174
- msgstr "Durchsuche Theme- und Plugin-Dateien nach Zeichenketten"
175
-
176
- #. Author of the plugin/theme
177
- msgid "Clorith"
178
- msgstr ""
179
-
180
- #. Author URI of the plugin/theme
181
- msgid "http://www.clorith.net"
182
- msgstr ""
183
-
184
- #~ msgid "<strong>Warning:</strong> You appear to be editing a Core file."
185
- #~ msgstr "<strong>Warnung:</strong> Du scheinst eine Core-Datei zu ändern."
186
-
187
- #~ msgid ""
188
- #~ "Keep in mind that edits to core files will be lost when WordPress is "
189
- #~ "updated."
190
- #~ msgstr ""
191
- #~ "Bitte denke daran, dass Änderungen an Core-Dateien bei einer "
192
- #~ "Aktualisierung von WordPress verloren gehen."
193
-
194
- #~ msgid "the whole WordPress directory"
195
- #~ msgstr "das gesamte WordPress-Verzeichnis"
196
-
197
- #~ msgid "Line"
198
- #~ msgstr "Zeile"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
options.php CHANGED
@@ -3,6 +3,7 @@
3
 
4
  $search_string = '';
5
  $search_location = '';
 
6
 
7
  if ( isset( $_POST['string-locator-string'] ) ) {
8
  $search_string = $_POST['string-locator-string'];
@@ -16,6 +17,7 @@
16
 
17
  $search_string = $restore->search;
18
  $search_location = $restore->directory;
 
19
  }
20
  ?>
21
  <div class="wrap">
@@ -41,6 +43,8 @@
41
  <label for="string-locator-string"><?php _e( 'Search string', 'string-locator' ); ?></label>
42
  <input type="text" name="string-locator-string" id="string-locator-string" value="<?php echo esc_attr( $search_string ); ?>" />
43
 
 
 
44
  <p>
45
  <input type="submit" name="submit" id="submit" class="button button-primary" value="<?php _e( 'Search', 'string-locator' ); ?>">
46
  <a href="<?php echo esc_url( $this_url . '&restore=true' ); ?>" class="button button-primary"><?php _e( 'Restore last search', 'string-locator' ); ?></a>
3
 
4
  $search_string = '';
5
  $search_location = '';
6
+ $search_regex = false;
7
 
8
  if ( isset( $_POST['string-locator-string'] ) ) {
9
  $search_string = $_POST['string-locator-string'];
17
 
18
  $search_string = $restore->search;
19
  $search_location = $restore->directory;
20
+ $search_regex = $restore->regex;
21
  }
22
  ?>
23
  <div class="wrap">
43
  <label for="string-locator-string"><?php _e( 'Search string', 'string-locator' ); ?></label>
44
  <input type="text" name="string-locator-string" id="string-locator-string" value="<?php echo esc_attr( $search_string ); ?>" />
45
 
46
+ <label><input type="checkbox" name="string-locator-regex" id="string-locator-regex"<?php echo ( $search_regex ? ' checked="checked"' : '' ); ?>'> RegEx search</label>
47
+
48
  <p>
49
  <input type="submit" name="submit" id="submit" class="button button-primary" value="<?php _e( 'Search', 'string-locator' ); ?>">
50
  <a href="<?php echo esc_url( $this_url . '&restore=true' ); ?>" class="button button-primary"><?php _e( 'Restore last search', 'string-locator' ); ?></a>
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.0.3
10
  License: GPLv2 or later
11
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
 
@@ -51,6 +51,13 @@ 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.0.3 =
55
  * Added support for HHVM
56
  * Improved inline documentation
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.0
10
  License: GPLv2 or later
11
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
 
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
57
+ * Exclude archive files, that we can't modify any way, from searches
58
+ * Display file path in the editor to identify which file is being modified
59
+ * Add support for RegEx string searches
60
+
61
  = 2.0.3 =
62
  * Added support for HHVM
63
  * Improved inline documentation
resources/css/string-locator.css CHANGED
@@ -34,6 +34,7 @@ table.tools_page_string-locator.restore {
34
  margin-right: 3%;
35
  vertical-align: top;
36
  width: 70%;
 
37
  }
38
 
39
  .string-locator-sidebar-wrap {
@@ -71,6 +72,10 @@ table.tools_page_string-locator.restore {
71
  width: 100%;
72
  }
73
 
 
 
 
 
74
  /* Media Queries for responsive behavior */
75
  @media (max-width: 1065px) {
76
  .string-locator-edit-wrap {
34
  margin-right: 3%;
35
  vertical-align: top;
36
  width: 70%;
37
+ direction: ltr;
38
  }
39
 
40
  .string-locator-sidebar-wrap {
72
  width: 100%;
73
  }
74
 
75
+ .string-locator-italics {
76
+ font-style: italic;
77
+ }
78
+
79
  /* Media Queries for responsive behavior */
80
  @media (max-width: 1065px) {
81
  .string-locator-edit-wrap {
resources/js/string-locator-search.js CHANGED
@@ -112,6 +112,7 @@ jQuery(document).ready(function ($) {
112
  action : 'string-locator-get-directory-structure',
113
  directory : $("#string-locator-search").val(),
114
  search : $("#string-locator-string").val(),
 
115
  nonce : string_locator.search_nonce
116
  };
117
 
112
  action : 'string-locator-get-directory-structure',
113
  directory : $("#string-locator-search").val(),
114
  search : $("#string-locator-string").val(),
115
+ regex : $("#string-locator-regex").is(':checked'),
116
  nonce : string_locator.search_nonce
117
  };
118
 
string-locator.php CHANGED
@@ -3,13 +3,13 @@
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.0.3
7
  * Author: Clorith
8
  * Author URI: http://www.clorith.net
9
  * Text Domain: string-locator
10
  * License: GPL2
11
  *
12
- * Copyright 2013 Marius Jensen (email : marius@clorith.net)
13
  *
14
  * This program is free software; you can redistribute it and/or modify
15
  * it under the terms of the GNU General Public License, version 2, as
@@ -26,133 +26,28 @@
26
  */
27
 
28
  /**
29
- * The primary plugin class.
30
- *
31
- * The String_Locator class contains the functions required to search, edit, and safeguard edits within the plugin.
32
- *
33
- * @since 1.0.0
34
  */
35
  class String_Locator
36
  {
37
  /**
38
- * The code language used for the editing page.
39
- *
40
- * @access public
41
- *
42
- * @since 1.2.0
43
- *
44
- * @var string $string_locator_language
45
  */
46
  public $string_locator_language = '';
47
-
48
- /**
49
- * String Locator version number.
50
- *
51
- * @access public
52
- *
53
- * @since 1.2.0
54
- *
55
- * @var string $version
56
- */
57
- public $version = '2.0.3';
58
-
59
- /**
60
- * An array containing all notices to display.
61
- *
62
- * @access public
63
- *
64
- * @since 1.2.0
65
- *
66
- * @var array $notice
67
- */
68
  public $notice = array();
69
-
70
- /**
71
- * Has there been a failed edit.
72
- *
73
- * @access public
74
- *
75
- * @since 1.2.0
76
- *
77
- * @var bool $failed_edit
78
- */
79
  public $failed_edit = false;
80
-
81
- /**
82
- * The URL to the plugins directory.
83
- *
84
- * @access private
85
- *
86
- * @since 1.2.0
87
- *
88
- * @var string $plugin_url
89
- */
90
  private $plugin_url = '';
91
-
92
- /**
93
- * Holds the path to the plugins pages within wp-admin based on the site setup.
94
- *
95
- * @access private
96
- *
97
- * @since 1.5.0
98
- *
99
- * @var string
100
- */
101
  private $path_to_use = '';
102
-
103
- /**
104
- * An array of HTTP codes considered to have "broken" a website.
105
- *
106
- * @access private
107
- *
108
- * @since 1.6.0
109
- *
110
- * @var array
111
- */
112
  private $bad_http_codes = array( '500' );
113
-
114
- /**
115
- * The length of an excerpt from a file matching our search.
116
- *
117
- * @access private
118
- *
119
- * @since 1.7.0
120
- *
121
- * @var int
122
- */
123
  private $excerpt_length = 25;
124
-
125
- /**
126
- * The maximum execution time of PHP.
127
- *
128
- * @access private
129
- *
130
- * @since 1.9.0
131
- *
132
- * @var int
133
- */
134
- private $max_execution_time = 0;
135
-
136
- /**
137
- * The current time when execution began.
138
- *
139
- * @access private
140
- *
141
- * @since 1.9.0
142
- *
143
- * @var int
144
- */
145
  private $start_execution_timer = 0;
146
-
147
- /**
148
- * The maximum amount of memory available to PHP.
149
- *
150
- * @access private
151
- *
152
- * @since 2.0.0
153
- *
154
- * @var int
155
- */
156
  private $max_memory_consumption = 0;
157
 
158
  /**
@@ -160,21 +55,18 @@ class String_Locator
160
  */
161
  function __construct()
162
  {
163
- /*
164
- * Set up execution limitations
165
- */
166
- $this->set_max_execution_time();
167
- $this->set_memory_limit();
168
-
169
- /*
170
  * Define class variables requiring expressions
171
  */
172
  $this->plugin_url = plugin_dir_url( __FILE__ );
173
  $this->path_to_use = ( is_multisite() ? 'network/admin.php' : 'tools.php' );
174
  $this->excerpt_length = apply_filters( 'string_locator_excerpt_length', 25 );
175
 
 
176
  $this->start_execution_timer = microtime( true );
177
 
 
 
178
  add_action( 'admin_menu', array( $this, 'populate_menu' ) );
179
  add_action( 'network_admin_menu', array( $this, 'populate_network_menu' ) );
180
 
@@ -188,35 +80,13 @@ class String_Locator
188
  add_action( 'wp_ajax_string-locator-get-directory-structure', array( $this, 'ajax_get_directory_structure' ) );
189
  add_action( 'wp_ajax_string-locator-search', array( $this, 'ajax_file_search' ) );
190
  add_action( 'wp_ajax_string-locator-clean', array( $this, 'ajax_clean_search' ) );
191
- }
192
 
193
- /**
194
- * Check what system PHP runs as.
195
- *
196
- * Currently this is only used to check if HHVM is being used, but may need ot be expanded in the future
197
- * as new systems pop up that require quirks for proper behavior.
198
- *
199
- * @since 2.0.3
200
- *
201
- * @param string $system The system being used.
202
- *
203
- * @return bool
204
- */
205
- function is_specific_system( $system ) {
206
- if ( 'HHVM' == $system ) {
207
- return defined( 'HHVM_VERSION' );
208
- }
209
-
210
- return false;
211
  }
212
 
213
  /**
214
  * Sets up the memory limit variables
215
  *
216
- * @uses String_Locator::is_valid_location()
217
- * @uses apply_filters()
218
- * @uses absint()
219
- *
220
  * @since 2.0.0
221
  *
222
  * @return void
@@ -224,21 +94,6 @@ class String_Locator
224
  function set_memory_limit() {
225
  $memory_limit = ini_get( 'memory_limit' );
226
 
227
- if ( empty( $memory_limit ) && $this->is_specific_system( 'HHVM' ) ) {
228
- /*
229
- * Some versions of HHVM have a ini_get bug which returns a blank value.
230
- *
231
- * This check is in place to set the HHVM default value if this is the case.
232
- *
233
- * As of https://github.com/facebook/hhvm/commit/91cf450b8ec25b849274fe19e1e66dd5380e4ea6 the default
234
- * value was set to 1GiB, so this is what we'll base our selves off
235
- *
236
- * The filter allows for this value to be overridden by a mu-plugin or similar for those who know the
237
- * value in use by their system until HHVM allows for a more exact config reading.
238
- */
239
- $memory_limit = apply_filters( 'string-locator-hhvm-memory-limit', '1G');
240
- }
241
-
242
  $this->max_memory_consumption = absint( $memory_limit );
243
 
244
  if ( strstr( $memory_limit, 'k' ) ) {
@@ -253,24 +108,25 @@ class String_Locator
253
  }
254
 
255
  /**
256
- * Sets up the max execution time variables
257
- *
258
- * @since 2.0.3
259
  *
260
- * @return void
261
  */
262
- function set_max_execution_time() {
263
- $this->max_execution_time = ini_get( 'max_execution_time' );
 
 
 
 
 
 
 
264
  }
265
 
266
  /**
267
  * Create a set of drop-down options for picking one of the available themes
268
  *
269
- * @uses esc_html()
270
- * @uses __()
271
- * @uses wp_get_themes()
272
- * @uses wp_get_theme()
273
- *
274
  * @param string $current The current selection option to match against
275
  *
276
  * @return string
@@ -303,9 +159,6 @@ class String_Locator
303
  /**
304
  * Create a set of drop-down options for picking one of the available plugins
305
  *
306
- * @uses esc_html()
307
- * @uses __()
308
- *
309
  * @param string $current The current selection option to match against
310
  *
311
  * @return string
@@ -338,14 +191,6 @@ class String_Locator
338
  /**
339
  * Handles the AJAX request to prepare the search hierarchy
340
  *
341
- * @uses check_ajax_referer()
342
- * @uses wp_send_json_error()
343
- * @uses String_Locator::prepare_scan_path()
344
- * @uses String_Locator::ajax_scan_path()
345
- * @uses wp_unslash()
346
- * @uses update_option()
347
- * @uses wp_send_json_success()
348
- *
349
  * @return object
350
  */
351
  function ajax_get_directory_structure() {
@@ -369,14 +214,16 @@ class String_Locator
369
  'scan_path' => $scan_path,
370
  'search' => wp_unslash( $_POST['search'] ),
371
  'directory' => $_POST['directory'],
372
- 'chunks' => count( $file_chunks )
 
373
  );
374
 
375
  $response = array(
376
  'total' => count( $files ),
377
  'current' => 0,
378
  'directory' => $scan_path,
379
- 'chunks' => count( $file_chunks )
 
380
  );
381
 
382
  update_option( 'string-locator-search-overview', serialize( $store ), true );
@@ -392,13 +239,16 @@ class String_Locator
392
  /**
393
  * Check if the script is about to exceed the max execution time.
394
  *
395
- * @uses apply_filters()
396
- *
397
  * @since 1.9.0
398
  *
399
  * @return bool
400
  */
401
  function nearing_execution_limit() {
 
 
 
 
 
402
  $built_in_delay = apply_filters( 'string-locator-extra-search-delay', 2 );
403
  $execution_time = ( microtime( true ) - $this->start_execution_timer + $built_in_delay );
404
 
@@ -411,8 +261,6 @@ class String_Locator
411
  /**
412
  * Check if the script is about to exceed the server memory limit.
413
  *
414
- * @uses apply_filters()
415
- *
416
  * @since 2.0.0
417
  *
418
  * @return bool
@@ -431,18 +279,9 @@ class String_Locator
431
  /**
432
  * Search an individual file supplied via AJAX
433
  *
434
- * @uses check_ajax_referer()
435
- * @uses wp_send_json_error()
436
- * @uses apply_filters()
437
- * @uses absint()
438
- * @uses get_option()
439
- * @uses maybe_unserialize()
440
- * @uses update_option()
441
- * @uses wp_send_json_success()
442
- *
443
  * @since 1.9.0
444
  *
445
- * @return void
446
  */
447
  function ajax_file_search() {
448
  if ( ! check_ajax_referer( 'string-locator-search', 'nonce', false ) ) { wp_send_json_error( __( 'Authentication failed', 'string-locator' ) ); }
@@ -500,7 +339,21 @@ class String_Locator
500
  $file_name = explode( "/", $file_data[ $filenum ] );
501
  $file_name = end( $file_name );
502
 
503
- $search_results = $this->scan_file( $file_data[ $filenum ], $scan_data->search, $file_data[ $filenum ], $scan_data->scan_path->type, '' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
504
 
505
  $response['last_file'] = $file_data[ $filenum ];
506
  $response['filenum'] = $filenum;
@@ -528,13 +381,7 @@ class String_Locator
528
  /**
529
  * Clean up our options used to help during the search
530
  *
531
- * @uses check_ajax_referer()
532
- * @uses wp_send_json_error()
533
- * @uses get_option()
534
- * @uses delete_option()
535
- * @uses wp_send_json_success()
536
- *
537
- * @return void
538
  */
539
  function ajax_clean_search() {
540
  if ( ! check_ajax_referer( 'string-locator-search', 'nonce', false ) ) { wp_send_json_error( __( 'Authentication failed', 'string-locator' ) ); }
@@ -550,9 +397,6 @@ class String_Locator
550
  /**
551
  * Create a table row for insertion into the search results list
552
  *
553
- * @uses esc_url()
554
- * @uses esc_html()
555
- *
556
  * @param array|object $item The table row item
557
  *
558
  * @return string
@@ -578,9 +422,6 @@ class String_Locator
578
  /**
579
  * Create a full table populated with the supplied items
580
  *
581
- * @uses esc_html()
582
- * @uses __()
583
- *
584
  * @param array $items An array of table rows
585
  * @param array $table_class An array of items to append to the table class along with the defaults
586
  *
@@ -625,9 +466,6 @@ class String_Locator
625
  /**
626
  * Create an admin edit link for the supplied path
627
  *
628
- * @uses absint()
629
- * @uses admin_url()
630
- *
631
  * @param string $path
632
  * @param int $line
633
  *
@@ -752,10 +590,6 @@ class String_Locator
752
 
753
  /**
754
  * Set the text domain for translated plugin content
755
- *
756
- * @uses load_plugin_textdomain()
757
- *
758
- * @return void
759
  */
760
  function load_i18n() {
761
  $i18n_dir = 'string-locator/languages/';
@@ -764,17 +598,6 @@ class String_Locator
764
 
765
  /**
766
  * Load up JavaScript and CSS for our plugin on the appropriate admin pages
767
- *
768
- * @uses wp_register_style()
769
- * @uses plugin_dir_url()
770
- * @uses wp_register_script()
771
- * @uses admin_url()
772
- * @uses wp_create_nonce()
773
- * @uses wp_enqueue_style()
774
- * @uses wp_enqueue_script()
775
- * @uses wp_localize_script()
776
- *
777
- * @return void
778
  */
779
  function admin_enqueue_scripts( $hook ) {
780
  // Break out early if we are not on a String Locator page
@@ -880,13 +703,7 @@ class String_Locator
880
  }
881
 
882
  /**
883
- * Add our plugin to the 'Tools' menu.
884
- *
885
- * @uses is_multisite()
886
- * @uses __()
887
- * @uses add_submenu_page()
888
- *
889
- * @return void
890
  */
891
  function populate_menu()
892
  {
@@ -903,14 +720,6 @@ class String_Locator
903
  add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $function );
904
  }
905
 
906
- /**
907
- * Add our plugin to the top level menu in multisite.
908
- *
909
- * @uses __()
910
- * @uses add_menu_page()
911
- *
912
- * @return void
913
- */
914
  function populate_network_menu()
915
  {
916
  $page_title = __( 'String Locator', 'string-locator' );
@@ -923,23 +732,18 @@ class String_Locator
923
  }
924
 
925
  /**
926
- * Function for including the actual plugin Admin UI page.
927
- *
928
- * @uses current_user_can()
929
- * @uses String_Locator::is_valid_location()
930
- *
931
- * @return void
932
  */
933
  function options_page()
934
  {
935
- /*
936
  * Don't load anything if the user can't edit themes any way
937
  */
938
  if ( ! current_user_can( 'edit_themes' ) ) {
939
- return;
940
  }
941
 
942
- /*
943
  * Show the edit page if;
944
  * - The edit file path query var is set
945
  * - The edit file path query var isn't empty
@@ -954,12 +758,9 @@ class String_Locator
954
  }
955
 
956
  /**
957
- * Check for mismatching start and end parameters (such as opening and closing parenthesis).
958
- *
959
  * @param string $start Start delimited
960
  * @param string $end End delimiter
961
  * @param string $string The string to scan
962
- *
963
  * @return array
964
  */
965
  function SmartScan( $start, $end, $string ) {
@@ -979,17 +780,8 @@ class String_Locator
979
  }
980
 
981
  /**
982
- * Handler for storing the content of the code editor.
983
- * This is also when we invoke the Smart-Scan if enabled.
984
- *
985
- * @uses check_admin_referer()
986
- * @uses current_user_can()
987
- * @uses String_Locator::SmartScan()
988
- * @uses __()
989
- * @uses String_Locator::write_file()
990
- * @uses wp_remote_head()
991
- *
992
- * @return void
993
  */
994
  function editor_save() {
995
  if ( isset( $_POST['string-locator-editor-content'] ) && check_admin_referer( 'string-locator-edit_' . $_GET['edit-file'] ) && current_user_can( 'edit_themes' ) ) {
@@ -998,7 +790,7 @@ class String_Locator
998
  $path = urldecode( $_GET['string-locator-path'] );
999
  $content = stripslashes( $_POST['string-locator-editor-content'] );
1000
 
1001
- /*
1002
  * Send an error notice if the file isn't writable
1003
  */
1004
  if ( ! is_writeable( $path ) ) {
@@ -1010,7 +802,7 @@ class String_Locator
1010
  return;
1011
  }
1012
 
1013
- /*
1014
  * If enabled, run the Smart-Scan on the content before saving it
1015
  */
1016
  if ( isset( $_POST['string-locator-smart-edit'] ) ) {
@@ -1081,7 +873,7 @@ class String_Locator
1081
 
1082
  $this->write_file( $path, $content );
1083
 
1084
- /*
1085
  * Check the status of the site after making our edits.
1086
  * If the site fails, revert the changes to return the sites to its original state
1087
  */
@@ -1120,18 +912,11 @@ class String_Locator
1120
  }
1121
 
1122
  /**
1123
- * When editing a file, this is where we write all the new content.
1124
- *
1125
  * We will break early if the user isn't allowed to edit files
1126
  *
1127
- * @uses current_user_can()
1128
- * @uses apply_filters()
1129
- * @uses __()
1130
- *
1131
  * @param string $path - The path to the file
1132
  * @param string $content - The content to write to the file
1133
- *
1134
- * @return void
1135
  */
1136
  private function write_file( $path, $content ) {
1137
  if ( ! current_user_can( 'edit_themes' ) ) {
@@ -1167,12 +952,7 @@ class String_Locator
1167
  }
1168
 
1169
  /**
1170
- * Hook the admin notices and loop over any notices we've registered in the plugin.
1171
- *
1172
- * @uses esc_attr()
1173
- * @uses esc_html()
1174
- *
1175
- * @return void
1176
  */
1177
  function admin_notice() {
1178
  if ( ! empty( $this->notice ) ) {
@@ -1189,19 +969,16 @@ class String_Locator
1189
  /**
1190
  * Scan through an individual file to look for occurrences of £string
1191
  *
1192
- * @uses esc_url()
1193
- * @uses esc_html()
1194
- * @uses String_Locator::create_edit_link()
1195
- *
1196
- * @param string $filename - The path to the file
1197
- * @param string $string - The search string
1198
- * @param mixed $location - The file location object/string
1199
- * @param string $type - File type
1200
- * @param string $slug - The plugin/theme slug of the file
1201
  *
1202
- * @return string
1203
  */
1204
- function scan_file( $filename, $string, $location, $type, $slug ) {
1205
  if ( empty( $string ) || ! is_file( $filename ) ) {
1206
  return false;
1207
  }
@@ -1222,7 +999,7 @@ class String_Locator
1222
  /*
1223
  * Check if the filename matches our search pattern
1224
  */
1225
- if ( stristr( $file, $string ) ) {
1226
  $relativepath = str_replace( array( ABSPATH, '\\', '/' ), array( '', DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR ), $path );
1227
  $match_count++;
1228
 
@@ -1252,20 +1029,19 @@ class String_Locator
1252
  {
1253
  $string_preview_is_cut = false;
1254
  $linenum++;
1255
-
1256
- /*
1257
  * If our string is found in this line, output the line number and other data
1258
  */
1259
- if ( stristr( $readline, $string ) )
1260
  {
1261
- /*
1262
  * Prepare the visual path for the end user
1263
  * Removes path leading up to WordPress root and ensures consistent directory separators
1264
  */
1265
  $relativepath = str_replace( array( ABSPATH, '\\', '/' ), array( '', DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR ), $path );
1266
  $match_count++;
1267
 
1268
- /*
1269
  * Create the URL to take the user to the editor
1270
  */
1271
  $editurl = $this->create_edit_link( $path, $linenum );
@@ -1288,7 +1064,12 @@ class String_Locator
1288
  $string_preview_is_cut = true;
1289
  }
1290
 
1291
- $string_preview = str_ireplace( $string, '<strong>' . $string . '</strong>', esc_html( $string_preview ) );
 
 
 
 
 
1292
  if ( $string_preview_is_cut ) {
1293
  $string_preview = sprintf(
1294
  '&hellip;%s&hellip;',
@@ -1317,7 +1098,7 @@ class String_Locator
1317
  fclose( $readfile );
1318
  }
1319
  else {
1320
- /*
1321
  * The file was unreadable, give the user a friendly notification
1322
  */
1323
  $output[] = array(
@@ -1330,13 +1111,6 @@ class String_Locator
1330
  return $output;
1331
  }
1332
 
1333
- /**
1334
- * Get a list of files inside a path.
1335
- *
1336
- * @param string $path
1337
- *
1338
- * @return array
1339
- */
1340
  function ajax_scan_path( $path ) {
1341
  $files = array();
1342
 
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.0
7
  * Author: Clorith
8
  * Author URI: http://www.clorith.net
9
  * Text Domain: string-locator
10
  * License: GPL2
11
  *
12
+ * Copyright 2013 Marius Jensen (email : marius@jits.no)
13
  *
14
  * This program is free software; you can redistribute it and/or modify
15
  * it under the terms of the GNU General Public License, version 2, as
26
  */
27
 
28
  /**
29
+ * Class String_Locator
 
 
 
 
30
  */
31
  class String_Locator
32
  {
33
  /**
34
+ * @var string $string_locator_language The code language used for the editing page
35
+ * @var string $version String Locator version number
36
+ * @var array $notice Array containing all notices to display
37
+ * @var bool $failed_edit Has there been a failed edit
38
+ * @var string $plugin_url The URL to the plugins directory
 
 
39
  */
40
  public $string_locator_language = '';
41
+ public $version = '2.1.0';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  public $notice = array();
 
 
 
 
 
 
 
 
 
 
43
  public $failed_edit = false;
 
 
 
 
 
 
 
 
 
 
44
  private $plugin_url = '';
 
 
 
 
 
 
 
 
 
 
45
  private $path_to_use = '';
 
 
 
 
 
 
 
 
 
 
46
  private $bad_http_codes = array( '500' );
47
+ private $bad_file_types = array( 'rar', '7z', 'zip', 'tar', 'gz' );
 
 
 
 
 
 
 
 
 
48
  private $excerpt_length = 25;
49
+ private $max_execution_time = null;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  private $start_execution_timer = 0;
 
 
 
 
 
 
 
 
 
 
51
  private $max_memory_consumption = 0;
52
 
53
  /**
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
 
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
89
  *
 
 
 
 
90
  * @since 2.0.0
91
  *
92
  * @return void
94
  function set_memory_limit() {
95
  $memory_limit = ini_get( 'memory_limit' );
96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  $this->max_memory_consumption = absint( $memory_limit );
98
 
99
  if ( strstr( $memory_limit, 'k' ) ) {
108
  }
109
 
110
  /**
111
+ * @param $meta
112
+ * @param $plugin_file
 
113
  *
114
+ * @return array
115
  */
116
+ function plugin_row_meta( $meta, $plugin_file ) {
117
+ if ( 'string-locator/string-locator.php' == $plugin_file ) {
118
+ $meta[] = sprintf(
119
+ '<a href="https://www.paypal.me/clorith">%s</a>',
120
+ esc_html__( 'Donate to this plugin', 'string-locator' )
121
+ );
122
+ }
123
+
124
+ return $meta;
125
  }
126
 
127
  /**
128
  * Create a set of drop-down options for picking one of the available themes
129
  *
 
 
 
 
 
130
  * @param string $current The current selection option to match against
131
  *
132
  * @return string
159
  /**
160
  * Create a set of drop-down options for picking one of the available plugins
161
  *
 
 
 
162
  * @param string $current The current selection option to match against
163
  *
164
  * @return string
191
  /**
192
  * Handles the AJAX request to prepare the search hierarchy
193
  *
 
 
 
 
 
 
 
 
194
  * @return object
195
  */
196
  function ajax_get_directory_structure() {
214
  'scan_path' => $scan_path,
215
  'search' => wp_unslash( $_POST['search'] ),
216
  'directory' => $_POST['directory'],
217
+ 'chunks' => count( $file_chunks ),
218
+ 'regex' => $_POST['regex']
219
  );
220
 
221
  $response = array(
222
  'total' => count( $files ),
223
  'current' => 0,
224
  'directory' => $scan_path,
225
+ 'chunks' => count( $file_chunks ),
226
+ 'regex' => $_POST['regex']
227
  );
228
 
229
  update_option( 'string-locator-search-overview', serialize( $store ), true );
239
  /**
240
  * Check if the script is about to exceed the max execution time.
241
  *
 
 
242
  * @since 1.9.0
243
  *
244
  * @return bool
245
  */
246
  function nearing_execution_limit() {
247
+ // Max execution time is 0 (infinite) in server config
248
+ if ( 0 === $this->max_execution_time ) {
249
+ return false;
250
+ }
251
+
252
  $built_in_delay = apply_filters( 'string-locator-extra-search-delay', 2 );
253
  $execution_time = ( microtime( true ) - $this->start_execution_timer + $built_in_delay );
254
 
261
  /**
262
  * Check if the script is about to exceed the server memory limit.
263
  *
 
 
264
  * @since 2.0.0
265
  *
266
  * @return bool
279
  /**
280
  * Search an individual file supplied via AJAX
281
  *
 
 
 
 
 
 
 
 
 
282
  * @since 1.9.0
283
  *
284
+ * @return object
285
  */
286
  function ajax_file_search() {
287
  if ( ! check_ajax_referer( 'string-locator-search', 'nonce', false ) ) { wp_send_json_error( __( 'Authentication failed', 'string-locator' ) ); }
339
  $file_name = explode( "/", $file_data[ $filenum ] );
340
  $file_name = end( $file_name );
341
 
342
+ /*
343
+ * Check the file type, if it's an unsupported type, we skip it
344
+ */
345
+ $file_type = explode( '.', $file_name );
346
+ $file_type = end( $file_type );
347
+
348
+ if ( in_array( $file_type, $this->bad_file_types ) ) {
349
+ continue;
350
+ }
351
+
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;
381
  /**
382
  * Clean up our options used to help during the search
383
  *
384
+ * @return object
 
 
 
 
 
 
385
  */
386
  function ajax_clean_search() {
387
  if ( ! check_ajax_referer( 'string-locator-search', 'nonce', false ) ) { wp_send_json_error( __( 'Authentication failed', 'string-locator' ) ); }
397
  /**
398
  * Create a table row for insertion into the search results list
399
  *
 
 
 
400
  * @param array|object $item The table row item
401
  *
402
  * @return string
422
  /**
423
  * Create a full table populated with the supplied items
424
  *
 
 
 
425
  * @param array $items An array of table rows
426
  * @param array $table_class An array of items to append to the table class along with the defaults
427
  *
466
  /**
467
  * Create an admin edit link for the supplied path
468
  *
 
 
 
469
  * @param string $path
470
  * @param int $line
471
  *
590
 
591
  /**
592
  * Set the text domain for translated plugin content
 
 
 
 
593
  */
594
  function load_i18n() {
595
  $i18n_dir = 'string-locator/languages/';
598
 
599
  /**
600
  * Load up JavaScript and CSS for our plugin on the appropriate admin pages
 
 
 
 
 
 
 
 
 
 
 
601
  */
602
  function admin_enqueue_scripts( $hook ) {
603
  // Break out early if we are not on a String Locator page
703
  }
704
 
705
  /**
706
+ * Add our plugin to the 'Tools' menu
 
 
 
 
 
 
707
  */
708
  function populate_menu()
709
  {
720
  add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $function );
721
  }
722
 
 
 
 
 
 
 
 
 
723
  function populate_network_menu()
724
  {
725
  $page_title = __( 'String Locator', 'string-locator' );
732
  }
733
 
734
  /**
735
+ * Function for including the actual plugin Admin UI page
 
 
 
 
 
736
  */
737
  function options_page()
738
  {
739
+ /**
740
  * Don't load anything if the user can't edit themes any way
741
  */
742
  if ( ! current_user_can( 'edit_themes' ) ) {
743
+ return false;
744
  }
745
 
746
+ /**
747
  * Show the edit page if;
748
  * - The edit file path query var is set
749
  * - The edit file path query var isn't empty
758
  }
759
 
760
  /**
 
 
761
  * @param string $start Start delimited
762
  * @param string $end End delimiter
763
  * @param string $string The string to scan
 
764
  * @return array
765
  */
766
  function SmartScan( $start, $end, $string ) {
780
  }
781
 
782
  /**
783
+ * Handler for storing the content of the code editor
784
+ * Also runs over the Smart-Scan if enabled
 
 
 
 
 
 
 
 
 
785
  */
786
  function editor_save() {
787
  if ( isset( $_POST['string-locator-editor-content'] ) && check_admin_referer( 'string-locator-edit_' . $_GET['edit-file'] ) && current_user_can( 'edit_themes' ) ) {
790
  $path = urldecode( $_GET['string-locator-path'] );
791
  $content = stripslashes( $_POST['string-locator-editor-content'] );
792
 
793
+ /**
794
  * Send an error notice if the file isn't writable
795
  */
796
  if ( ! is_writeable( $path ) ) {
802
  return;
803
  }
804
 
805
+ /**
806
  * If enabled, run the Smart-Scan on the content before saving it
807
  */
808
  if ( isset( $_POST['string-locator-smart-edit'] ) ) {
873
 
874
  $this->write_file( $path, $content );
875
 
876
+ /**
877
  * Check the status of the site after making our edits.
878
  * If the site fails, revert the changes to return the sites to its original state
879
  */
912
  }
913
 
914
  /**
915
+ * When editing a file, this is where we write all the new content
 
916
  * We will break early if the user isn't allowed to edit files
917
  *
 
 
 
 
918
  * @param string $path - The path to the file
919
  * @param string $content - The content to write to the file
 
 
920
  */
921
  private function write_file( $path, $content ) {
922
  if ( ! current_user_can( 'edit_themes' ) ) {
952
  }
953
 
954
  /**
955
+ * Hook the admin notices and loop over any notices we've registered in the plugin
 
 
 
 
 
956
  */
957
  function admin_notice() {
958
  if ( ! empty( $this->notice ) ) {
969
  /**
970
  * Scan through an individual file to look for occurrences of £string
971
  *
972
+ * @param string $filename The path to the file
973
+ * @param string $string The search string
974
+ * @param mixed $location The file location object/string
975
+ * @param string $type File type
976
+ * @param string $slug The plugin/theme slug of the file
977
+ * @param boolean $regex Should a regex search be performed
 
 
 
978
  *
979
+ * @return mixed
980
  */
981
+ function scan_file( $filename, $string, $location, $type, $slug, $regex = false ) {
982
  if ( empty( $string ) || ! is_file( $filename ) ) {
983
  return false;
984
  }
999
  /*
1000
  * Check if the filename matches our search pattern
1001
  */
1002
+ if ( stristr( $file, $string ) || ( $regex && preg_match( $string, $file ) ) ) {
1003
  $relativepath = str_replace( array( ABSPATH, '\\', '/' ), array( '', DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR ), $path );
1004
  $match_count++;
1005
 
1029
  {
1030
  $string_preview_is_cut = false;
1031
  $linenum++;
1032
+ /**
 
1033
  * If our string is found in this line, output the line number and other data
1034
  */
1035
+ if ( ( ! $regex && stristr( $readline, $string ) ) || ( $regex && preg_match( $string, $readline ) ) )
1036
  {
1037
+ /**
1038
  * Prepare the visual path for the end user
1039
  * Removes path leading up to WordPress root and ensures consistent directory separators
1040
  */
1041
  $relativepath = str_replace( array( ABSPATH, '\\', '/' ), array( '', DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR ), $path );
1042
  $match_count++;
1043
 
1044
+ /**
1045
  * Create the URL to take the user to the editor
1046
  */
1047
  $editurl = $this->create_edit_link( $path, $linenum );
1064
  $string_preview_is_cut = true;
1065
  }
1066
 
1067
+ if ( $regex ) {
1068
+ $string_preview = preg_replace( preg_replace( '/\/(.+)\//', '/($1)/', $string ), '<strong>$1</strong>', esc_html( $string_preview ) );
1069
+ }
1070
+ else {
1071
+ $string_preview = str_ireplace( $string, '<strong>' . $string . '</strong>', esc_html( $string_preview ) );
1072
+ }
1073
  if ( $string_preview_is_cut ) {
1074
  $string_preview = sprintf(
1075
  '&hellip;%s&hellip;',
1098
  fclose( $readfile );
1099
  }
1100
  else {
1101
+ /**
1102
  * The file was unreadable, give the user a friendly notification
1103
  */
1104
  $output[] = array(
1111
  return $output;
1112
  }
1113
 
 
 
 
 
 
 
 
1114
  function ajax_scan_path( $path ) {
1115
  $files = array();
1116