Advertisement
  1. Code
  2. WordPress

Улучшенные методы Ajax для WordPress: объектно-ориентированное программирование

Scroll to top
Read Time: 13 min

() translation by (you can also view the original English article)

В предыдущем посте в этой серии мы пересматривали тему работы с Ajax в WordPress. В конечном счете, цель состоит в том, чтобы улучшить предыдущую серию, которая была запущена на сайте несколько лет назад.

Повторяю, это не значит, что методы, описанные в оригинальной серии, были ошибочными, но со временем программное обеспечение меняется, поэтому всегда полезно пересмотреть концепции, которые были рассмотрены много лет назад, и попытаться обновить их.

Вспомните предыдущий пост, где мы обратили внимание на следующий комментарий из оригинальной серии:

Мы собираемся сделать очень краткий обзор того, что такое Ajax, как он работает, как настроить его на передней панели и понять, какие ловушки поддерживает WordPress. Мы также создадим небольшой проект, который воплотит эту теорию в жизнь. Мы просмотрим исходный код, и мы также убедимся, что он доступен и на GitHub.

И в этой статье мы рассмотрели некоторые дополнительные способы включения API Ajax для WordPress в наши проекты с использованием процедурного программирования. В этом посте мы собираемся взять код, который мы написали в первой части этой серии, и реорганизовать его так, чтобы он использовал объектно-ориентированный подход.

В конечном счете, цель состоит не в том, чтобы привести пример, когда одна парадигма должна использоваться вместо другой; Вместо этого мы должны показать, как мы можем достичь той же функциональности независимо от подхода, который вы выбираете при создании своих плагинов.

Планирование плагина

Прежде чем мы начнем рефакторинг кода, мы должны рассмотреть, как мы собираемся выкладывать различные файлы. В конце концов, часть процесса создания нового проекта - или даже прыжка в старый - планирование того, как будет все будет работать.

Для этого конкретного плагина нам понадобятся следующие:

  • Файл bootstrap, который отвечает за инициализацию основного класса и запуск плагина
  • Класс, отвечающий за загрузку зависимостей, таких как JavaScript
  • Класс, который является основным классом плагинов

Как вы можете видеть, нам не так уж много нужно делать. Мы также будем реорганизовывать некоторые файлы, чтобы иметь согласованную структуру каталогов, а так же будем обязательно будем документировать весь код так, чтобы он соответствовал стандартам кодирования WordPress.

С учетом всего вышесказанного, давайте начнем.

Организация файлов

Прежде чем мы начнем писать любой код, давайте сделаем следующее:

  1. Создайте каталог assets.
  2. Создайте каталог js, который будет находиться в каталоге assets.
  3. Перенесите frontend.js в каталог js.
The assets directoryThe assets directoryThe assets directory

Причина этого в том, что мы переходим к объектно-ориентированному стилю программирования. Часть этого включает в себя организацию наших файлов, чтобы они следовали соглашениям, которые часто считаются пакетами.

В нашем случае каталог assets включает в себя все необходимое для запуска программы. Для некоторых плагинов это могут быть JavaScript, CSS, изображения, шрифты и т. Д. В этом случае у нас есть один файл JavaScript.

Загрузчик зависимостей

Далее нам нужно ввести класс, который будет отвечать за загрузку зависимостей для нашего проекта. Для этого конкретного плагина единственная зависимость, которая у нас есть, это файл JavaScript, который мы только что разместили в каталоге assets.

Часть объектно-ориентированного программирования гарантирует, что каждый класс имеет конкретную цель. В этом случае класс, который мы собираемся ввести, будет отвечать за загрузку JavaScript с использованием WordPress API.

Начнем с создания базовой структуры класса:

1
<?php
2
    
3
/**

4
 * Loads and enqueues dependencies for the plugin.

5
 *

6
 * @since    1.0.0

7
 *

8
 * @package  WPA/includes

9
 */
10
class Dependency_Loader {
11
  
12
}

Затем мы добавим метод, который будет отвечать за загрузку JavaScript в соответствии с API WordPress.

1
<?php
2
/**

3
 * Loads and registers dependencies.

4
 *

5
 * @since    1.0.0

6
 *

7
 * @package   WPA

8
 * @author    Tom McFarlin

9
 * @license   https://www.gnu.org/licenses/gpl-2.0.txt

10
 * @link      https://tommcfarlin.com/

11
 */
12
13
/**

14
 * Loads and enqueues dependencies for the plugin.

15
 *

16
 * @package    WPA

17
 * @subpackage WPA/includes

18
 * @since      1.0.0

19
 * @author     Tom McFarlin

20
 * @license    http://www.gnu.org/licenses/gpl-2.0.txt

21
 * @link       https://tommcfarlin.com/

22
 */
23
class Dependency_Loader {
24
25
    /**

26
     * Initializes the plugin by enqueuing the necessary dependencies.

27
	 *

28
	 * @since    1.0.0

29
	 */
30
    public function initialize() {
31
        $this->enqueue_scripts();
32
    }
33
34
    /**

35
	 * Enqueues the front-end scripts for getting the current user's information

36
	 * via Ajax.

37
	 *

38
     * @access   private

39
     * 

40
	 * @since    1.0.0

41
	 */
42
	private function enqueue_scripts() {
43
44
		wp_enqueue_script(
45
			'ajax-script',
46
			plugin_dir_url( dirname( __FILE__ ) ) . 'assets/js/frontend.js',
47
			array( 'jquery' )
48
		);
49
50
		wp_localize_script(
51
			'ajax-script',
52
			'sa_demo',
53
			array( 'ajax_url' => admin_url( 'admin-ajax.php' ) )
54
		);
55
56
	}
57
}

После этого нам нужно взять функции, отвечающие за обработку Ajax-запросов и предоставление ответов, а затем добавить их в класс. Так как они будут в контексте класса, нам нужно добавить новую функцию, которая зарегистрирует их в WordPress.

Мы создадим функцию setup_ajax_handlers. Это выглядит так:

1
<?php
2
3
/**
4
 * Registers the callback functions responsible for providing a response
5
 * to Ajax requests setup throughout the rest of the plugin.
6
 *
7
 * @since    1.0.0
8
 */
9
public function setup_ajax_handlers() {
10
11
    add_action(
12
		'wp_ajax_get_current_user_info',
13
		array( $this, 'get_current_user_info' )
14
	);
15
16
	add_action(
17
		'wp_ajax_nopriv_get_current_user_info',
18
		array( $this, 'get_current_user_info' )
19
	);
20
21
}

Затем нам нужно фактически переместить функции в этот класс. Обратите внимание, что функции, которые были изначально с префиксом _sa, больше не помечены как таковые. Поскольку они находятся в контексте класса, мы можем отбросить префикс, а также отбросить знак подчеркивания в пользу ключевого слова private.

1
<?php
2
3
public function get_current_user_info() {
4
5
    $user_id = get_current_user_id();
6
7
	if ( $this->user_is_logged_in( $user_id ) && $this->user_exists( $user_id ) ) {
8
9
		wp_send_json_success(
10
			wp_json_encode( get_user_by( 'id', $user_id ) )
11
		);
12
13
	}
14
15
}
16
17
private function user_is_logged_in( $user_id ) {
18
19
	$is_logged_in = true;
20
21
	if ( 0 === $user_id ) {
22
23
		wp_send_json_error(
24
			new WP_Error( '-2', 'The visitor is not currently logged into the site.' )
25
		);
26
27
		$is_logged_in = false;
28
29
	}
30
31
	return $is_logged_in;
32
33
}
34
35
private function user_exists( $user_id ) {
36
37
	$user_exists = true;
38
39
	if ( false === get_user_by( 'id', $user_id ) ) {
40
41
		wp_send_json_error(
42
			new WP_Error( '-1', 'No user was found with the specified ID [' . $user_id . ']' )
43
		);
44
45
		$user_exists = false;
46
47
	}
48
49
	return $user_exists;
50
51
}

Затем мы сохраним этот файл в каталоге include в корневом каталоге плагина. Каталог includes включает код, который используется во всем проекте. Можно еще подробнее  рассказать об этом конкретном каталоге, но это контент для более длинной статьи.

Окончательная версия этого класса должна выглядеть так:

1
<?php
2
/**

3
 * Loads and registers dependencies.

4
 *

5
 * @since    1.0.0

6
 *

7
 * @package   WPA

8
 * @author    Tom McFarlin

9
 * @license   http://www.gnu.org/licenses/gpl-2.0.txt

10
 * @link      https://tommcfarlin.com/

11
 */
12
13
/**

14
 * Loads and enqueues dependencies for the plugin.

15
 *

16
 * @package    WPA

17
 * @subpackage WPA/includes

18
 * @since      1.0.0

19
 * @author     Tom McFarlin

20
 * @license    http://www.gnu.org/licenses/gpl-2.0.txt

21
 * @link       https://tommcfarlin.com/

22
 */
23
class Dependency_Loader {
24
25
    /**

26
     * Initializes the plugin by enqueuing the necessary dependencies.

27
     *

28
	 * @since    1.0.0

29
	 */
30
    public function initialize() {
31
        $this->enqueue_scripts();
32
    }
33
34
    /**

35
	 * Enqueues the front-end scripts for getting the current user's information

36
	 * via Ajax.

37
	 *

38
     * @access   private

39
     * 

40
	 * @since    1.0.0

41
	 */
42
	private function enqueue_scripts() {
43
44
		wp_enqueue_script(
45
			'ajax-script',
46
			plugin_dir_url( dirname( __FILE__ ) ) . 'assets/js/frontend.js',
47
			array( 'jquery' )
48
		);
49
50
		wp_localize_script(
51
			'ajax-script',
52
			'sa_demo',
53
			array( 'ajax_url' => admin_url( 'admin-ajax.php' ) )
54
		);
55
56
	}
57
58
	/**

59
	 * Registers the callback functions responsible for providing a response

60
	 * to Ajax requests setup throughout the rest of the plugin.

61
	 *

62
	 * @since    1.0.0

63
	 */
64
	public function setup_ajax_handlers() {
65
66
		add_action(
67
			'wp_ajax_get_current_user_info',
68
			array( $this, 'get_current_user_info' )
69
		);
70
71
		add_action(
72
			'wp_ajax_nopriv_get_current_user_info',
73
			array( $this, 'get_current_user_info' )
74
		);
75
76
	}
77
78
	/**

79
	 * Retrieves information about the user who is currently logged into the site.

80
	 *

81
	 * This function is intended to be called via the client-side of the public-facing

82
	 * side of the site.

83
	 *

84
	 * @since    1.0.0

85
	 */
86
	public function get_current_user_info() {
87
88
		$user_id = get_current_user_id();
89
90
		if ( $this->user_is_logged_in( $user_id ) && $this->user_exists( $user_id ) ) {
91
92
			wp_send_json_success(
93
				wp_json_encode( get_user_by( 'id', $user_id ) )
94
			);
95
96
		}
97
98
	}
99
100
	/**

101
	 * Determines if a user is logged into the site using the specified user ID. If not,

102
	 * then the following error code and message will be returned to the client:

103
	 *

104
	 * -2: The visitor is not currently logged into the site.

105
	 *

106
	 * @access   private

107
	 * @since    1.0.0

108
	 *

109
	 * @param    int $user_id         The current user's ID.

110
	 *

111
	 * @return   bool $is_logged_in    Whether or not the current user is logged in.

112
	 */
113
	private function user_is_logged_in( $user_id ) {
114
115
		$is_logged_in = true;
116
117
		if ( 0 === $user_id ) {
118
119
			wp_send_json_error(
120
				new WP_Error( '-2', 'The visitor is not currently logged into the site.' )
121
			);
122
123
			$is_logged_in = false;
124
125
		}
126
127
		return $is_logged_in;
128
129
	}
130
131
	/**

132
	 * Determines if a user with the specified ID exists in the WordPress database. If not, then will

133
	 * the following error code and message will be returned to the client:

134
	 *

135
	 * -1: No user was found with the specified ID [ $user_id ].

136
	 *

137
	 * @access   private

138
	 * @since    1.0.0

139
	 *

140
	 * @param    int $user_id        The current user's ID.

141
	 *

142
	 * @return   bool $user_exists    Whether or not the specified user exists.

143
	 */
144
	private function user_exists( $user_id ) {
145
146
		$user_exists = true;
147
148
		if ( false === get_user_by( 'id', $user_id ) ) {
149
150
			wp_send_json_error(
151
				new WP_Error( '-1', 'No user was found with the specified ID [' . $user_id . ']' )
152
			);
153
154
			$user_exists = false;
155
156
		}
157
158
		return $user_exists;
159
160
	}
161
}

Основной класс

Теперь мы готовы написать основной класс для плагина. Этот конкретный класс будет находиться в корне каталога плагинов, а базовая структура класса будет выглядеть так:

1
<?php
2
3
/**

4
 * Loads and enqueues dependencies for the plugin.

5
 *

6
 * @since    1.0.0

7
 *

8
 * @package  WPA

9
 */
10
class WP_Simple_Ajax {
11
    
12
}

Затем мы добавим пару свойств, которые мы установим, когда класс будет создан:

1
<?php
2
3
class WP_Simple_Ajax {
4
5
	private $version;
6
7
	private $loader;
8
9
}

После этого мы создадим конструктор и функцию инициализации, которые будут использоваться для установки плагина:

1
<?php
2
/**

3
 * The primary class for the plugin

4
 *

5
 * Stores the plugin version, loads and enqueues dependencies

6
 * for the plugin.

7
 *

8
 * @since    1.0.0

9
 *

10
 * @package   WPA

11
 * @author    Tom McFarlin

12
 * @license   http://www.gnu.org/licenses/gpl-2.0.txt

13
 * @link      https://tommcfarlin.com/

14
 */
15
16
/**

17
 * Stores the plugin version, loads and enqueues dependencies

18
 * for the plugin.

19
 *

20
 * @package   WPA

21
 * @author    Tom McFarlin

22
 * @license   http://www.gnu.org/licenses/gpl-2.0.txt

23
 * @link      https://tommcfarlin.com/

24
 */
25
class WP_Simple_Ajax {
26
27
    /**

28
	 * Represents the current version of this plugin.

29
	 *

30
	 * @access    private

31
	 * @since     1.0.0

32
	 * @var       string

33
	 */
34
	private $version;
35
36
	/**

37
	 * A reference to the Dependency Loader.

38
	 *

39
	 * @access    private

40
	 * @since     1.0.0

41
	 * @var       Dependency_Loader

42
	 */
43
	private $loader;
44
45
	/**

46
	 * Initializes the properties of the class.

47
	 *

48
	 * @access    private

49
	 * @since     1.0.0

50
	 */
51
	public function __construct() {
52
53
		$this->version = '1.0.0';
54
		$this->loader  = new Dependency_Loader();
55
56
	}
57
58
	/**

59
	 * Initializes this plugin and the dependency loader to include

60
	 * the JavaScript necessary for the plugin to function.

61
	 *

62
	 * @access    private

63
	 * @since     1.0.0

64
	 */
65
	public function initialize() {
66
        
67
		$this->loader->initialize();
68
        $this->loader->setup_ajax_handlers();
69
        
70
	}
71
}

В приведенном выше коде конструктор задает свойства и создает зависимости, необходимые для приведения плагина в движение.

Когда вызывается initialize, плагин запускается и вызывает метод initialize для класса зависимостей, который мы создали ранее в этом уроке.

Bootstrap

Последнее, что нам нужно сделать, - это взять основной файл, который у нас есть, использовать функцию PHP include и убедиться, что он знает о необходимых PHP-файлах, которые у нас есть.

1
<?php
2
3
/**

4
 * Loads and registers dependencies.

5
 */
6
include_once( 'includes/class-dependency-loader.php' );
7
8
/**

9
 * The primary class for the plugin

10
 */
11
include_once( 'class-wp-simple-ajax.php' );

После этого нам нужно определить метод, который инициализирует основной файл плагина и приводит все в действие.

1
<?php
2
3
/**

4
 * Instantiates the main class and initializes the plugin.

5
 */
6
function wpa_start_plugin() {
7
8
    $plugin = new WP_Simple_Ajax();
9
	$plugin->initialize();
10
11
}

Окончательная версия загрузочного файла должна выглядеть так:

1
<?php
2
/**

3
 * This plugin demonstrates how to use the WordPress Ajax APIs.

4
 *

5
 * @package           WPA

6
 *

7
 * @wordpress-plugin

8
 * Plugin Name:       Simple Ajax Demo

9
 * Description:       A simple demonstration of the WordPress Ajax APIs.

10
 * Version:           1.0.0

11
 * Author:            Tom McFarlin

12
 * Author URI:        https://tommcfarlin.com/

13
 * License:           GPL-2.0+

14
 * License URI:       http://www.gnu.org/licenses/gpl-2.0.txt

15
 */
16
17
// If this file is called directly, abort.

18
if ( ! defined( 'WPINC' ) ) {
19
    die;
20
}
21
22
/**

23
 * Loads and registers dependencies.

24
 */
25
include_once( 'includes/class-dependency-loader.php' );
26
27
/**

28
 * The primary class for the plugin

29
 */
30
include_once( 'class-wp-simple-ajax.php' );
31
32
/**

33
 * Instantiates the main class and initializes the plugin.

34
 */
35
function wpa_start_plugin() {
36
37
	$plugin = new WP_Simple_Ajax();
38
	$plugin->initialize();
39
40
}
41
wpa_start_plugin();

Во-первых, файл проверяет, можно ли получить доступ к нему напрямую, проверив, была ли определена константа WordPress. Если нет, то выполнение останавливается.

После этого он включает в себя различные классы, которые мы создали в этом уроке. Наконец, он определяет функцию, которая вызывается, когда WordPress загружает плагин, который запускает плагин и запускает все в движение.

Заключение

И вот мы подошли к концу этой серии из двух частей. Надеемся, вы узнали не только о некоторых лучших методах включения Ajax в ваши проекты WordPress, но также немного о документировании как процедурного, так и объектно-ориентированного кода, а также о различиях в них.

В будущем посте я могу вернуться к некоторым объектно-ориентированным концепциям, которые были введены здесь, и более подробно их описывать. А пока взглянем на плагин, используя ссылку GitHub на боковой панели этой страницы.

Помните, что вы можете отслеживать все мои курсы и учебные материалы на моей странице в профиле, и вы можете следить за мной в моем блоге и/или Twitter в @tommcfarlin, где я рассказываю о разработке программного обеспечения в контексте WordPress.

Как обычно, пожалуйста, не стесняйтесь оставлять любые вопросы или комментарии в ленте ниже, и я постараюсь ответить на каждый из них.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.