用于WordPress的改进的Ajax技术:面向对象的编程

在本系列的上一篇文章中,我们重新讨论了在WordPress中使用Ajax的主题。 最终,目标是改进几年前在该站点上运行的以前的系列

重申一下,并不是说原始系列中讲授的技术是错误的,而是软件会随着时间的推移而变化,因此最好回顾一下几年前介绍的概念,并尝试将其更新为更具最新性和灵活性的东西。为我们的发展努力。

回想一下以前的帖子 ,我们看了原始系列的以下评论:

我们将简要介绍一下Ajax是什么,它如何工作,如何在前端进行设置以及了解WordPress提供的功能。 实际上,我们还将构建一个将理论付诸实践的小项目。 我们将遍历源代码,并确保它在GitHub上也可用。

在那篇文章中,我们回顾了一些使用过程编程将WordPress Ajax API集成到我们的项目中的高级方法。 在本文中,我们将采用在本系列第一部分中编写的代码并对其进行重构,以使其使用面向对象的方法。

最终,目的不是要弄清楚为什么一个范式应该在另一个范式上使用; 相反,这是为了展示我们如何能够实现相同的功能,而与构建插件时选择的方法无关。

规划插件

在开始重构代码之前,我们需要考虑的是如何布置各种文件。 毕竟,开始一个新项目,甚至跳入一个老项目的过程的一部分,是计划如何完成工作。

对于这个特定的插件,我们将需要以下内容:

  • 一个引导文件,负责初始化主类并启动插件
  • 一个负责加载依赖项的类,例如JavaScript
  • 用作主插件类的类

如您所见,我们对该插件没有太多要做。 我们还将重新组织一些文件,使其具有一致的目录结构,并确保正确记录所有代码,使其遵循WordPress编码标准

话虽如此,让我们开始吧。

整理文件

在编写任何代码之前,让我们继续执行以下操作:

  1. 创建assets目录。
  2. 创建一个将位于assets目录中的js目录。
  3. frontend.js移到js目录。
资产目录

这样做的原因是我们正在进入一种面向对象的编程风格。 其中一部分包括组织文件,使它们遵循通常被视为软件包的约定。

在我们的例子中, assets目录包含了使程序运行所需的所有东西。 对于某些插件,这可能是JavaScript,CSS,图像,字体等。 在这种情况下,我们只有一个JavaScript文件。

依赖加载器

接下来,我们需要引入一个类,该类负责为我们的项目加载依赖项。 对于这个特定的插件,我们唯一的依赖关系就是我们刚刚放置在assets目录中JavaScript文件。

面向对象编程的一部分是确保每个类都有特定的目的。 在这种情况下,我们将要介绍的类将负责使用WordPress API加载JavaScript。

让我们从创建类的基本结构开始:

<?php
    
/**
 * Loads and enqueues dependencies for the plugin.
 *
 * @since    1.0.0
 *
 * @package  WPA/includes
 */
class Dependency_Loader {
	
}

接下来,我们将添加一个方法,该方法将负责按照WordPress API排队JavaScript。

<?php
/**
 * Loads and registers dependencies.
 *
 * @since    1.0.0
 *
 * @package   WPA
 * @author    Tom McFarlin
 * @license   http://www.gnu.org/licenses/gpl-2.0.txt
 * @link      https://tommcfarlin.com/
 */

/**
 * Loads and enqueues dependencies for the plugin.
 *
 * @package    WPA
 * @subpackage WPA/includes
 * @since      1.0.0
 * @author     Tom McFarlin
 * @license    http://www.gnu.org/licenses/gpl-2.0.txt
 * @link       https://tommcfarlin.com/
 */
class Dependency_Loader {

    /**
     * Initializes the plugin by enqueuing the necessary dependencies.
	 *
	 * @since    1.0.0
	 */
    public function initialize() {
        $this->enqueue_scripts();
    }

    /**
	 * Enqueues the front-end scripts for getting the current user's information
	 * via Ajax.
	 *
     * @access   private
     * 
	 * @since    1.0.0
	 */
	private function enqueue_scripts() {

		wp_enqueue_script(
			'ajax-script',
			plugin_dir_url( dirname( __FILE__ ) ) . 'assets/js/frontend.js',
			array( 'jquery' )
		);

		wp_localize_script(
			'ajax-script',
			'sa_demo',
			array( 'ajax_url' => admin_url( 'admin-ajax.php' ) )
		);

	}
}

之后,我们需要采用负责处理Ajax请求和提供响应的功能,然后将它们添加到类中。 由于它们将在类的上下文中,因此我们需要添加一个新功能,以在WordPress中进行注册。

我们将创建一个setup_ajax_handlers函数。 看起来像这样:

<?php

/**
 * Registers the callback functions responsible for providing a response
 * to Ajax requests setup throughout the rest of the plugin.
 *
 * @since    1.0.0
 */
public function setup_ajax_handlers() {

    add_action(
		'wp_ajax_get_current_user_info',
		array( $this, 'get_current_user_info' )
	);

	add_action(
		'wp_ajax_nopriv_get_current_user_info',
		array( $this, 'get_current_user_info' )
	);

}

接下来,我们需要将函数实际移入此类。 请注意,原来以_sa的功能不再标记为。 由于它们在类的上下文中,因此我们可以删除前缀,也可以删除下划线以使用private关键字。

<?php

public function get_current_user_info() {

    $user_id = get_current_user_id();

	if ( $this->user_is_logged_in( $user_id ) && $this->user_exists( $user_id ) ) {

		wp_send_json_success(
			wp_json_encode( get_user_by( 'id', $user_id ) )
		);

	}

}

private function user_is_logged_in( $user_id ) {

	$is_logged_in = true;

	if ( 0 === $user_id ) {

		wp_send_json_error(
			new WP_Error( '-2', 'The visitor is not currently logged into the site.' )
		);

		$is_logged_in = false;

	}

	return $is_logged_in;

}

private function user_exists( $user_id ) {

	$user_exists = true;

	if ( false === get_user_by( 'id', $user_id ) ) {

		wp_send_json_error(
			new WP_Error( '-1', 'No user was found with the specified ID [' . $user_id . ']' )
		);

		$user_exists = false;

	}

	return $user_exists;

}

然后,我们将该文件保存在插件目录根目录中的includes目录中。 includes目录通常是整个项目中使用的代码所在的位置。 关于这个特定的目录可以说更多,但这是更长篇幅的内容。

该类的最终版本应如下所示:

<?php
/**
 * Loads and registers dependencies.
 *
 * @since    1.0.0
 *
 * @package   WPA
 * @author    Tom McFarlin
 * @license   http://www.gnu.org/licenses/gpl-2.0.txt
 * @link      https://tommcfarlin.com/
 */

/**
 * Loads and enqueues dependencies for the plugin.
 *
 * @package    WPA
 * @subpackage WPA/includes
 * @since      1.0.0
 * @author     Tom McFarlin
 * @license    http://www.gnu.org/licenses/gpl-2.0.txt
 * @link       https://tommcfarlin.com/
 */
class Dependency_Loader {

    /**
     * Initializes the plugin by enqueuing the necessary dependencies.
     *
	 * @since    1.0.0
	 */
    public function initialize() {
        $this->enqueue_scripts();
    }

    /**
	 * Enqueues the front-end scripts for getting the current user's information
	 * via Ajax.
	 *
     * @access   private
     * 
	 * @since    1.0.0
	 */
	private function enqueue_scripts() {

		wp_enqueue_script(
			'ajax-script',
			plugin_dir_url( dirname( __FILE__ ) ) . 'assets/js/frontend.js',
			array( 'jquery' )
		);

		wp_localize_script(
			'ajax-script',
			'sa_demo',
			array( 'ajax_url' => admin_url( 'admin-ajax.php' ) )
		);

	}

	/**
	 * Registers the callback functions responsible for providing a response
	 * to Ajax requests setup throughout the rest of the plugin.
	 *
	 * @since    1.0.0
	 */
	public function setup_ajax_handlers() {

		add_action(
			'wp_ajax_get_current_user_info',
			array( $this, 'get_current_user_info' )
		);

		add_action(
			'wp_ajax_nopriv_get_current_user_info',
			array( $this, 'get_current_user_info' )
		);

	}

	/**
	 * Retrieves information about the user who is currently logged into the site.
	 *
	 * This function is intended to be called via the client-side of the public-facing
	 * side of the site.
	 *
	 * @since    1.0.0
	 */
	public function get_current_user_info() {

		$user_id = get_current_user_id();

		if ( $this->user_is_logged_in( $user_id ) && $this->user_exists( $user_id ) ) {

			wp_send_json_success(
				wp_json_encode( get_user_by( 'id', $user_id ) )
			);

		}

	}

	/**
	 * Determines if a user is logged into the site using the specified user ID. If not,
	 * then the following error code and message will be returned to the client:
	 *
	 * -2: The visitor is not currently logged into the site.
	 *
	 * @access   private
	 * @since    1.0.0
	 *
	 * @param    int $user_id         The current user's ID.
	 *
	 * @return   bool $is_logged_in    Whether or not the current user is logged in.
	 */
	private function user_is_logged_in( $user_id ) {

		$is_logged_in = true;

		if ( 0 === $user_id ) {

			wp_send_json_error(
				new WP_Error( '-2', 'The visitor is not currently logged into the site.' )
			);

			$is_logged_in = false;

		}

		return $is_logged_in;

	}

	/**
	 * Determines if a user with the specified ID exists in the WordPress database. If not, then will
	 * the following error code and message will be returned to the client:
	 *
	 * -1: No user was found with the specified ID [ $user_id ].
	 *
	 * @access   private
	 * @since    1.0.0
	 *
	 * @param    int $user_id        The current user's ID.
	 *
	 * @return   bool $user_exists    Whether or not the specified user exists.
	 */
	private function user_exists( $user_id ) {

		$user_exists = true;

		if ( false === get_user_by( 'id', $user_id ) ) {

			wp_send_json_error(
				new WP_Error( '-1', 'No user was found with the specified ID [' . $user_id . ']' )
			);

			$user_exists = false;

		}

		return $user_exists;

	}
}

主班

现在,我们准备为插件编写主类。 这个特定的类将位于plugin目录的根目录中,并且该类的基本结构如下所示:

<?php

/**
 * Loads and enqueues dependencies for the plugin.
 *
 * @since    1.0.0
 *
 * @package  Acme
 */
class Acme_Simple_Ajax {
    
}

接下来,我们将添加几个在实例化该类时要设置的属性:

<?php

class Acme_Simple_Ajax {

	private $version;

	private $loader;

}

之后,我们将创建一个构造函数和一个初始化函数,这些函数将用于使插件运行:

<?php
/**
 * The primary class for the plugin
 *
 * Stores the plugin version, loads and enqueues dependencies
 * for the plugin.
 *
 * @since    1.0.0
 *
 * @package   Acme
 * @author    Tom McFarlin
 * @license   http://www.gnu.org/licenses/gpl-2.0.txt
 * @link      https://tommcfarlin.com/
 */

/**
 * Stores the plugin version, loads and enqueues dependencies
 * for the plugin.
 *
 * @package   Acme
 * @author    Tom McFarlin
 * @license   http://www.gnu.org/licenses/gpl-2.0.txt
 * @link      https://tommcfarlin.com/
 */
class Acme_Simple_Ajax {

    /**
	 * Represents the current version of this plugin.
	 *
	 * @access    private
	 * @since     1.0.0
	 * @var       string
	 */
	private $version;

	/**
	 * A reference to the Dependency Loader.
	 *
	 * @access    private
	 * @since     1.0.0
	 * @var       Dependency_Loader
	 */
	private $loader;

	/**
	 * Initializes the properties of the class.
	 *
	 * @access    private
	 * @since     1.0.0
	 */
	public function __construct() {

		$this->version = '1.0.0';
		$this->loader  = new Dependency_Loader();

	}

	/**
	 * Initializes this plugin and the dependency loader to include
	 * the JavaScript necessary for the plugin to function.
	 *
	 * @access    private
	 * @since     1.0.0
	 */
	public function initialize() {
        
		$this->loader->initialize();
        $this->loader->setup_ajax_handlers();
        
	}
}

在上面的代码中,构造函数设置属性并实例化使插件运动所需的依赖关系。

调用initialize ,插件将启动,并且它将在我们在本教程前面创建的依赖项类上调用initialize方法。

引导程序

我们需要做的最后一件事是获取拥有的主文件,使用PHP的include功能,并确保它知道我们拥有的必要PHP文件。

<?php

/**
 * Loads and registers dependencies.
 */
include_once( 'includes/class-dependency-loader.php' );

/**
 * The primary class for the plugin
 */
include_once( 'class-acme-simple-ajax.php' );

之后,我们需要定义一个方法,该方法将初始化主插件文件并设置所有内容。

<?php

/**
 * Instantiates the main class and initializes the plugin.
 */
function acme_start_plugin() {

    $plugin = new Acme_Simple_Ajax();
	$plugin->initialize();

}

引导程序文件的最终版本应如下所示:

<?php
/**
 * This plugin demonstrates how to use the WordPress Ajax APIs.
 *
 * @package           Acme
 *
 * @wordpress-plugin
 * Plugin Name:       Simple Ajax Demo
 * Description:       A simple demonstration of the WordPress Ajax APIs.
 * Version:           1.0.0
 * Author:            Tom McFarlin
 * Author URI:        https://tommcfarlin.com/
 * License:           GPL-2.0+
 * License URI:       http://www.gnu.org/licenses/gpl-2.0.txt
 */

// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
    die;
}

/**
 * Loads and registers dependencies.
 */
include_once( 'includes/class-dependency-loader.php' );

/**
 * The primary class for the plugin
 */
include_once( 'class-acme-simple-ajax.php' );

/**
 * Instantiates the main class and initializes the plugin.
 */
function acme_start_plugin() {

	$plugin = new Acme_Simple_Ajax();
	$plugin->initialize();

}
acme_start_plugin();

首先,通过检查是否已定义WordPress常量来检查文件是否直接访问。 如果不是,则执行停止。

之后,它包括我们通过本教程创建的各种类。 最后,它定义了一个功能,当WordPress加载该插件时该函数将启动该插件并将所有内容设置为动态。

结论

至此,本系列分为两部分。 希望您不仅学到了将Ajax集成到WordPress项目中的一些最佳实践,而且还学到了有关记录过程性代码和面向对象的代码的知识,以及了解布局多少代码的区别。

在以后的文章中,我可能会回顾这里介绍的一些面向对象的概念,并详细介绍它们。 但是,现在,使用此页面侧边栏上的GitHub链接查看插件。

记住,您可以在我的个人资料页面上捕获我的所有课程和教程,还可以在@tommcfarlin 上的博客和/或Twitter上关注我,在其中我谈论了WordPress上下文中的软件开发。

与往常一样,请不要在下面的提要中留下任何问题或评论,我将尽力回答每个问题或评论。

翻译自: https://code.tutsplus.com/tutorials/improved-ajax-techniques-for-wordpress-object-oriented-programming--cms-24897

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值