Tente de modifier un fichier pour un thème ou un plugin.

Description

Lors de la modification d'un fichier PHP, des demandes de bouclage seront faites à l'admin et à la page d'accueil pour tenter de voir s'il y a une erreur fatale introduite. Si c'est le cas, la modification PHP sera annulée.

Paramètres

$args

(chaîne de caractères[])(Obligatoire)Args. Notez que toutes les valeurs d'arg sont déjà unslashed. Cependant, elles proviennent directement de $_POST et ne sont pas validées ou assainies de quelque manière que ce soit.

  • 'fichier'
    (chaîne de caractères) Chemin d'accès relatif au fichier.
  • "plugin
    (chaîne de caractères) Chemin du fichier du plugin relatif au répertoire des plugins.
  • 'thème'
    (chaîne de caractères) Thème en cours de modification.
  • 'newcontent' (nouveau contenu)
    (chaîne de caractères) Nouveau contenu pour le fichier.
  • 'nonce' (chaîne de caractères)
    (chaîne de caractères) Nonce.

Retourner

(true|WP_Error) True en cas de succès ou WP_Error en cas d'échec.

Source

Fichier : wp-admin/includes/file.php

functionwp_edit_theme_plugin_file($args){if(empty($args['file'])){returnnewWP_Error('missing_file');}$file=$args['file'];if(0!==validate_file($file)){returnnewWP_Error('bad_file');}if(!isset($args['newcontent'])){returnnewWP_Error('missing_content');}$content=$args['newcontent'];if(!isset($args['nonce'])){returnnewWP_Error('missing_nonce');}$plugin=null;$theme=null;$real_file=null;if(!empty($args['plugin'])){$plugin=$args['plugin'];if(!current_user_can('edit_plugins')){returnnewWP_Error('unauthorized',__('Sorry, you are not allowed to edit plugins for this site.'));}if(!wp_verify_nonce($args['nonce'],'edit-plugin_'.$file)){returnnewWP_Error('nonce_failure');}if(!array_key_exists($plugin,get_plugins())){returnnewWP_Error('invalid_plugin');}if(0!==validate_file($file,get_plugin_files($plugin))){returnnewWP_Error('bad_plugin_file_path',__('Sorry, that file cannot be edited.'));}$editable_extensions=wp_get_plugin_file_editable_extensions($plugin);$real_file=WP_PLUGIN_DIR.'/'.$file;$is_active=in_array($plugin,(array)get_option('active_plugins',array()),true);}elseif(!empty($args['theme'])){$stylesheet=$args['theme'];if(0!==validate_file($stylesheet)){returnnewWP_Error('bad_theme_path');}if(!current_user_can('edit_themes')){returnnewWP_Error('unauthorized',__('Sorry, you are not allowed to edit templates for this site.'));}$theme=wp_get_theme($stylesheet);if(!$theme->exists()){returnnewWP_Error('non_existent_theme',__('The requested theme does not exist.'));}if(!wp_verify_nonce($args['nonce'],'edit-theme_'.$stylesheet.'_'.$file)){returnnewWP_Error('nonce_failure');}if($theme->errors()&&'theme_no_stylesheet'===$theme->errors()->get_error_code()){returnnewWP_Error('theme_no_stylesheet',__('The requested theme does not exist.').' '.$theme->errors()->get_error_message());}$editable_extensions=wp_get_theme_file_editable_extensions($theme);$allowed_files=array();foreach($editable_extensionsas$type){switch($type){case'php':$allowed_files=array_merge($allowed_files,$theme->get_files('php',-1));break;case'css':$style_files=$theme->get_files('css',-1);$allowed_files['style.css']=$style_files['style.css'];$allowed_files=array_merge($allowed_files,$style_files);break;default:$allowed_files=array_merge($allowed_files,$theme->get_files($type,-1));break;}}// Compare based on relative paths.if(0!==validate_file($file,array_keys($allowed_files))){returnnewWP_Error('disallowed_theme_file',__('Sorry, that file cannot be edited.'));}$real_file=$theme->get_stylesheet_directory().'/'.$file;$is_active=(get_stylesheet()===$stylesheet||get_template()===$stylesheet);}else{returnnewWP_Error('missing_theme_or_plugin');}// Ensure file is real.if(!is_file($real_file)){returnnewWP_Error('file_does_not_exist',__('File does not exist! Please double check the name and try again.'));}// Ensure file extension is allowed.$extension=null;if(preg_match('/.([^.]+)$/',$real_file,$matches)){$extension=strtolower($matches[1]);if(!in_array($extension,$editable_extensions,true)){returnnewWP_Error('illegal_file_type',__('Files of this type are not editable.'));}}$previous_content=file_get_contents($real_file);if(!is_writable($real_file)){returnnewWP_Error('file_not_writable');}$f=fopen($real_file,'w+');if(false===$f){returnnewWP_Error('file_not_writable');}$written=fwrite($f,$content);fclose($f);if(false===$written){returnnewWP_Error('unable_to_write',__('Unable to write to file.'));}wp_opcache_invalidate($real_file,true);if($is_active&&'php'===$extension){$scrape_key=md5(rand());$transient='scrape_key_'.$scrape_key;$scrape_nonce=(string)rand();// It shouldn't take more than 60 seconds to make the two loopback requests.set_transient($transient,$scrape_nonce,60);$cookies=wp_unslash($_COOKIE);$scrape_params=array('wp_scrape_key'=>$scrape_key,'wp_scrape_nonce'=>$scrape_nonce,);$headers=array('Cache-Control'=>'no-cache',);/** This filter is documented in wp-includes/class-wp-http-streams.php */$sslverify=apply_filters('https_local_ssl_verify',false);// Include Basic auth in loopback requests.if(isset($_SERVER['PHP_AUTH_USER'])&&isset($_SERVER['PHP_AUTH_PW'])){$headers['Authorization']='Basic '.base64_encode(wp_unslash($_SERVER['PHP_AUTH_USER']).':'.wp_unslash($_SERVER['PHP_AUTH_PW']));}// Make sure PHP process doesn't die before loopback requests complete.set_time_limit(300);// Time to wait for loopback requests to finish.$timeout=100;$needle_start="###### wp_scraping_result_start:$scrape_key ######";$needle_end="###### wp_scraping_result_end:$scrape_key ######";// Attempt loopback request to editor to see if user just whitescreened themselves.if($plugin){$url=add_query_arg(compact('plugin','file'),admin_url('plugin-editor.php'));}elseif(isset($stylesheet)){$url=add_query_arg(array('theme'=>$stylesheet,'file'=>$file,),admin_url('theme-editor.php'));}else{$url=admin_url();}if(function_exists('session_status')&&PHP_SESSION_ACTIVE===session_status()){// Close any active session to prevent HTTP requests from timing out// when attempting to connect back to the site.session_write_close();}$url=add_query_arg($scrape_params,$url);$r=wp_remote_get($url,compact('cookies','headers','timeout','sslverify'));$body=wp_remote_retrieve_body($r);$scrape_result_position=strpos($body,$needle_start);$loopback_request_failure=array('code'=>'loopback_request_failed','message'=>__('Unable to communicate back with site to check for fatal errors, so the PHP change was reverted. You will need to upload your PHP file change by some other means, such as by using SFTP.'),);$json_parse_failure=array('code'=>'json_parse_error',);$result=null;if(false===$scrape_result_position){$result=$loopback_request_failure;}else{$error_output=substr($body,$scrape_result_position+strlen($needle_start));$error_output=substr($error_output,0,strpos($error_output,$needle_end));$result=json_decode(trim($error_output),true);if(empty($result)){$result=$json_parse_failure;}}// Try making request to homepage as well to see if visitors have been whitescreened.if(true===$result){$url=home_url('/');$url=add_query_arg($scrape_params,$url);$r=wp_remote_get($url,compact('cookies','headers','timeout','sslverify'));$body=wp_remote_retrieve_body($r);$scrape_result_position=strpos($body,$needle_start);if(false===$scrape_result_position){$result=$loopback_request_failure;}else{$error_output=substr($body,$scrape_result_position+strlen($needle_start));$error_output=substr($error_output,0,strpos($error_output,$needle_end));$result=json_decode(trim($error_output),true);if(empty($result)){$result=$json_parse_failure;}}}delete_transient($transient);if(true!==$result){// Roll-back file change.file_put_contents($real_file,$previous_content);wp_opcache_invalidate($real_file,true);if(!isset($result['message'])){$message=__('Something went wrong.');}else{$message=$result['message'];unset($result['message']);}returnnewWP_Error('php_error',$message,$result);}}if($themeinstanceofWP_Theme){$theme->cache_delete();}returntrue;}

Related

Utilise

Utilisations Description
wp-admin/includes/file.php : wp_opcache_invalidate()

Tente d'effacer le cache des opcodes pour un fichier PHP individuel.

wp-admin/includes/file.php : wp_get_plugin_file_editable_extensions()

Récupère la liste des extensions de fichiers modifiables dans les plugins.

wp-admin/includes/file.php : wp_get_theme_file_editable_extensions()

Récupère la liste des extensions de fichiers modifiables pour un thème donné.

wp-admin/includes/plugin.php : get_plugins()

Vérifie le répertoire des plugins et récupère tous les fichiers de plugins contenant des données de plugins.

wp-admin/includes/plugin.php : get_plugin_files()

Récupère la liste des fichiers d'un plugin.

wp-includes/capabilities.php : current_user_can()

Renvoie si l'utilisateur actuel a la capacité spécifiée.

wp-includes/theme.php : get_template()

Récupère le nom du thème actuel.

wp-includes/theme.php : wp_get_theme()

Obtient un objet WP_Theme pour un thème.

wp-includes/theme.php : get_stylesheet()

Récupère le nom de la feuille de style actuelle.

wp-includes/l10n.php : __()

Récupère la traduction de $text.

wp-includes/formatting.php : wp_unslash()

Supprime les barres obliques d'une chaîne de caractères ou supprime récursivement les barres obliques des chaînes de caractères dans un tableau.

wp-includes/pluggable.php : wp_verify_nonce()

Vérifie qu'un nonce de sécurité correct a été utilisé avec une limite de temps.

wp-includes/class-wp-http-streams.php :https_local_ssl_verify

Filtre si le SSL doit être vérifié pour les demandes d'API HTTP locales.

wp-includes/functions.php : validate_file()

Valide le nom et le chemin d'un fichier par rapport à un ensemble de règles autorisées.

wp-includes/functions.php : add_query_arg()

Récupère une chaîne de requête d'URL modifiée.

wp-includes/link-template.php : admin_url()

Récupère l'URL de la zone d'administration pour le site actuel.

wp-includes/link-template.php : home_url()

Récupère l'URL du site actuel où le front-end est accessible.

wp-includes/http.php : wp_remote_get()

Effectue une requête HTTP en utilisant la méthode GET et renvoie sa réponse.

wp-includes/http.php : wp_remote_retrieve_body()

Récupérer uniquement le corps de la réponse brute.

wp-includes/plugin.php : apply_filters()

Appelle les fonctions de rappel qui ont été ajoutées à un crochet de filtre.

wp-includes/option.php : set_transient()

Définit/met à jour la valeur d'un transitoire.

wp-includes/option.php : delete_transient()

Supprime un transitoire.

wp-includes/option.php : get_option()

Récupère une valeur d'option en fonction d'un nom d'option.

wp-includes/class-wp-error.php : WP_Error::__construct()

Initialise l'erreur.

Utilisé par

Utilisé par Description
wp-admin/includes/ajax-actions.php : wp_ajax_edit_theme_plugin_file()

Gestionnaire Ajax pour l'édition d'un fichier de thème ou de plugin.

Changelog

Version Description
4.9.0 Introduit.