Ajax PHP 类结构 WordPress 数据:{ action : 'ds_calculators::myfunction', },

问题描述 投票:0回答:2

自从我使用 AJAX 和 Wordpress 以来已经有一段时间了。我以前做事的方式非常简单,使用在 functions.php 中创建函数的函数名称,然后我使用 :

添加操作
add_action('wp_ajax_nopriv_myfunction', 'myfunction');
add_action('wp_ajax_myfunction', 'myfunction');

我在这里画了一个空白,因为现在我的 PHP 代码结构有点不同,我的函数不再位于我的 functions.php 文件中。它位于一个名为:

的类中

ds_calculators

$.ajax({
    type: 'POST',
    url: my_ajax.ajaxurl,
    data: { action : 'ds_calculators::myfunction', },
    success: function(data, textStatus, XMLHttpRequest)
            {
                //jQuery('#table_listing').html(''); // empty an element
                jQuery('.changer').html(data); // put our list of links into it
            },
        error: function(XMLHttpRequest, textStatus, errorThrown)
        {
            if (typeof console === "undefined")
            {
                console = {
                    log: function() {},
                    debug: function() {},
                };
            }
            if (XMLHttpRequest.status == 404)
            {
                console.log('Element not found.');
            }
            else
            {
                console.log('Error: ' + errorThrown);
            }
        }
    });

我现在添加这样的动作

add_action('wp_ajax_nopriv_myFunction', 'ds_calculators::myFunction');
add_action('wp_ajax_myFunction', 'ds_calculators::myFunction');

对于上述情况,我遇到了 400(错误请求)。当函数在类中时,如何包含函数名称?那是我的问题还是我的其他问题?

php ajax wordpress
2个回答
1
投票

你不需要在 JS 端指定类引用:

    $.ajax({
              url: window.ajaxurl,
              method: "post",
              data: {
                action: "myfunction",
              },
            })
...

在php模板中,如果你的函数在类中,你需要引用它的实例($this)来指定它。

add_action( 'wp_ajax_myfunction', array($this, 'myfunction') );
add_action('wp_ajax_nopriv_myfunction', array($this, 'myfunction') );

如果 (myfucntion) 方法是静态的,那么您将使用类名为 'ds_calculators::myfunction' 的作用域运算符

add_action( 'wp_ajax_myfunction', 'ds_calculators::myfunction' );
add_action('wp_ajax_nopriv_myfunction', 'ds_calculators::myfunction' );

记住

wp_ajax_nopriv_{$action}
为注销的用户触发未经身份验证的 Ajax 操作。


0
投票

如果你使用 wp_ajax 钩子,你不需要太担心命名空间。

add_action( 'wp_ajax_myfunction', array($this, 'myfunction') );

告诉 wordpress,当请求发送到默认的 ajax url 时,操作设置为“myfunction”,以将其传递给解析时引用的回调函数。唯一要注意的是

wp_ajax_${your_function/action_name}
必须与它在解析时调用的函数相同,并且所讨论的方法必须是 public

这里 是一篇关于如何在类中实现 wordpress ajax 处理程序的精彩文章,以及我从哪里偷来的

namespace MyPlugin;

class AjaxHandler
{
    /**
     * Action hook used by the AJAX class.
     *
     * @var string
     */
    const ACTION = 'my_plugin';

    /**
     * Action argument used by the nonce validating the AJAX request.
     *
     * @var string
     */
    const NONCE = 'my-plugin-ajax';

    /**
     * Register the AJAX handler class with all the appropriate WordPress hooks.
     */
    public static function register()
    {
        $handler = new self();

        add_action('wp_ajax_' . self::ACTION, array($handler, 'handle'));
        add_action('wp_ajax_nopriv_' . self::ACTION, array($handler, 'handle'));
        add_action('wp_loaded', array($handler, 'register_script'));
    }

    /**
     * Handles the AJAX request for my plugin.
     */
    public function handle()
    {
        // Make sure we are getting a valid AJAX request
        check_ajax_referer(self::NONCE);

        // Stand back! I'm about to try... SCIENCE!

        die();
    }

    /**
     * Register our AJAX JavaScript.
     */
    public function register_script()
    {
        wp_register_script('wp_ajax', plugins_url('path/to/ajax.js', __FILE__));
        wp_localize_script('wp_ajax', 'wp_ajax_data', $this->get_ajax_data());
        wp_enqueue_script('wp_ajax');
    }

    /**
     * Get the AJAX data that WordPress needs to output.
     *
     * @return array
     */
    private function get_ajax_data()
    {
        return array(
            'action' => self::ACTION,
            'nonce' => wp_create_nonce(AjaxHandler::NONCE)
        );
    }

    /**
     * Get the comment text sent by the AJAX request.
     *
     * @return string
     */
    private function get_comment()
    {
        $comment = '';

        if (isset($_POST['comment'])) {
            $comment = filter_var($_POST['comment'], FILTER_SANITIZE_STRING);
        }

        return $comment;
    }

    /**
     * Get the post ID sent by the AJAX request.
     *
     * @return int
     */
    private function get_post_id()
    {
        $post_id = 0;

        if (isset($_POST['post_id'])) {
            $post_id = absint(filter_var($_POST['post_id'], FILTER_SANITIZE_NUMBER_INT));
        }

        return $post_id;
    }

    /**
     * Sends a JSON response with the details of the given error.
     *
     * @param WP_Error $error
     */
    private function send_error(WP_Error $error)
    {
        wp_send_json(array(
            'code' => $error->get_error_code(),
            'message' => $error->get_error_message()
        ));
    }
}

Ajax::register();

如果您有兴趣将 REST API 与 ajax api 一起使用/而不是 ajax api,这里是我制作的一个快速课程,了解如何完成并显示该设置中的命名空间,以及涵盖 wp-nonce 的基础知识

<?php
/**
 * Demo Rest API
 *
 * This file is included in my main plugin class on the
 * 'init' action hook. Then the class is instantiated
 * (aka new RestApi() is called) and the constructor for
 * this calss fires adding the rest_api_init action hook 
 * for the register_routes() method.
 *
 * @author yourname
 * @version $Id$
 * @copyright yourname, 22 February, 2023
 * @package default
 */

declare(strict_types = 1);

namespace TESEO;

use WP_REST_Server;
use WP_REST_Request;
use WP_REST_Response;
use WP_Error;

/**
 * Class RestApi
 *
 * @package TESEO
 */
class RestApi {

  /**
   * Define the url in a constant
   */
  const DEMO_URL = 'teseo/v1';


    /**
     * RestApi constructor.
     */
    public function __construct() {
        add_action( 'rest_api_init', array( $this, 'register_routes' ) );
        add_action( 'wp_footer', array( $this, 'TESEO_plugin_path' ) );
    }


    /**
     * Add plugin path constant to the footer
     *
     * @return void
     */
    public function TESEO_plugin_path(): void {
        ?>
        <script>
    // For use in the frontend ajax
            var my_plugin_js_vars = {
                'plugin_url': '<?php echo plugin_dir_url( __FILE__ ); ?>'
                'ajax_url': '<?php echo \admin_url( 'admin-ajax.php' ); ?>',
                'nonce': '<?php echo \wp_create_nonce( 'npg_ajax_nonce' ); ?>',
            };
    // For use with rest you want a nonce
      var my_plugin_rest_vars = {
        'nonce': '<?php echo \wp_create_nonce( 'wp_rest' ); ?>',
      };
        </script>
        <?php
    }

    /**
     * Register rest API routes on the 'rest_api_init' action
   *
   * This is where most of the 'namespacing' happens.
   * The default base url is '/wp-json/' with the namespace being the first part of the url.
   * So in this case the url would be '/wp-json/teseo/v1/' with the namespace being 'teseo'.
   * The version is the second part of the url, and the actual route is the third part of the url.
     */
    public function register_routes(): void {
        register_rest_route(
            'teseo/v1',
            '/dummy',
            array(
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => array( $this, 'get_dummy' ),
                'permission_callback' => array( $this, 'get_dummy_permissions_check' ),
                'args'                => array(),
            )
        );

        register_rest_route(
            'teseo/v1',
            '/dummy/validate',
            array(
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => array( $this, 'get_dummy_validate' ),
                'permission_callback' => array( $this, 'get_dummy_validate_permissions_check' ),
                'args'                => array(
                    'id' => array(
                        'required'          => true,
                        'validate_callback' => function( $param, $request, $key ) {
                            return is_numeric( $param );
                        },
                    ),
                    'nonce' => array(
                        'required'          => true,
                        'validate_callback' => function( $param, $request, $key ) {
                            return wp_verify_nonce( $param, 'wp_rest' );
                        },
                    ),
                ),
            ),
        );
    }

    /**
     * Get dummy
     *
     * @param WP_REST_Request $request Request.
     *
     * @return WP_REST_Response|WP_Error
     */
    public function get_dummy( WP_REST_Request $request ): WP_REST_Response {
        $data = array(
            'message' => 'Hello World',
        );

        return new WP_REST_Response( $data, 200 );
    }

    /**
     * Get dummy permissions check
     *
     * @param WP_REST_Request $request Request.
     *
     * @return bool|WP_Error
     */
    public function get_dummy_permissions_check( WP_REST_Request $request ): bool {
        return true;
    }

    /**
     * Get dummy validate
     *
     * @param WP_REST_Request $request Request.
     * @return WP_REST_Response|WP_Error
     */
    public function get_dummy_validate( WP_REST_Request $request ): WP_REST_Response {
        $data = array(
            'message' => 'Hello World',
        );

        return new WP_REST_Response( $data, 200 );
    }

    /**
     * Get dummy validate permissions check
   *
   * We don't actually need to do anything here, because the permission check
   * is already done in the parameter validation. But if we wanted to, we could
   * do extra checks here for the current user, role or whatever.
     *
     * @param WP_REST_Request $request Request.
     * @return bool|WP_Error
     */
    public function get_dummy_validate_permissions_check( WP_REST_Request $request ) {
        // check if the user has the role 'administrator'
        if ( ! current_user_can( 'administrator' ) ) {
            return new WP_Error( 'rest_forbidden', esc_html__( 'You do not have permission to do this.', 'textdomain' ), array( 'status' => 401 ) );
        }

        // check if the users id is 1
        if ( 1 !== get_current_user_id() ) {
            return new WP_Error( 'rest_forbidden', esc_html__( 'You do not have permission to do this.', 'textdomain' ), array( 'status' => 401 ) );
        }

        // arbitrary check for some other condition
        return $this->validate_arbitrary_permissions_check( $request ) ? true : new WP_Error( 'rest_forbidden', esc_html__( 'You do not have permission to do this.', 'textdomain' ), array( 'status' => 401 ) );
    }

    /**
     * Validate that the user making the request has made atleast 5 posts
     * in the last 30 days.
     *
     * @param WP_REST_Request $request Request.
     * @return bool|WP_Error
     */
    public function validate_arbitrary_permissions_check( WP_REST_Request $request ) {
        // get the current user
        $user = wp_get_current_user();

        // get the users posts
        $posts = get_posts(
            array(
                'author'      => $user->ID,
                'date_query'  => array(
                    array(
                        'after' => '30 days ago',
                    ),
                ),
                'post_type'   => 'post',
                'post_status' => 'publish',
            )
        );

        // check if the user has made atleast 5 posts in the last 30 days
        if ( count( $posts ) < 5 ) {
            return new WP_Error( 'rest_forbidden', esc_html__( 'You do not have permission to do this.', 'textdomain' ), array( 'status' => 401 ) );
        }

        return true;
    }


}
© www.soinside.com 2019 - 2024. All rights reserved.