wp/wp-admin/theme-editor.php
changeset 9 177826044cd9
parent 7 cf61fcea0001
child 16 a86126ab1dd4
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
    12 if ( is_multisite() && ! is_network_admin() ) {
    12 if ( is_multisite() && ! is_network_admin() ) {
    13 	wp_redirect( network_admin_url( 'theme-editor.php' ) );
    13 	wp_redirect( network_admin_url( 'theme-editor.php' ) );
    14 	exit();
    14 	exit();
    15 }
    15 }
    16 
    16 
    17 if ( !current_user_can('edit_themes') )
    17 if ( ! current_user_can( 'edit_themes' ) ) {
    18 	wp_die('<p>'.__('Sorry, you are not allowed to edit templates for this site.').'</p>');
    18 	wp_die( '<p>' . __( 'Sorry, you are not allowed to edit templates for this site.' ) . '</p>' );
    19 
    19 }
    20 $title = __("Edit Themes");
    20 
       
    21 $title       = __( 'Edit Themes' );
    21 $parent_file = 'themes.php';
    22 $parent_file = 'themes.php';
    22 
    23 
    23 get_current_screen()->add_help_tab( array(
    24 get_current_screen()->add_help_tab(
    24 'id'		=> 'overview',
    25 	array(
    25 'title'		=> __('Overview'),
    26 		'id'      => 'overview',
    26 'content'	=>
    27 		'title'   => __( 'Overview' ),
    27 	'<p>' . __( 'You can use the Theme Editor to edit the individual CSS and PHP files which make up your theme.' ) . '</p>' .
    28 		'content' =>
    28 	'<p>' . __( 'Begin by choosing a theme to edit from the dropdown menu and clicking the Select button. A list then appears of the theme&#8217;s template files. Clicking once on any file name causes the file to appear in the large Editor box.' ) . '</p>' .
    29 				'<p>' . __( 'You can use the theme editor to edit the individual CSS and PHP files which make up your theme.' ) . '</p>' .
    29 	'<p>' . __( 'For PHP files, you can use the Documentation dropdown to select from functions recognized in that file. Look Up takes you to a web page with reference material about that particular function.' ) . '</p>' .
    30 				'<p>' . __( 'Begin by choosing a theme to edit from the dropdown menu and clicking the Select button. A list then appears of the theme&#8217;s template files. Clicking once on any file name causes the file to appear in the large Editor box.' ) . '</p>' .
    30 	'<p id="editor-keyboard-trap-help-1">' . __( 'When using a keyboard to navigate:' ) . '</p>' .
    31 				'<p>' . __( 'For PHP files, you can use the Documentation dropdown to select from functions recognized in that file. Look Up takes you to a web page with reference material about that particular function.' ) . '</p>' .
    31 	'<ul>' .
    32 				'<p id="editor-keyboard-trap-help-1">' . __( 'When using a keyboard to navigate:' ) . '</p>' .
    32 	'<li id="editor-keyboard-trap-help-2">' . __( 'In the editing area, the Tab key enters a tab character.' ) . '</li>' .
    33 				'<ul>' .
    33 	'<li id="editor-keyboard-trap-help-3">' . __( 'To move away from this area, press the Esc key followed by the Tab key.' ) . '</li>' .
    34 				'<li id="editor-keyboard-trap-help-2">' . __( 'In the editing area, the Tab key enters a tab character.' ) . '</li>' .
    34 	'<li id="editor-keyboard-trap-help-4">' . __( 'Screen reader users: when in forms mode, you may need to press the Esc key twice.' ) . '</li>' .
    35 				'<li id="editor-keyboard-trap-help-3">' . __( 'To move away from this area, press the Esc key followed by the Tab key.' ) . '</li>' .
    35 	'</ul>' .
    36 				'<li id="editor-keyboard-trap-help-4">' . __( 'Screen reader users: when in forms mode, you may need to press the Esc key twice.' ) . '</li>' .
    36 	'<p>' . __( 'After typing in your edits, click Update File.' ) . '</p>' .
    37 				'</ul>' .
    37 	'<p>' . __( '<strong>Advice:</strong> think very carefully about your site crashing if you are live-editing the theme currently in use.' ) . '</p>' .
    38 				'<p>' . __( 'After typing in your edits, click Update File.' ) . '</p>' .
    38 	/* translators: %s: link to codex article about child themes */
    39 				'<p>' . __( '<strong>Advice:</strong> Think very carefully about your site crashing if you are live-editing the theme currently in use.' ) . '</p>' .
    39 	'<p>' . sprintf( __( 'Upgrading to a newer version of the same theme will override changes made here. To avoid this, consider creating a <a href="%s">child theme</a> instead.' ), __( 'https://codex.wordpress.org/Child_Themes' ) ) . '</p>' .
    40 				'<p>' . sprintf(
    40 	( is_network_admin() ? '<p>' . __( 'Any edits to files from this screen will be reflected on all sites in the network.' ) . '</p>' : '' ),
    41 					/* translators: %s: link to documentation on child themes */
    41 ) );
    42 					__( 'Upgrading to a newer version of the same theme will override changes made here. To avoid this, consider creating a <a href="%s">child theme</a> instead.' ),
       
    43 					__( 'https://developer.wordpress.org/themes/advanced-topics/child-themes/' )
       
    44 				) . '</p>' .
       
    45 				( is_network_admin() ? '<p>' . __( 'Any edits to files from this screen will be reflected on all sites in the network.' ) . '</p>' : '' ),
       
    46 	)
       
    47 );
    42 
    48 
    43 get_current_screen()->set_help_sidebar(
    49 get_current_screen()->set_help_sidebar(
    44 	'<p><strong>' . __('For more information:') . '</strong></p>' .
    50 	'<p><strong>' . __( 'For more information:' ) . '</strong></p>' .
    45 	'<p>' . __('<a href="https://codex.wordpress.org/Theme_Development">Documentation on Theme Development</a>') . '</p>' .
    51 	'<p>' . __( '<a href="https://codex.wordpress.org/Theme_Development">Documentation on Theme Development</a>' ) . '</p>' .
    46 	'<p>' . __('<a href="https://codex.wordpress.org/Using_Themes">Documentation on Using Themes</a>') . '</p>' .
    52 	'<p>' . __( '<a href="https://codex.wordpress.org/Using_Themes">Documentation on Using Themes</a>' ) . '</p>' .
    47 	'<p>' . __('<a href="https://codex.wordpress.org/Editing_Files">Documentation on Editing Files</a>') . '</p>' .
    53 	'<p>' . __( '<a href="https://codex.wordpress.org/Editing_Files">Documentation on Editing Files</a>' ) . '</p>' .
    48 	'<p>' . __('<a href="https://codex.wordpress.org/Template_Tags">Documentation on Template Tags</a>') . '</p>' .
    54 	'<p>' . __( '<a href="https://codex.wordpress.org/Template_Tags">Documentation on Template Tags</a>' ) . '</p>' .
    49 	'<p>' . __('<a href="https://wordpress.org/support/">Support Forums</a>') . '</p>'
    55 	'<p>' . __( '<a href="https://wordpress.org/support/">Support</a>' ) . '</p>'
    50 );
    56 );
    51 
    57 
    52 wp_reset_vars( array( 'action', 'error', 'file', 'theme' ) );
    58 wp_reset_vars( array( 'action', 'error', 'file', 'theme' ) );
    53 
    59 
    54 if ( $theme ) {
    60 if ( $theme ) {
    74 
    80 
    75 foreach ( $file_types as $type ) {
    81 foreach ( $file_types as $type ) {
    76 	switch ( $type ) {
    82 	switch ( $type ) {
    77 		case 'php':
    83 		case 'php':
    78 			$allowed_files += $theme->get_files( 'php', -1 );
    84 			$allowed_files += $theme->get_files( 'php', -1 );
    79 			$has_templates = ! empty( $allowed_files );
    85 			$has_templates  = ! empty( $allowed_files );
    80 			break;
    86 			break;
    81 		case 'css':
    87 		case 'css':
    82 			$style_files = $theme->get_files( 'css', -1 );
    88 			$style_files                = $theme->get_files( 'css', -1 );
    83 			$allowed_files['style.css'] = $style_files['style.css'];
    89 			$allowed_files['style.css'] = $style_files['style.css'];
    84 			$allowed_files += $style_files;
    90 			$allowed_files             += $style_files;
    85 			break;
    91 			break;
    86 		default:
    92 		default:
    87 			$allowed_files += $theme->get_files( $type, -1 );
    93 			$allowed_files += $theme->get_files( $type, -1 );
    88 			break;
    94 			break;
    89 	}
    95 	}
    97 	$allowed_files = array( 'style.css' => $allowed_files['style.css'] ) + $allowed_files;
   103 	$allowed_files = array( 'style.css' => $allowed_files['style.css'] ) + $allowed_files;
    98 }
   104 }
    99 
   105 
   100 if ( empty( $file ) ) {
   106 if ( empty( $file ) ) {
   101 	$relative_file = 'style.css';
   107 	$relative_file = 'style.css';
   102 	$file = $allowed_files['style.css'];
   108 	$file          = $allowed_files['style.css'];
   103 } else {
   109 } else {
   104 	$relative_file = wp_unslash( $file );
   110 	$relative_file = wp_unslash( $file );
   105 	$file = $theme->get_stylesheet_directory() . '/' . $relative_file;
   111 	$file          = $theme->get_stylesheet_directory() . '/' . $relative_file;
   106 }
   112 }
   107 
   113 
   108 validate_file_to_edit( $file, $allowed_files );
   114 validate_file_to_edit( $file, $allowed_files );
   109 
   115 
   110 // Handle fallback editing of file when JavaScript is not available.
   116 // Handle fallback editing of file when JavaScript is not available.
   111 $edit_error = null;
   117 $edit_error     = null;
   112 $posted_content = null;
   118 $posted_content = null;
   113 if ( 'POST' === $_SERVER['REQUEST_METHOD'] ) {
   119 if ( 'POST' === $_SERVER['REQUEST_METHOD'] ) {
   114 	$r = wp_edit_theme_plugin_file( wp_unslash( $_POST ) );
   120 	$r = wp_edit_theme_plugin_file( wp_unslash( $_POST ) );
   115 	if ( is_wp_error( $r ) ) {
   121 	if ( is_wp_error( $r ) ) {
   116 		$edit_error = $r;
   122 		$edit_error = $r;
   117 		if ( check_ajax_referer( 'edit-theme_' . $file . $stylesheet, 'nonce', false ) && isset( $_POST['newcontent'] ) ) {
   123 		if ( check_ajax_referer( 'edit-theme_' . $stylesheet . '_' . $relative_file, 'nonce', false ) && isset( $_POST['newcontent'] ) ) {
   118 			$posted_content = wp_unslash( $_POST['newcontent'] );
   124 			$posted_content = wp_unslash( $_POST['newcontent'] );
   119 		}
   125 		}
   120 	} else {
   126 	} else {
   121 		wp_redirect( add_query_arg(
   127 		wp_redirect(
   122 			array(
   128 			add_query_arg(
   123 				'a' => 1, // This means "success" for some reason.
   129 				array(
   124 				'theme' => $stylesheet,
   130 					'a'     => 1, // This means "success" for some reason.
   125 				'file' => $relative_file,
   131 					'theme' => $stylesheet,
   126 			),
   132 					'file'  => $relative_file,
   127 			admin_url( 'theme-editor.php' )
   133 				),
   128 		) );
   134 				admin_url( 'theme-editor.php' )
       
   135 			)
       
   136 		);
   129 		exit;
   137 		exit;
   130 	}
   138 	}
   131 }
   139 }
   132 
   140 
   133 	$settings = array(
   141 	$settings = array(
   139 
   147 
   140 	require_once( ABSPATH . 'wp-admin/admin-header.php' );
   148 	require_once( ABSPATH . 'wp-admin/admin-header.php' );
   141 
   149 
   142 	update_recently_edited( $file );
   150 	update_recently_edited( $file );
   143 
   151 
   144 	if ( ! is_file( $file ) )
   152 	if ( ! is_file( $file ) ) {
   145 		$error = true;
   153 		$error = true;
       
   154 	}
   146 
   155 
   147 	$content = '';
   156 	$content = '';
   148 	if ( ! empty( $posted_content ) ) {
   157 	if ( ! empty( $posted_content ) ) {
   149 		$content = $posted_content;
   158 		$content = $posted_content;
   150 	} elseif ( ! $error && filesize( $file ) > 0 ) {
   159 	} elseif ( ! $error && filesize( $file ) > 0 ) {
   151 		$f = fopen($file, 'r');
   160 		$f       = fopen( $file, 'r' );
   152 		$content = fread($f, filesize($file));
   161 		$content = fread( $f, filesize( $file ) );
   153 
   162 
   154 		if ( '.php' == substr( $file, strrpos( $file, '.' ) ) ) {
   163 		if ( '.php' == substr( $file, strrpos( $file, '.' ) ) ) {
   155 			$functions = wp_doc_link_parse( $content );
   164 			$functions = wp_doc_link_parse( $content );
   156 
   165 
   157 			$docs_select = '<select name="docs-list" id="docs-list">';
   166 			$docs_select  = '<select name="docs-list" id="docs-list">';
   158 			$docs_select .= '<option value="">' . esc_attr__( 'Function Name&hellip;' ) . '</option>';
   167 			$docs_select .= '<option value="">' . esc_attr__( 'Function Name&hellip;' ) . '</option>';
   159 			foreach ( $functions as $function ) {
   168 			foreach ( $functions as $function ) {
   160 				$docs_select .= '<option value="' . esc_attr( urlencode( $function ) ) . '">' . htmlspecialchars( $function ) . '()</option>';
   169 				$docs_select .= '<option value="' . esc_attr( urlencode( $function ) ) . '">' . htmlspecialchars( $function ) . '()</option>';
   161 			}
   170 			}
   162 			$docs_select .= '</select>';
   171 			$docs_select .= '</select>';
   163 		}
   172 		}
   164 
   173 
   165 		$content = esc_textarea( $content );
   174 		$content = esc_textarea( $content );
   166 	}
   175 	}
   167 
   176 
   168 $file_description = get_file_description( $relative_file );
   177 	$file_description = get_file_description( $relative_file );
   169 $file_show = array_search( $file, array_filter( $allowed_files ) );
   178 	$file_show        = array_search( $file, array_filter( $allowed_files ) );
   170 $description = esc_html( $file_description );
   179 	$description      = esc_html( $file_description );
   171 if ( $file_description != $file_show ) {
   180 	if ( $file_description != $file_show ) {
   172 	$description .= ' <span>(' . esc_html( $file_show ) . ')</span>';
   181 		$description .= ' <span>(' . esc_html( $file_show ) . ')</span>';
   173 }
   182 	}
   174 ?>
   183 	?>
   175 <div class="wrap">
   184 <div class="wrap">
   176 <h1><?php echo esc_html( $title ); ?></h1>
   185 <h1><?php echo esc_html( $title ); ?></h1>
   177 
   186 
   178 <?php if ( isset( $_GET['a'] ) ) : ?>
   187 <?php if ( isset( $_GET['a'] ) ) : ?>
   179 	<div id="message" class="updated notice is-dismissible">
   188 	<div id="message" class="updated notice is-dismissible">
   200 	</div>
   209 	</div>
   201 <?php endif; ?>
   210 <?php endif; ?>
   202 
   211 
   203 <div class="fileedit-sub">
   212 <div class="fileedit-sub">
   204 <div class="alignleft">
   213 <div class="alignleft">
   205 <h2><?php echo $theme->display( 'Name' ); if ( $description ) echo ': ' . $description; ?></h2>
   214 <h2>
       
   215 <?php
       
   216 echo $theme->display( 'Name' );
       
   217 if ( $description ) {
       
   218 	echo ': ' . $description;}
       
   219 ?>
       
   220 </h2>
   206 </div>
   221 </div>
   207 <div class="alignright">
   222 <div class="alignright">
   208 	<form action="theme-editor.php" method="get">
   223 	<form action="theme-editor.php" method="get">
   209 		<strong><label for="theme"><?php _e('Select theme to edit:'); ?> </label></strong>
   224 		<strong><label for="theme"><?php _e( 'Select theme to edit:' ); ?> </label></strong>
   210 		<select name="theme" id="theme">
   225 		<select name="theme" id="theme">
   211 <?php
   226 <?php
   212 foreach ( wp_get_themes( array( 'errors' => null ) ) as $a_stylesheet => $a_theme ) {
   227 foreach ( wp_get_themes( array( 'errors' => null ) ) as $a_stylesheet => $a_theme ) {
   213 	if ( $a_theme->errors() && 'theme_no_stylesheet' == $a_theme->errors()->get_error_code() )
   228 	if ( $a_theme->errors() && 'theme_no_stylesheet' == $a_theme->errors()->get_error_code() ) {
   214 		continue;
   229 		continue;
       
   230 	}
   215 
   231 
   216 	$selected = $a_stylesheet == $stylesheet ? ' selected="selected"' : '';
   232 	$selected = $a_stylesheet == $stylesheet ? ' selected="selected"' : '';
   217 	echo "\n\t" . '<option value="' . esc_attr( $a_stylesheet ) . '"' . $selected . '>' . $a_theme->display('Name') . '</option>';
   233 	echo "\n\t" . '<option value="' . esc_attr( $a_stylesheet ) . '"' . $selected . '>' . $a_theme->display( 'Name' ) . '</option>';
   218 }
   234 }
   219 ?>
   235 ?>
   220 		</select>
   236 		</select>
   221 		<?php submit_button( __( 'Select' ), '', 'Submit', false ); ?>
   237 		<?php submit_button( __( 'Select' ), '', 'Submit', false ); ?>
   222 	</form>
   238 	</form>
   223 </div>
   239 </div>
   224 <br class="clear" />
   240 <br class="clear" />
   225 </div>
   241 </div>
   226 <?php
   242 <?php
   227 if ( $theme->errors() )
   243 if ( $theme->errors() ) {
   228 	echo '<div class="error"><p><strong>' . __( 'This theme is broken.' ) . '</strong> ' . $theme->errors()->get_error_message() . '</p></div>';
   244 	echo '<div class="error"><p><strong>' . __( 'This theme is broken.' ) . '</strong> ' . $theme->errors()->get_error_message() . '</p></div>';
       
   245 }
   229 ?>
   246 ?>
   230 <div id="templateside">
   247 <div id="templateside">
   231 	<h2 id="theme-files-label"><?php _e( 'Theme Files' ); ?></h2>
   248 	<h2 id="theme-files-label"><?php _e( 'Theme Files' ); ?></h2>
   232 	<ul role="tree" aria-labelledby="theme-files-label">
   249 	<ul role="tree" aria-labelledby="theme-files-label">
   233 		<?php if ( ( $has_templates || $theme->parent() ) && $theme->parent() ) : ?>
   250 		<?php if ( ( $has_templates || $theme->parent() ) && $theme->parent() ) : ?>
   234 			<li class="howto">
   251 			<li class="howto">
   235 				<?php
   252 				<?php
   236 				/* translators: %s: link to edit parent theme */
   253 				/* translators: %s: link to edit parent theme */
   237 				echo sprintf( __( 'This child theme inherits templates from a parent theme, %s.' ),
   254 				echo sprintf(
   238 					sprintf( '<a href="%s">%s</a>',
   255 					__( 'This child theme inherits templates from a parent theme, %s.' ),
       
   256 					sprintf(
       
   257 						'<a href="%s">%s</a>',
   239 						self_admin_url( 'theme-editor.php?theme=' . urlencode( $theme->get_template() ) ),
   258 						self_admin_url( 'theme-editor.php?theme=' . urlencode( $theme->get_template() ) ),
   240 						$theme->parent()->display( 'Name' )
   259 						$theme->parent()->display( 'Name' )
   241 					)
   260 					)
   242 				);
   261 				);
   243 				?>
   262 				?>
   249 			</ul>
   268 			</ul>
   250 		</li>
   269 		</li>
   251 	</ul>
   270 	</ul>
   252 </div>
   271 </div>
   253 
   272 
   254 <?php if ( $error ) :
   273 <?php
   255 	echo '<div class="error"><p>' . __('Oops, no such file exists! Double check the name and try again, merci.') . '</p></div>';
   274 if ( $error ) :
   256 else : ?>
   275 	echo '<div class="error"><p>' . __( 'Oops, no such file exists! Double check the name and try again, merci.' ) . '</p></div>';
       
   276 else :
       
   277 	?>
   257 	<form name="template" id="template" action="theme-editor.php" method="post">
   278 	<form name="template" id="template" action="theme-editor.php" method="post">
   258 		<?php wp_nonce_field( 'edit-theme_' . $file . $stylesheet, 'nonce' ); ?>
   279 		<?php wp_nonce_field( 'edit-theme_' . $stylesheet . '_' . $relative_file, 'nonce' ); ?>
   259 		<div>
   280 		<div>
   260 			<label for="newcontent" id="theme-plugin-editor-label"><?php _e( 'Selected file content:' ); ?></label>
   281 			<label for="newcontent" id="theme-plugin-editor-label"><?php _e( 'Selected file content:' ); ?></label>
   261 			<textarea cols="70" rows="30" 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>
   282 			<textarea cols="70" rows="30" 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>
   262 			<input type="hidden" name="action" value="update" />
   283 			<input type="hidden" name="action" value="update" />
   263 			<input type="hidden" name="file" value="<?php echo esc_attr( $relative_file ); ?>" />
   284 			<input type="hidden" name="file" value="<?php echo esc_attr( $relative_file ); ?>" />
   264 			<input type="hidden" name="theme" value="<?php echo esc_attr( $theme->get_stylesheet() ); ?>" />
   285 			<input type="hidden" name="theme" value="<?php echo esc_attr( $theme->get_stylesheet() ); ?>" />
   265 		</div>
   286 		</div>
   266 	<?php if ( ! empty( $functions ) ) : ?>
   287 	<?php if ( ! empty( $functions ) ) : ?>
   267 		<div id="documentation" class="hide-if-no-js">
   288 		<div id="documentation" class="hide-if-no-js">
   268 		<label for="docs-list"><?php _e('Documentation:') ?></label>
   289 		<label for="docs-list"><?php _e( 'Documentation:' ); ?></label>
   269 		<?php echo $docs_select; ?>
   290 		<?php echo $docs_select; ?>
   270 		<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'); }" />
   291 		<input disabled id="docs-lookup" 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'); }" />
   271 		</div>
   292 		</div>
   272 	<?php endif; ?>
   293 	<?php endif; ?>
   273 
   294 
   274 	<div>
   295 	<div>
   275 		<div class="editor-notices">
   296 		<div class="editor-notices">
   276 			<?php if ( is_child_theme() && $theme->get_stylesheet() == get_template() ) : ?>
   297 			<?php if ( is_child_theme() && $theme->get_stylesheet() == get_template() ) : ?>
   277 				<div class="notice notice-warning inline">
   298 				<div class="notice notice-warning inline">
   278 					<p>
   299 					<p>
   279 						<?php if ( is_writeable( $file ) ) { ?><strong><?php _e( 'Caution:' ); ?></strong><?php } ?>
   300 						<?php
       
   301 						if ( is_writeable( $file ) ) {
       
   302 							?>
       
   303 						<strong><?php _e( 'Caution:' ); ?></strong><?php } ?>
   280 						<?php _e( 'This is a file in your current parent theme.' ); ?>
   304 						<?php _e( 'This is a file in your current parent theme.' ); ?>
   281 					</p>
   305 					</p>
   282 				</div>
   306 				</div>
   283 			<?php endif; ?>
   307 			<?php endif; ?>
   284 		</div>
   308 		</div>
   286 		<p class="submit">
   310 		<p class="submit">
   287 			<?php submit_button( __( 'Update File' ), 'primary', 'submit', false ); ?>
   311 			<?php submit_button( __( 'Update File' ), 'primary', 'submit', false ); ?>
   288 			<span class="spinner"></span>
   312 			<span class="spinner"></span>
   289 		</p>
   313 		</p>
   290 	<?php else : ?>
   314 	<?php else : ?>
   291 		<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>
   315 		<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>
   292 	<?php endif; ?>
   316 	<?php endif; ?>
   293 	</div>
   317 	</div>
   294 	<?php wp_print_file_editor_templates(); ?>
   318 	<?php wp_print_file_editor_templates(); ?>
   295 	</form>
   319 	</form>
   296 <?php
   320 	<?php
   297 endif; // $error
   321 endif; // $error
   298 ?>
   322 ?>
   299 <br class="clear" />
   323 <br class="clear" />
   300 </div>
   324 </div>
   301 <?php
   325 <?php
   302 $dismissed_pointers = explode( ',', (string) get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) );
   326 $dismissed_pointers = explode( ',', (string) get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) );
   303 if ( ! in_array( 'theme_editor_notice', $dismissed_pointers, true ) ) :
   327 if ( ! in_array( 'theme_editor_notice', $dismissed_pointers, true ) ) :
   304 	// Get a back URL
   328 	// Get a back URL
   305 	$referer = wp_get_referer();
   329 	$referer                    = wp_get_referer();
   306 	$excluded_referer_basenames = array( 'theme-editor.php', 'wp-login.php' );
   330 	$excluded_referer_basenames = array( 'theme-editor.php', 'wp-login.php' );
   307 
   331 
   308 	if ( $referer && ! in_array( basename( parse_url( $referer, PHP_URL_PATH ) ), $excluded_referer_basenames, true ) ) {
   332 	if ( $referer && ! in_array( basename( parse_url( $referer, PHP_URL_PATH ) ), $excluded_referer_basenames, true ) ) {
   309 		$return_url = $referer;
   333 		$return_url = $referer;
   310 	} else {
   334 	} else {
   311 		$return_url = admin_url( '/' );
   335 		$return_url = admin_url( '/' );
   312 	}
   336 	}
   313 ?>
   337 	?>
   314 <div id="file-editor-warning" class="notification-dialog-wrap file-editor-warning hide-if-no-js hidden">
   338 <div id="file-editor-warning" class="notification-dialog-wrap file-editor-warning hide-if-no-js hidden">
   315 	<div class="notification-dialog-background"></div>
   339 	<div class="notification-dialog-background"></div>
   316 	<div class="notification-dialog">
   340 	<div class="notification-dialog">
   317 		<div class="file-editor-warning-content">
   341 		<div class="file-editor-warning-content">
   318 			<div class="file-editor-warning-message">
   342 			<div class="file-editor-warning-message">
   319 				<h1><?php _e( 'Heads up!' ); ?></h1>
   343 				<h1><?php _e( 'Heads up!' ); ?></h1>
   320 				<p>
   344 				<p>
   321 					<?php
   345 					<?php
   322 					echo sprintf(
   346 					echo sprintf(
   323 						/* translators: %s: Codex URL */
   347 						/* translators: %s: link to documentation on child themes */
   324 						__( 'You appear to be making direct edits to your theme in the WordPress dashboard. We recommend that you don&#8217;t! Editing your theme directly could break your site and your changes may be lost in future updates. If you need to tweak more than your theme&#8217;s CSS, you might want to try <a href="%s">making a child theme</a>.' ),
   348 						__( 'You appear to be making direct edits to your theme in the WordPress dashboard. We recommend that you don&#8217;t! Editing your theme directly could break your site and your changes may be lost in future updates. If you need to tweak more than your theme&#8217;s CSS, you might want to try <a href="%s">making a child theme</a>.' ),
   325 						esc_url( __( 'https://codex.wordpress.org/Child_Themes' ) )
   349 						esc_url( __( 'https://developer.wordpress.org/themes/advanced-topics/child-themes/' ) )
   326 					);
   350 					);
   327 					?>
   351 					?>
   328 				</p>
   352 				</p>
   329 				<p><?php _e( 'If you decide to go ahead with direct edits anyway, 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>
   353 				<p><?php _e( 'If you decide to go ahead with direct edits anyway, 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>
   330 				
       
   331 			</div>
   354 			</div>
   332 			<p>
   355 			<p>
   333 				<a class="button file-editor-warning-go-back" href="<?php echo esc_url( $return_url ); ?>"><?php _e( 'Go back' ); ?></a>
   356 				<a class="button file-editor-warning-go-back" href="<?php echo esc_url( $return_url ); ?>"><?php _e( 'Go back' ); ?></a>
   334 				<button type="button" class="file-editor-warning-dismiss button button-primary"><?php _e( 'I understand' ); ?></button>
   357 				<button type="button" class="file-editor-warning-dismiss button button-primary"><?php _e( 'I understand' ); ?></button>
   335 			</p>
   358 			</p>
   336 		</div>
   359 		</div>
   337 	</div>
   360 	</div>
   338 </div>
   361 </div>
   339 <?php
   362 	<?php
   340 endif; // editor warning notice
   363 endif; // editor warning notice
   341 
   364 
   342 include(ABSPATH . 'wp-admin/admin-footer.php' );
   365 include( ABSPATH . 'wp-admin/admin-footer.php' );