wp/wp-admin/plugin-editor.php
changeset 7 cf61fcea0001
parent 5 5e2f62d02dcd
child 9 177826044cd9
equal deleted inserted replaced
6:490d5cc509ed 7:cf61fcea0001
    13 	wp_redirect( network_admin_url( 'plugin-editor.php' ) );
    13 	wp_redirect( network_admin_url( 'plugin-editor.php' ) );
    14 	exit();
    14 	exit();
    15 }
    15 }
    16 
    16 
    17 if ( !current_user_can('edit_plugins') )
    17 if ( !current_user_can('edit_plugins') )
    18 	wp_die( __('You do not have sufficient permissions to edit plugins for this site.') );
    18 	wp_die( __('Sorry, you are not allowed to edit plugins for this site.') );
    19 
    19 
    20 $title = __("Edit Plugins");
    20 $title = __("Edit Plugins");
    21 $parent_file = 'plugins.php';
    21 $parent_file = 'plugins.php';
    22 
       
    23 wp_reset_vars( array( 'action', 'error', 'file', 'plugin' ) );
       
    24 
    22 
    25 $plugins = get_plugins();
    23 $plugins = get_plugins();
    26 
    24 
    27 if ( empty( $plugins ) ) {
    25 if ( empty( $plugins ) ) {
    28 	include( ABSPATH . 'wp-admin/admin-header.php' );
    26 	include( ABSPATH . 'wp-admin/admin-header.php' );
    29 	?>
    27 	?>
    30 	<div class="wrap">
    28 	<div class="wrap">
    31 		<h2><?php echo esc_html( $title ); ?></h2>
    29 		<h1><?php echo esc_html( $title ); ?></h1>
    32 		<div id="message" class="error"><p><?php _e( 'You do not appear to have any plugins available at this time.' ); ?></p></div>
    30 		<div id="message" class="error"><p><?php _e( 'You do not appear to have any plugins available at this time.' ); ?></p></div>
    33 	</div>
    31 	</div>
    34 	<?php
    32 	<?php
    35 	include( ABSPATH . 'wp-admin/admin-footer.php' );
    33 	include( ABSPATH . 'wp-admin/admin-footer.php' );
    36 	exit;
    34 	exit;
    37 }
    35 }
    38 
    36 
    39 if ( $file ) {
    37 $file = '';
    40 	$plugin = $file;
    38 $plugin = '';
    41 } elseif ( empty( $plugin ) ) {
    39 if ( isset( $_REQUEST['file'] ) ) {
    42 	$plugin = array_keys($plugins);
    40 	$file = wp_unslash( $_REQUEST['file'] );
    43 	$plugin = $plugin[0];
    41 }
       
    42 
       
    43 if ( isset( $_REQUEST['plugin'] ) ) {
       
    44 	$plugin = wp_unslash( $_REQUEST['plugin'] );
       
    45 }
       
    46 
       
    47 if ( empty( $plugin ) ) {
       
    48 	if ( $file ) {
       
    49 
       
    50 		// Locate the plugin for a given plugin file being edited.
       
    51 		$file_dirname = dirname( $file );
       
    52 		foreach ( array_keys( $plugins ) as $plugin_candidate ) {
       
    53 			if ( $plugin_candidate === $file || ( '.' !== $file_dirname && dirname( $plugin_candidate ) === $file_dirname ) ) {
       
    54 				$plugin = $plugin_candidate;
       
    55 				break;
       
    56 			}
       
    57 		}
       
    58 
       
    59 		// Fallback to the file as the plugin.
       
    60 		if ( empty( $plugin ) ) {
       
    61 			$plugin = $file;
       
    62 		}
       
    63 	} else {
       
    64 		$plugin = array_keys( $plugins );
       
    65 		$plugin = $plugin[0];
       
    66 	}
    44 }
    67 }
    45 
    68 
    46 $plugin_files = get_plugin_files($plugin);
    69 $plugin_files = get_plugin_files($plugin);
    47 
    70 
    48 if ( empty($file) )
    71 if ( empty( $file ) ) {
    49 	$file = $plugin_files[0];
    72 	$file = $plugin_files[0];
       
    73 }
    50 
    74 
    51 $file = validate_file_to_edit($file, $plugin_files);
    75 $file = validate_file_to_edit($file, $plugin_files);
    52 $real_file = WP_PLUGIN_DIR . '/' . $file;
    76 $real_file = WP_PLUGIN_DIR . '/' . $file;
    53 $scrollto = isset($_REQUEST['scrollto']) ? (int) $_REQUEST['scrollto'] : 0;
    77 
    54 
    78 // Handle fallback editing of file when JavaScript is not available.
    55 switch ( $action ) {
    79 $edit_error = null;
    56 
    80 $posted_content = null;
    57 case 'update':
    81 if ( 'POST' === $_SERVER['REQUEST_METHOD'] ) {
    58 
    82 	$r = wp_edit_theme_plugin_file( wp_unslash( $_POST ) );
    59 	check_admin_referer('edit-plugin_' . $file);
    83 	if ( is_wp_error( $r ) ) {
    60 
    84 		$edit_error = $r;
    61 	$newcontent = wp_unslash( $_POST['newcontent'] );
    85 		if ( check_ajax_referer( 'edit-plugin_' . $file, 'nonce', false ) && isset( $_POST['newcontent'] ) ) {
    62 	if ( is_writeable($real_file) ) {
    86 			$posted_content = wp_unslash( $_POST['newcontent'] );
    63 		$f = fopen($real_file, 'w+');
    87 		}
    64 		fwrite($f, $newcontent);
    88 	} else {
    65 		fclose($f);
    89 		wp_redirect( add_query_arg(
    66 
    90 			array(
    67 		$network_wide = is_plugin_active_for_network( $file );
    91 				'a' => 1, // This means "success" for some reason.
    68 
    92 				'plugin' => $plugin,
    69 		// Deactivate so we can test it.
    93 				'file' => $file,
    70 		if ( is_plugin_active($file) || isset($_POST['phperror']) ) {
    94 			),
    71 			if ( is_plugin_active($file) )
    95 			admin_url( 'plugin-editor.php' )
    72 				deactivate_plugins($file, true);
    96 		) );
    73 
       
    74 			if ( ! is_network_admin() )
       
    75 				update_option( 'recently_activated', array( $file => time() ) + (array) get_option( 'recently_activated' ) );
       
    76 
       
    77 			wp_redirect(add_query_arg('_wpnonce', wp_create_nonce('edit-plugin-test_' . $file), "plugin-editor.php?file=$file&liveupdate=1&scrollto=$scrollto&networkwide=" . $network_wide));
       
    78 			exit;
       
    79 		}
       
    80 		wp_redirect( self_admin_url("plugin-editor.php?file=$file&a=te&scrollto=$scrollto") );
       
    81 	} else {
       
    82 		wp_redirect( self_admin_url("plugin-editor.php?file=$file&scrollto=$scrollto") );
       
    83 	}
       
    84 	exit;
       
    85 
       
    86 default:
       
    87 
       
    88 	if ( isset($_GET['liveupdate']) ) {
       
    89 		check_admin_referer('edit-plugin-test_' . $file);
       
    90 
       
    91 		$error = validate_plugin($file);
       
    92 		if ( is_wp_error($error) )
       
    93 			wp_die( $error );
       
    94 
       
    95 		if ( ( ! empty( $_GET['networkwide'] ) && ! is_plugin_active_for_network($file) ) || ! is_plugin_active($file) )
       
    96 			activate_plugin($file, "plugin-editor.php?file=$file&phperror=1", ! empty( $_GET['networkwide'] ) ); // we'll override this later if the plugin can be included without fatal error
       
    97 
       
    98 		wp_redirect( self_admin_url("plugin-editor.php?file=$file&a=te&scrollto=$scrollto") );
       
    99 		exit;
    97 		exit;
   100 	}
    98 	}
       
    99 }
   101 
   100 
   102 	// List of allowable extensions
   101 	// List of allowable extensions
   103 	$editable_extensions = array('php', 'txt', 'text', 'js', 'css', 'html', 'htm', 'xml', 'inc', 'include');
   102 	$editable_extensions = wp_get_plugin_file_editable_extensions( $plugin );
   104 
       
   105 	/**
       
   106 	 * Filter file type extensions editable in the plugin editor.
       
   107 	 *
       
   108 	 * @since 2.8.0
       
   109 	 *
       
   110 	 * @param array $editable_extensions An array of editable plugin file extensions.
       
   111 	 */
       
   112 	$editable_extensions = (array) apply_filters( 'editable_extensions', $editable_extensions );
       
   113 
   103 
   114 	if ( ! is_file($real_file) ) {
   104 	if ( ! is_file($real_file) ) {
   115 		wp_die(sprintf('<p>%s</p>', __('No such file exists! Double check the name and try again.')));
   105 		wp_die(sprintf('<p>%s</p>', __('No such file exists! Double check the name and try again.')));
   116 	} else {
   106 	} else {
   117 		// Get the extension of the file
   107 		// Get the extension of the file
   126 	get_current_screen()->add_help_tab( array(
   116 	get_current_screen()->add_help_tab( array(
   127 	'id'		=> 'overview',
   117 	'id'		=> 'overview',
   128 	'title'		=> __('Overview'),
   118 	'title'		=> __('Overview'),
   129 	'content'	=>
   119 	'content'	=>
   130 		'<p>' . __('You can use the editor to make changes to any of your plugins&#8217; individual PHP files. Be aware that if you make changes, plugins updates will overwrite your customizations.') . '</p>' .
   120 		'<p>' . __('You can use the editor to make changes to any of your plugins&#8217; individual PHP files. Be aware that if you make changes, plugins updates will overwrite your customizations.') . '</p>' .
   131 		'<p>' . __('Choose a plugin to edit from the menu in the upper right and click the Select button. Click once on any file name to load it in the editor, and make your changes. Don&#8217;t forget to save your changes (Update File) when you&#8217;re finished.') . '</p>' .
   121 		'<p>' . __('Choose a plugin to edit from the dropdown menu and click the Select button. Click once on any file name to load it in the editor, and make your changes. Don&#8217;t forget to save your changes (Update File) when you&#8217;re finished.') . '</p>' .
   132 		'<p>' . __('The Documentation menu below the editor lists the PHP functions recognized in the plugin file. Clicking Look Up takes you to a web page about that particular function.') . '</p>' .
   122 		'<p>' . __('The Documentation menu below the editor lists the PHP functions recognized in the plugin file. Clicking Look Up takes you to a web page about that particular function.') . '</p>' .
   133 		'<p id="newcontent-description">' . __( 'In the editing area the Tab key enters a tab character. To move below this area by pressing Tab, press the Esc key followed by the Tab key. In some cases the Esc key will need to be pressed twice before the Tab key will allow you to continue.' ) . '</p>' .
   123 		'<p id="editor-keyboard-trap-help-1">' . __( 'When using a keyboard to navigate:' ) . '</p>' .
       
   124 		'<ul>' .
       
   125 		'<li id="editor-keyboard-trap-help-2">' . __( 'In the editing area, the Tab key enters a tab character.' ) . '</li>' .
       
   126 		'<li id="editor-keyboard-trap-help-3">' . __( 'To move away from this area, press the Esc key followed by the Tab key.' ) . '</li>' .
       
   127 		'<li id="editor-keyboard-trap-help-4">' . __( 'Screen reader users: when in forms mode, you may need to press the Esc key twice.' ) . '</li>' .
       
   128 		'</ul>' .
   134 		'<p>' . __('If you want to make changes but don&#8217;t want them to be overwritten when the plugin is updated, you may be ready to think about writing your own plugin. For information on how to edit plugins, write your own from scratch, or just better understand their anatomy, check out the links below.') . '</p>' .
   129 		'<p>' . __('If you want to make changes but don&#8217;t want them to be overwritten when the plugin is updated, you may be ready to think about writing your own plugin. For information on how to edit plugins, write your own from scratch, or just better understand their anatomy, check out the links below.') . '</p>' .
   135 		( is_network_admin() ? '<p>' . __('Any edits to files from this screen will be reflected on all sites in the network.') . '</p>' : '' )
   130 		( is_network_admin() ? '<p>' . __('Any edits to files from this screen will be reflected on all sites in the network.') . '</p>' : '' )
   136 	) );
   131 	) );
   137 
   132 
   138 	get_current_screen()->set_help_sidebar(
   133 	get_current_screen()->set_help_sidebar(
   139 		'<p><strong>' . __('For more information:') . '</strong></p>' .
   134 		'<p><strong>' . __('For more information:') . '</strong></p>' .
   140 		'<p>' . __('<a href="https://codex.wordpress.org/Plugins_Editor_Screen" target="_blank">Documentation on Editing Plugins</a>') . '</p>' .
   135 		'<p>' . __('<a href="https://codex.wordpress.org/Plugins_Editor_Screen">Documentation on Editing Plugins</a>') . '</p>' .
   141 		'<p>' . __('<a href="https://codex.wordpress.org/Writing_a_Plugin" target="_blank">Documentation on Writing Plugins</a>') . '</p>' .
   136 		'<p>' . __('<a href="https://codex.wordpress.org/Writing_a_Plugin">Documentation on Writing Plugins</a>') . '</p>' .
   142 		'<p>' . __('<a href="https://wordpress.org/support/" target="_blank">Support Forums</a>') . '</p>'
   137 		'<p>' . __('<a href="https://wordpress.org/support/">Support Forums</a>') . '</p>'
   143 	);
   138 	);
   144 
   139 
       
   140 	$settings = array(
       
   141 		'codeEditor' => wp_enqueue_code_editor( array( 'file' => $real_file ) ),
       
   142 	);
       
   143 	wp_enqueue_script( 'wp-theme-plugin-editor' );
       
   144 	wp_add_inline_script( 'wp-theme-plugin-editor', sprintf( 'jQuery( function( $ ) { wp.themePluginEditor.init( $( "#template" ), %s ); } )', wp_json_encode( $settings ) ) );
       
   145 	wp_add_inline_script( 'wp-theme-plugin-editor', sprintf( 'wp.themePluginEditor.themeOrPlugin = "plugin";' ) );
       
   146 
   145 	require_once(ABSPATH . 'wp-admin/admin-header.php');
   147 	require_once(ABSPATH . 'wp-admin/admin-header.php');
   146 
   148 
   147 	update_recently_edited(WP_PLUGIN_DIR . '/' . $file);
   149 	update_recently_edited(WP_PLUGIN_DIR . '/' . $file);
   148 
   150 
   149 	$content = file_get_contents( $real_file );
   151 	if ( ! empty( $posted_content ) ) {
       
   152 		$content = $posted_content;
       
   153 	} else {
       
   154 		$content = file_get_contents( $real_file );
       
   155 	}
   150 
   156 
   151 	if ( '.php' == substr( $real_file, strrpos( $real_file, '.' ) ) ) {
   157 	if ( '.php' == substr( $real_file, strrpos( $real_file, '.' ) ) ) {
   152 		$functions = wp_doc_link_parse( $content );
   158 		$functions = wp_doc_link_parse( $content );
   153 
   159 
   154 		if ( !empty($functions) ) {
   160 		if ( !empty($functions) ) {
   161 		}
   167 		}
   162 	}
   168 	}
   163 
   169 
   164 	$content = esc_textarea( $content );
   170 	$content = esc_textarea( $content );
   165 	?>
   171 	?>
   166 <?php if (isset($_GET['a'])) : ?>
   172 <div class="wrap">
   167  <div id="message" class="updated notice is-dismissible"><p><?php _e('File edited successfully.') ?></p></div>
   173 <h1><?php echo esc_html( $title ); ?></h1>
   168 <?php elseif (isset($_GET['phperror'])) : ?>
   174 
   169  <div id="message" class="updated"><p><?php _e('This plugin has been deactivated because your changes resulted in a <strong>fatal error</strong>.') ?></p>
   175 <?php if ( isset( $_GET['a'] ) ) : ?>
   170 	<?php
   176 	<div id="message" class="updated notice is-dismissible">
   171 		if ( wp_verify_nonce($_GET['_error_nonce'], 'plugin-activation-error_' . $file) ) { ?>
   177 		<p><?php _e( 'File edited successfully.' ); ?></p>
   172 	<iframe style="border:0" width="100%" height="70px" src="<?php bloginfo('wpurl'); ?>/wp-admin/plugins.php?action=error_scrape&amp;plugin=<?php echo esc_attr($file); ?>&amp;_wpnonce=<?php echo esc_attr($_GET['_error_nonce']); ?>"></iframe>
   178 	</div>
   173 	<?php } ?>
   179 <?php elseif ( is_wp_error( $edit_error ) ) : ?>
   174 </div>
   180 	<div id="message" class="notice notice-error">
       
   181 		<p><?php _e( 'There was an error while trying to update the file. You may need to fix something and try updating again.' ); ?></p>
       
   182 		<pre><?php echo esc_html( $edit_error->get_error_message() ? $edit_error->get_error_message() : $edit_error->get_error_code() ); ?></pre>
       
   183 	</div>
   175 <?php endif; ?>
   184 <?php endif; ?>
   176 <div class="wrap">
       
   177 <h2><?php echo esc_html( $title ); ?></h2>
       
   178 
   185 
   179 <div class="fileedit-sub">
   186 <div class="fileedit-sub">
   180 <div class="alignleft">
   187 <div class="alignleft">
   181 <big><?php
   188 <h2>
   182 	if ( is_plugin_active($plugin) ) {
   189 	<?php
   183 		if ( is_writeable($real_file) )
   190 	if ( is_plugin_active( $plugin ) ) {
   184 			echo sprintf(__('Editing <strong>%s</strong> (active)'), $file);
   191 		if ( is_writeable( $real_file ) ) {
   185 		else
   192 			/* translators: %s: plugin file name */
   186 			echo sprintf(__('Browsing <strong>%s</strong> (active)'), $file);
   193 			echo sprintf( __( 'Editing %s (active)' ), '<strong>' . esc_html( $file ) . '</strong>' );
   187 	} else {
   194 		} else {
   188 		if ( is_writeable($real_file) )
   195 			/* translators: %s: plugin file name */
   189 			echo sprintf(__('Editing <strong>%s</strong> (inactive)'), $file);
   196 			echo sprintf( __( 'Browsing %s (active)' ), '<strong>' . esc_html( $file ) . '</strong>' );
   190 		else
   197 		}
   191 			echo sprintf(__('Browsing <strong>%s</strong> (inactive)'), $file);
   198 	} else {
   192 	}
   199 		if ( is_writeable( $real_file ) ) {
   193 	?></big>
   200 			/* translators: %s: plugin file name */
       
   201 			echo sprintf( __( 'Editing %s (inactive)' ), '<strong>' . esc_html( $file ) . '</strong>' );
       
   202 		} else {
       
   203 			/* translators: %s: plugin file name */
       
   204 			echo sprintf( __( 'Browsing %s (inactive)' ), '<strong>' . esc_html( $file ) . '</strong>' );
       
   205 		}
       
   206 	}
       
   207 	?>
       
   208 </h2>
   194 </div>
   209 </div>
   195 <div class="alignright">
   210 <div class="alignright">
   196 	<form action="plugin-editor.php" method="post">
   211 	<form action="plugin-editor.php" method="get">
   197 		<strong><label for="plugin"><?php _e('Select plugin to edit:'); ?> </label></strong>
   212 		<strong><label for="plugin"><?php _e('Select plugin to edit:'); ?> </label></strong>
   198 		<select name="plugin" id="plugin">
   213 		<select name="plugin" id="plugin">
   199 <?php
   214 <?php
   200 	foreach ( $plugins as $plugin_key => $a_plugin ) {
   215 	foreach ( $plugins as $plugin_key => $a_plugin ) {
   201 		$plugin_name = $a_plugin['Name'];
   216 		$plugin_name = $a_plugin['Name'];
   207 		$plugin_key = esc_attr($plugin_key);
   222 		$plugin_key = esc_attr($plugin_key);
   208 		echo "\n\t<option value=\"$plugin_key\" $selected>$plugin_name</option>";
   223 		echo "\n\t<option value=\"$plugin_key\" $selected>$plugin_name</option>";
   209 	}
   224 	}
   210 ?>
   225 ?>
   211 		</select>
   226 		</select>
   212 		<?php submit_button( __( 'Select' ), 'button', 'Submit', false ); ?>
   227 		<?php submit_button( __( 'Select' ), '', 'Submit', false ); ?>
   213 	</form>
   228 	</form>
   214 </div>
   229 </div>
   215 <br class="clear" />
   230 <br class="clear" />
   216 </div>
   231 </div>
   217 
   232 
   218 <div id="templateside">
   233 <div id="templateside">
   219 	<h3><?php _e('Plugin Files'); ?></h3>
   234 	<h2 id="plugin-files-label"><?php _e( 'Plugin Files' ); ?></h2>
   220 
   235 
   221 	<ul>
   236 	<?php
   222 <?php
   237 	$plugin_editable_files = array();
   223 foreach ( $plugin_files as $plugin_file ) :
   238 	foreach ( $plugin_files as $plugin_file ) {
   224 	// Get the extension of the file
   239 		if ( preg_match('/\.([^.]+)$/', $plugin_file, $matches ) && in_array( $matches[1], $editable_extensions ) ) {
   225 	if ( preg_match('/\.([^.]+)$/', $plugin_file, $matches) ) {
   240 			$plugin_editable_files[] = $plugin_file;
   226 		$ext = strtolower($matches[1]);
   241 		}
   227 		// If extension is not in the acceptable list, skip it
   242 	}
   228 		if ( !in_array( $ext, $editable_extensions ) )
   243 	?>
   229 			continue;
   244 	<ul role="tree" aria-labelledby="plugin-files-label">
   230 	} else {
   245 	<li role="treeitem" tabindex="-1" aria-expanded="true" aria-level="1" aria-posinset="1" aria-setsize="1">
   231 		// No extension found
   246 		<ul role="group">
   232 		continue;
   247 			<?php wp_print_plugin_file_tree( wp_make_plugin_file_tree( $plugin_editable_files ) ); ?>
   233 	}
   248 		</ul>
   234 ?>
       
   235 		<li<?php echo $file == $plugin_file ? ' class="highlight"' : ''; ?>><a href="plugin-editor.php?file=<?php echo urlencode( $plugin_file ) ?>&amp;plugin=<?php echo urlencode( $plugin ) ?>"><?php echo $plugin_file ?></a></li>
       
   236 <?php endforeach; ?>
       
   237 	</ul>
   249 	</ul>
   238 </div>
   250 </div>
   239 <form name="template" id="template" action="plugin-editor.php" method="post">
   251 <form name="template" id="template" action="plugin-editor.php" method="post">
   240 	<?php wp_nonce_field('edit-plugin_' . $file) ?>
   252 	<?php wp_nonce_field( 'edit-plugin_' . $file, 'nonce' ); ?>
   241 		<div><textarea cols="70" rows="25" name="newcontent" id="newcontent" aria-describedby="newcontent-description"><?php echo $content; ?></textarea>
   253 		<div>
   242 		<input type="hidden" name="action" value="update" />
   254 			<label for="newcontent" id="theme-plugin-editor-label"><?php _e( 'Selected file content:' ); ?></label>
   243 		<input type="hidden" name="file" value="<?php echo esc_attr($file) ?>" />
   255 			<textarea cols="70" rows="25" name="newcontent" id="newcontent" aria-describedby="editor-keyboard-trap-help-1 editor-keyboard-trap-help-2 editor-keyboard-trap-help-3 editor-keyboard-trap-help-4"><?php echo $content; ?></textarea>
   244 		<input type="hidden" name="plugin" value="<?php echo esc_attr($plugin) ?>" />
   256 			<input type="hidden" name="action" value="update" />
   245 		<input type="hidden" name="scrollto" id="scrollto" value="<?php echo $scrollto; ?>" />
   257 			<input type="hidden" name="file" value="<?php echo esc_attr( $file ); ?>" />
       
   258 			<input type="hidden" name="plugin" value="<?php echo esc_attr( $plugin ); ?>" />
   246 		</div>
   259 		</div>
   247 		<?php if ( !empty( $docs_select ) ) : ?>
   260 		<?php if ( !empty( $docs_select ) ) : ?>
   248 		<div id="documentation" class="hide-if-no-js"><label for="docs-list"><?php _e('Documentation:') ?></label> <?php echo $docs_select ?> <input type="button" class="button" value="<?php esc_attr_e( 'Look Up' ) ?> " onclick="if ( '' != jQuery('#docs-list').val() ) { window.open( 'http://api.wordpress.org/core/handbook/1.0/?function=' + escape( jQuery( '#docs-list' ).val() ) + '&amp;locale=<?php echo urlencode( get_locale() ) ?>&amp;version=<?php echo urlencode( $wp_version ) ?>&amp;redirect=true'); }" /></div>
   261 		<div id="documentation" class="hide-if-no-js"><label for="docs-list"><?php _e('Documentation:') ?></label> <?php echo $docs_select ?> <input type="button" class="button" value="<?php esc_attr_e( 'Look Up' ) ?> " onclick="if ( '' != jQuery('#docs-list').val() ) { window.open( 'https://api.wordpress.org/core/handbook/1.0/?function=' + escape( jQuery( '#docs-list' ).val() ) + '&amp;locale=<?php echo urlencode( get_user_locale() ) ?>&amp;version=<?php echo urlencode( get_bloginfo( 'version' ) ) ?>&amp;redirect=true'); }" /></div>
   249 		<?php endif; ?>
   262 		<?php endif; ?>
   250 <?php if ( is_writeable($real_file) ) : ?>
   263 <?php if ( is_writeable($real_file) ) : ?>
   251 	<?php if ( in_array( $file, (array) get_option( 'active_plugins', array() ) ) ) { ?>
   264 	<div class="editor-notices">
   252 		<p><?php _e('<strong>Warning:</strong> Making changes to active plugins is not recommended. If your changes cause a fatal error, the plugin will be automatically deactivated.'); ?></p>
   265 		<?php if ( in_array( $plugin, (array) get_option( 'active_plugins', array() ) ) ) { ?>
   253 	<?php } ?>
   266 			<div class="notice notice-warning inline active-plugin-edit-warning">
       
   267 			<p><?php _e('<strong>Warning:</strong> Making changes to active plugins is not recommended.'); ?></p>
       
   268 		</div>
       
   269 		<?php } ?>
       
   270 	</div>
   254 	<p class="submit">
   271 	<p class="submit">
   255 	<?php
   272 		<?php submit_button( __( 'Update File' ), 'primary', 'submit', false ); ?>
   256 		if ( isset($_GET['phperror']) ) {
   273 		<span class="spinner"></span>
   257 			echo "<input type='hidden' name='phperror' value='1' />";
       
   258 			submit_button( __( 'Update File and Attempt to Reactivate' ), 'primary', 'submit', false );
       
   259 		} else {
       
   260 			submit_button( __( 'Update File' ), 'primary', 'submit', false );
       
   261 		}
       
   262 	?>
       
   263 	</p>
   274 	</p>
   264 <?php else : ?>
   275 <?php else : ?>
   265 	<p><em><?php _e('You need to make this file writable before you can save your changes. See <a href="https://codex.wordpress.org/Changing_File_Permissions">the Codex</a> for more information.'); ?></em></p>
   276 	<p><em><?php _e('You need to make this file writable before you can save your changes. See <a href="https://codex.wordpress.org/Changing_File_Permissions">the Codex</a> for more information.'); ?></em></p>
   266 <?php endif; ?>
   277 <?php endif; ?>
       
   278 <?php wp_print_file_editor_templates(); ?>
   267 </form>
   279 </form>
   268 <br class="clear" />
   280 <br class="clear" />
   269 </div>
   281 </div>
   270 <script type="text/javascript">
       
   271 jQuery(document).ready(function($){
       
   272 	$('#template').submit(function(){ $('#scrollto').val( $('#newcontent').scrollTop() ); });
       
   273 	$('#newcontent').scrollTop( $('#scrollto').val() );
       
   274 });
       
   275 </script>
       
   276 <?php
   282 <?php
   277 	break;
   283 $dismissed_pointers = explode( ',', (string) get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) );
   278 }
   284 if ( ! in_array( 'plugin_editor_notice', $dismissed_pointers, true ) ) :
       
   285 	// Get a back URL
       
   286 	$referer = wp_get_referer();
       
   287 	$excluded_referer_basenames = array( 'plugin-editor.php', 'wp-login.php' );
       
   288 
       
   289 	if ( $referer && ! in_array( basename( parse_url( $referer, PHP_URL_PATH ) ), $excluded_referer_basenames, true ) ) {
       
   290 		$return_url = $referer;
       
   291 	} else {
       
   292 		$return_url = admin_url( '/' );
       
   293 	}
       
   294 ?>
       
   295 <div id="file-editor-warning" class="notification-dialog-wrap file-editor-warning hide-if-no-js hidden">
       
   296 	<div class="notification-dialog-background"></div>
       
   297 	<div class="notification-dialog">
       
   298 		<div class="file-editor-warning-content">
       
   299 			<div class="file-editor-warning-message">
       
   300 				<h1><?php _e( 'Heads up!' ); ?></h1>
       
   301 				<p><?php _e( 'You appear to be making direct edits to your plugin in the WordPress dashboard. We recommend that you don&#8217;t! Editing plugins directly may introduce incompatibilities that break your site and your changes may be lost in future updates.' ); ?></p>
       
   302 				<p><?php _e( 'If you absolutely have to make direct edits to this plugin, use a file manager to create a copy with a new name and hang on to the original. That way, you can re-enable a functional version if something goes wrong.' ); ?></p>
       
   303 			</div>
       
   304 			<p>
       
   305 				<a class="button file-editor-warning-go-back" href="<?php echo esc_url( $return_url ); ?>"><?php _e( 'Go back' ); ?></a>
       
   306 				<button type="button" class="file-editor-warning-dismiss button button-primary"><?php _e( 'I understand' ); ?></button>
       
   307 			</p>
       
   308 		</div>
       
   309 	</div>
       
   310 </div>
       
   311 <?php
       
   312 endif; // editor warning notice
       
   313 
   279 include(ABSPATH . "wp-admin/admin-footer.php");
   314 include(ABSPATH . "wp-admin/admin-footer.php");