在插件中,如何使用AJAX更新JSON文件

时间:2020-11-13 作者:Lbh

Context

学习插件创建,我想在用户每次单击div外部时保存div的内容。简而言之,其目的是创建记事本的文本备份。

我在当地工作。

Steps

<有些文本是用div编写的(感谢Trumbowyg.js)

Issues

几个我想我在第三步受阻了。几个小时的信息搜索让我不知所措。

Update

我尝试使用wp\\u remote\\u get()而不是file\\u get\\u contents(),它返回错误:[0]=>;未提供有效的URL。然而,我不知道它需要什么样的路径。

jdr。js公司

    $path = plugin_dir_path ( __FILE__ ) . "assets/json/notes.json";
    // $path = plugin_dir_url ( __FILE__ ) . "assets/json/notes.json";
    // $path = ABSPATH . "assets/json/notes.json";
    // $path = plugins_url("/jdr/assets/json/notes.json");
    
    $args_for_get = array(
        \'stream\' => true,
        \'sslverify\' => false,
        \'filename\' => $chemin3,
        \'reject_unsafe_urls\' => true,
        \'method\' => "POST"
    );
    $response = wp_remote_get( $chemin, $args_for_get );
    print_r(response);
控制台中的$响应

WP_Error Object
(
  [errors] => Array
    (
        [http_request_failed] => Array
            (
                [0] => L’URL fournie n’est pas valide. // A valid URL was not provided
            )

    )

[error_data] => Array
    (
    )

)

My code

Wordpress plugin structure:
plugins/
       -jdr.php
       -lbh-jdr/
               -inc/
                   -enqueue-scripts.php
                   -fonctions.php (= functions)
               -assets/
                      -js/
                           -plugin-jdr.js
                      -json/
                           -notes.json
jdr。php

<?php
/*
Plugin Name: jdr
etc..
*/

function lbh_jdr() {

  defined(\'MYPLUGIN_DIR\') or define(\'MYPLUGIN_DIR\', plugin_dir_path( __FILE__ ));

  include_once( MYPLUGIN_DIR . \'/inc/enqueue-scripts.php\');
  include_once( MYPLUGIN_DIR . \'/inc/fonctions.php\');

  $texte = $_REQUEST["texte"];
  $sessionPerso = $_REQUEST["sessionPerso"];
  $appelFonction = $_REQUEST["ajaxAction"];

  switch($appelFonction) {
    case \'sauvegarderNote\' : do_action("sauvegarderNote", $texte); break;
  }

  if(defined(\'DOING_AJAX\') && DOING_AJAX) die();
}
add_action("wp_ajax_lbh_jdr", "lbh_jdr");
add_action("wp_ajax_nopriv_lbh_jdr", "lbh_jdr");
?>
将脚本排队。php

注意:如果我封装排队脚本+add\\u操作,它将不起作用。不知道为什么

正确的方法:

function my_script_enqueuer() {
  wp_enqueue_script( "jdr-script", plugins_url("jdr/assets/js/plugin-jdr.js", __FILE__), 
  array("jquery"), "", true );
  wp_localize_script( "jdr-script", "myAjax", array(
    "ajaxurl" => admin_url( "admin-ajax.php"
    )));
}
add_action( \'wp_enqueue_scripts\', \'my_script_enqueuer\' );
为我工作的方式:

wp_enqueue_script( "jdr-script", plugins_url("jdr/assets/js/plugin-jdr.js", __FILE__), 
array("jquery"), "", true );
wp_localize_script( "jdr-script", "myAjax", array(
    "ajaxurl" => admin_url( "admin-ajax.php"
    )));
功能。php

add_action(\'wp_ajax_nopriv_sauvegarderNote\', \'sauvegarderNote\');
add_action(\'wp_ajax_sauvegarderNote\', \'sauvegarderNote\');

function sauvegarderNote() { // sauvergarderNote means saveNote

  $json = getJsondata();
  $jsonTableau = $json[0]; // Tableau means array
  $jsonChemin = $json[1];  // Chemin means path

  $jsonTableau["notes"] = [$texte];
  array_push($jsonTableau, $texte);

  $newJsonString = json_encode($jsonTableau, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | 
  JSON_UNESCAPED_SLASHES);
  file_put_contents($jsonChemin, $newJsonString);
}

 function getJsondata() {

   $chemin = plugin_dir_url( __FILE__ ) . "inc/json/notes.json";
   $jsonString = file_get_contents($chemin);
   $tempArray = json_decode($jsonString, true);
   return $tempArray;
}
插件jdr。js公司

jQuery( document ).ready( function() {
  
    let newData = {
        action: "lbh_jdr",
        ajaxAction: "sauvegarderNote",
        texte: jQuery("#blocNotes").text(),
        sessionPerso: sessionPerso
    };

    jQuery.ajax({
        url: myAjax.ajaxurl,
        data: newData,
        type: \'post\',
        error: function(e) {
            console.log(e);
        }
    })
        .done(function(response) {
            console.log(response);
        });
});

Questions

所以如果我按照预期的方式执行,为什么我的enqueue\\u脚本不起作用?为什么file\\u get\\u contents不返回任何内容?使用wordpress+Ajax读取/写入json文件的正确方法是什么?

提前谢谢你,我将继续关注!

1 个回复
最合适的回答,由SO网友:Tom J Nowell 整理而成

这是您的主要问题:

chemin = plugin_dir_url( __FILE__ ) . "inc/json/notes.json";
代码中有5个关键错误:

  1. file_get_contents 需要文件路径,但您正在使用plugin_dir_url, 并非所有服务器都支持远程URLfile_get_contents 出于安全原因,如果他们这样做了,这将对性能造成巨大影响,因为它涉及HTTP请求plugin_dir_... 类型函数需要将主插件文件作为参数传递,以便它知道需要哪个插件的值,但是__FILE__ 不是主插件文件路径,您正在调用它fonctions.php! 这是一个巨大的错误,而不是这些函数是如何工作的plugins_url$texte 毫无疑问,在AJAX处理程序中,不能只使用不存在的变量,PHP将用\'\', 它必须来自某个地方

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

    plugin_dir_path( string $file )

    获取插件的文件系统目录路径(带尾部斜杠)FILE 已传入。

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

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

    为此,您需要在主插件文件中检索并存储该值,并且must在该文件中完成。根据您的文件夹/文件列表,这将是jdr.php 因为这是包含插件头的文件。

    我认为最简单的方法是:define( \'JDR_MAIN_FILE\', __FILE__ );, 然后使用JDR_MAIN_FILE 而不是__FILE__ 调用这些函数时,如下所示:

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

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

    因此:

    wp_enqueue_script( "jdr-script", plugins_url("jdr/assets/js/plugin-jdr.js", __FILE__ ), 
    array("jquery"), "", true );
    
    变成这样:

    wp_enqueue_script( "jdr-script", plugins_url("assets/js/plugin-jdr.js", JDR_MAIN_FILE ), 
    array("jquery"), "", true );
    
    请注意jdr/ 已从路径参数中删除。

    Finally, your plugins folder structure is broken.

    插件遵循以下两种模式之一:

    中的单个文件/plugins/ 包含插件PHP文件以及其他支持文件(如JS/CSS/PHP等)以及readme.txtplugin_ 和plugins_ 功能将正常工作。

    移动您的jdr.php 进入lbh-jdr 文件夹并调整中的包含路径jdr.php 并删除对jdr/ 在URL参数中。完成此操作后,您需要进入WP Admin并重新激活插件。

    A final note

    我知道你提到你的代码很凌乱,你可能认为这没关系,但事实并非如此。这不像你的卧室乱七八糟,但没有人来看你,乱七八糟的东西积极地促成了东西被打破,这就是我们所说的技术债务。

    Bonus Note

    您应该投资使用RESTAPI,您也可以提出同样的请求。而不是在wp-admin 文件夹并传递action 参数,您可以将其设置为一个非常永久的URL,例如。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!";
    }
    
    它将对回调自动返回的任何内容进行JSON编码。下面是获取该示例的javascript:

    <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>
    
    添加永久链接后,不要忘记重新保存它。您可以展开register_rest_route 调用不同的回调POSTDELETE 等等,给它一个参数列表,如何清理它们,验证它们,谁有权访问端点等等,core将为您完成所有这些工作。如果您使用不当,它甚至会给出人类可读的错误消息,这与AdminAjax不同0 让你想知道发生了什么。