In a plugin, How to update a json file using ajax

Here is your main problem:

chemin = plugin_dir_url( __FILE__ ) . "inc/json/notes.json";

There are 5 critical mistakes in the code:

  1. file_get_contents requires a file path, but you’re asking for a URL by using plugin_dir_url, not all servers support remote URLs in file_get_contents for security reasons, and if they do, this would be a big performance hit as it involves a HTTP request
  2. plugin_dir_… type functions need the main plugin file to be passed as a parameter so it knows which plugin you need the value for, but __FILE__ is not the main plugin file path, you’re calling it in fonctions.php! This is a huge mistake, and not how these functions work.
  3. The same mistake is made in lots of other places, e.g. all uses of the function plugins_url
  4. Your plugins structure is highly unusual, with a single file plugin that then references a plugin folder that contains no plugins
  5. You’re pulling $texte out of thin air, in your AJAX handler, you can’t just use a variable that doesn’t exist, PHP will replace it with '', it has to come from somewhere

So first, you need to use the correct function, use plugin_dir_path instead:

plugin_dir_path( string $file )

Get the filesystem directory path (with trailing slash) for the plugin FILE passed in.

https://developer.wordpress.org/reference/functions/plugin_dir_path/

Next, we need to give it the actual plugin file.

For this you will need to retrieve and store this value inside the main plugin file, and it must be done in that file. According to your folder/file list, this would be jdr.php as that’s the file containing the plugin header.

I believe the easiest way to do this for you is something like this: define( 'JDR_MAIN_FILE', __FILE__ );, then using JDR_MAIN_FILE instead of __FILE__ when calling these functions, like this:

chemin = plugin_dir_path( JDR_MAIN_FILE ) . "inc/json/notes.json";

Then, we need to do the same to every instance of plugins_url

So this:

wp_enqueue_script( "jdr-script", plugins_url("jdr/assets/js/plugin-jdr.js", __FILE__ ), 
array("jquery"), "", true );

Becomes this:

wp_enqueue_script( "jdr-script", plugins_url("assets/js/plugin-jdr.js", JDR_MAIN_FILE ), 
array("jquery"), "", true );

Notice the jdr/ was removed from the path parameter.

Finally, your plugins folder structure is broken.

Plugins follow 1 of 2 patterns:

  • A single file in the /plugins/ folder that is self contained
  • A folder that contains a plugin PHP file, as well as other supporting files such as JS/CSS/PHP etc, as well as a readme.txt

You appear to have done neither. As a result none of the plugin_ and plugins_ functions will work correctly.

Move your jdr.php into the lbh-jdr folder and adjust the include paths in jdr.php and remove any reference to jdr/ in the URL parameters. You will need to go into WP Admin and reactivate your plugin after doing this.

A final note

I know that you mention your code is messy, and you might think that’s ok, but it is not. This isn’t like when your bedroom is messy but nobody comes to visit, the mess has actively contributed things being broken, and is what we would term technical debt.

Bonus Note

You should invest in using the REST API, you can make a request just the same. Instead of making it to an obscure PHP file in the wp-admin folder and passing an action parameter, you make it to a pretty permalink URL, e.g. example.com/wp-json/hurlemort/v1/example:

add_action( 'rest_api_init', function () {
        register_rest_route( 'hurlemort/v1', '/example/', array(
                'methods' => 'GET',
                'callback' => 'hurlemorts_endpoint'
        ) );
} );

function hurlemorts_endpoint( $request ) {
    return "Hello World!";
}

It will JSON encode anything the callback returns automatically. Here’s the javascript to fetch that example:

<script>
jQuery.ajax({
    url: <?php echo wp_json_encode( esc_url_raw( rest_url( 'hurlemort/v1/example' ) ) ); ?>
}).done(function( data ) {
    alert( data ); // prints Hello World!
});
</script>

Don’t forget to re-save permalinks after you add it. You can expand the register_rest_route to call different callbacks on POST OR DELETE etc, give it a list of arguments, how to sanitise them, validate them, who has access to the endpoint, etc etc and core will do all that work for you. It even gives human readable error messages if you use it incorrectly, unlike admin ajax that just says 0 and leaves you wondering what happened.