: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
'CodeMirror' => $code_mirror,
'goto_line' => ( isset( $_GET['string-locator-line'] ) ? absint( $_GET['string-locator-line'] ) : 0 ),
'goto_linepos' => ( isset( $_GET['string-locator-linepos'] ) ? absint( $_GET['string-locator-linepos'] ) : 0 ),
'save' => get_rest_url( null, 'string-locator/v1/save' ),
* Add our plugin to the 'Tools' menu.
function populate_menu() {
// if ( is_multisite() ) {
$page_title = __( 'String Locator', 'string-locator' );
$menu_title = __( 'String Locator', 'string-locator' );
$capability = 'install_plugins';
$parent_slug = 'tools.php';
$menu_slug = 'string-locator';
$function = array( $this, 'options_page' );
add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $function );
* Add our plugin to the main menu in the Network Admin.
function populate_network_menu() {
$page_title = __( 'String Locator', 'string-locator' );
$menu_title = __( 'String Locator', 'string-locator' );
$capability = 'install_plugins';
$menu_slug = 'string-locator';
$function = array( $this, 'options_page' );
add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function, 'dashicons-edit' );
* Function for including the actual plugin Admin UI page.
function options_page() {
* Don't load anything if the user can't edit themes any way
if ( ! current_user_can( 'edit_users' ) ) {
* - The edit file path query var is set
* - The edit file path query var isn't empty
* - The edit file path query var does not contains double dots (used to traverse directories)
* - The user is capable of editing files.
if ( isset( $_GET['string-locator-path'] ) && self::is_valid_location( $_GET['string-locator-path'] ) && current_user_can( String_Locator::$default_capability ) ) {
$include_path = trailingslashit( STRING_LOCATOR_PLUGIN_DIR ) . 'views/editors/default.php';
$include_path = trailingslashit( STRING_LOCATOR_PLUGIN_DIR ) . 'views/search.php';
$include_path = apply_filters( 'string_locator_view', $include_path );
if ( ! empty( $include_path ) ) {
include_once $include_path;
function admin_body_class( $class ) {
if ( isset( $_GET['string-locator-path'] ) && self::is_valid_location( $_GET['string-locator-path'] ) && current_user_can( String_Locator::$default_capability ) ) {
$class .= ' file-edit-screen';
* Hook the admin notices and loop over any notices we've registered in the plugin.
function admin_notice() {
if ( ! empty( $this->notice ) ) {
foreach ( $this->notice as $note ) {
'<div class="%s"><p>%s</p></div>',
esc_attr( $note['type'] ),
* Check if a file path is valid for editing.
* @param string $path Path to file.
public static function is_valid_location( $path ) {
$path = str_replace( array( '/' ), array( DIRECTORY_SEPARATOR ), stripslashes( $path ) );
$abspath = str_replace( array( '/' ), array( DIRECTORY_SEPARATOR ), ABSPATH );
* Check that the ABSPath is the start of the path.
* This helps ensure that no protocol triggers can be used as part of the file path.
if ( substr( $path, 0, strlen( $abspath ) ) !== $abspath ) {
// Check that it is a valid file we are trying to access as well.
if ( ! file_exists( $path ) ) {
if ( stristr( $path, '..' ) ) {
public static function create_preview( $string_preview, $string, $regex = false ) {
* Define class variables requiring expressions
$excerpt_length = apply_filters( 'string_locator_excerpt_length', 25 );
$string_preview_is_cut = false;
if ( strlen( $string_preview ) > ( strlen( $string ) + $excerpt_length ) ) {
$string_location = strpos( $string_preview, $string );
$string_location_start = $string_location - $excerpt_length;
if ( $string_location_start < 0 ) {
$string_location_start = 0;
$string_location_end = ( strlen( $string ) + ( $excerpt_length * 2 ) );
if ( $string_location_end > strlen( $string_preview ) ) {
$string_location_end = strlen( $string_preview );
$string_preview = substr( $string_preview, $string_location_start, $string_location_end );
$string_preview_is_cut = true;
$string_preview = preg_replace( preg_replace( '/\/(.+)\//', '/($1)/', $string ), '<strong>$1</strong>', esc_html( $string_preview ) );
$string_preview = preg_replace( '/(' . preg_quote( $string, '/' ) . ')/i', '<strong>$1</strong>', esc_html( $string_preview ) );
if ( $string_preview_is_cut ) {
$string_preview = sprintf(