Как написать плагин для WordPress

На моей новой работке постоянно приходиться модифицировать WP или выдумывать всякие нестандартные решения. Вот буквально сейчас, текущий проект — это будет каталог специфичных продуктов с возможностью покупки товаров через онлайн-магазин. E-commerce модуль у нас написан отдельно от каталога продуктов, которая в свою очередь храниться в базе WordPress. Главная задача перед программерами — это как связать каждый пост (чт. один конкретный продукт) с модулем e-commerce.

Я им предложил наваять быстренько плагинчик для WP, который хранил бы сгенерированный на лету уникальный код для каждого продукта в связке с ID поста WP. Таким образом, модуль онлайн-шопа сможет выцеплять всю необходимую инфу из поста по коду продукта через ID поста и с другой стороны вести учет продаж в своей базе.

На таком примере, легко показать прелесть WordPress в создании своих плагинов. Плагин получился очень простой.

Теория

Переписывать кодекс WordPress я не буду, тем более, что там на русском все подробно уже написано. Укажу всего-лишь, что нужно внимательно почитать Plugin API и иметь некоторое представление о PHP в целом.

Задача плагина

  • Подцепить ID каждого нового поста при создании оного.
  • Сгенерить уникальный код для «продукта» (поста).
  • Связать ID поста и код продукта.
  • Сохранить код::id_поста в базе данных.

Техническая реализация

Сначала плагин нужно обозвать, указать авторство и прочее. Пишется это по стандартному шаблону:

/*
Plugin Name: Unique Post ID Generator
Plugin URI: http://www.slaff.net/
Description: This plugin generates unique ID of post from post title, category(ies) and date of publish to use in future everywhere.
Version: 1.0
Author: Vyacheslav Bondaruk
Author URI: http://www.slaff.net/
License: GPL2
*/

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

function upidg_install()
{
	# set optios
	$option = get_option('upidg_plugin');

	if (false === $option) {
		# setup options:
		$option = array();
		$option['version'] = "1"; # plugin version
		$option['dbtable_name'] = "upidg"; # db table name
		$option['uninstall'] = false;

		add_option('upidg_plugin', $option);
		# install tables
	  global $wpdb;
	  $table = $wpdb->prefix.$option['dbtable_name'];
	  $structure = "CREATE TABLE IF NOT EXISTS $table (
									id INT(9) NOT NULL AUTO_INCREMENT PRIMARY KEY,
									upidg_code VARCHAR(255) NOT NULL,
									post_id_ref INT(11) NOT NULL,
									date_added DATETIME NOT NULL,
									UNIQUE (upidg_code)
									);";
	  $wpdb->query($structure);
	}
}

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

function upidg_uninstaller() {
	$option = get_option('upidg_plugin');

	global $wpdb;
	$table = $wpdb->prefix.$option['dbtable_name'];
	$wpdb->query("DROP TABLE " . $table);
	# delete plugin options
	delete_option('upidg_plugin');
}

Ну здесь тоже проще простого. Можно конечно и усложнить, но нам это не к чему. Теперь прописыванием хуки (hooks) для активации и деактивации плагина:

register_activation_hook( __FILE__, 'upidg_install'); # activate plugin
register_deactivation_hook( __FILE__, 'upidg_uninstaller'); # deactivate plugin

В листинге выше первый хук вызывает функцию для установки плагина при активации плагина, второй соответственно при отключении плагина. Теперь нам понадобятся одна вспомогательная функция для очистки названия поста по паттерну A-z/0-9.

function clean_title($string)
{
	# Replace other special chars
	$specialCharacters = array(
		"#" => "", "$" => "", "%" => "",
		"&" => "", "@" => "", "." => "",
		"," => "", "+" => "",	"=" => "",
		":" => "", " \ " => "", "/" => "",
		">" => "", "<" => "", "±" => "",
		";" => "", "|" => "",	"{" => "",
		"}" => "", "[" => "", "]" => ""
	);

	while (list($character, $replacement) = each($specialCharacters)) {
		$string = str_replace($character, $replacement, $string);
	}

	# Remove all remaining other unknown characters
	$string = preg_replace('/[^a-zA-Z0-9-]/', ' ', $string);
	$string = preg_replace('/^[-]+/', '', $string);
	$string = preg_replace('/[-]+$/', '', $string);
	$string = preg_replace('/[-]{2,}/', ' ', $string);
	return $string;
}

Ну и теперь добрались до самого главного — основной функции плагина, которая генерит код для продукта (чт. поста), сохраняет его в базе. Нужно еще учитывать также, чтобы не генерился дубликат кода при автосохранении и редактировании поста.

# plugin custom function
function upidg_worker($post_id) {
	global $post, $wpdb;

	$option = get_option('upidg_plugin');

	# access all post data
	$thePostID = $post_id;
	$postdata= get_post($thePostID);

	# get post title, then escape special caracters and remove spaces
	$pTitle = trim($postdata->post_title); # no spaces before and after title
	$pTitle = clean_title($pTitle); # clean from special caracters

	$pComplete = $pTitle;
	$pComplete = str_replace(" ", "", $pComplete); # remove rest of spaces

	# convert to uppercase
	$upidg_code = strtoupper($pComplete);

	$table = $wpdb->prefix.$option['dbtable_name'];	

	# prevent dublicate UPID on edit same post
	if ( isset($_POST['publish']) && isset($_POST['action']) == "editpost" ) {

		# check if upid code already exists in database
		$upidg_check = $wpdb->query("SELECT * FROM $table WHERE upidg_code = '".$upidg_code."' LIMIT 1");

		# get mysql timestep
		$post_time = current_time('mysql');

		# it was a problem. this code is already used
		if ($upidg_check != 0) {
			# we will add current date and time
			$upidg_code = $upidg_code.'_'.date("d").date("B");
		}

		# run sql and insert new reference
		$wpdb->insert($table, array(
				'upidg_code' => $upidg_code,
				'post_id_ref' => $thePostID,
				'date_added' => $post_time
			)
		);

	} // if ( isset ... )
} // upidg_worker
# plugin actions goes here
# action reference http://codex.wordpress.org/Plugin_API/Action_Reference
add_action ('publish_post', 'upidg_worker');

Ну вот и все. Активируем плагин и теперь при каждом новом посте у нас будет уникальный код продукта, сохраненный в специальной таблице. Полностью документированный на русском код плагина можно посмотреть, скачав файлик upid.php

  • Сорри за оффтопик, а какой плагин используется для подсветки синтаксиса кода?

  • а менэ почемута неполучились новичок я в етом.

  • А я вот вообще отказался от WP, ибо шибко он ресурсы жрет...

  • Куски кода — ничего не понятно %)

  • Согласен что не очень то понятно. Вообще в сети мало толкового материала который легко понять.

  • Не понятно!

    При написании инструкции по написанию плагина на будущее советую делать пример такой

    1) Напсиание админки

    — меню

    — подменю

    --поле для текста, чекбокс, радио, картинка, и прочее

    2) как сделать вывод содержимого плагина в нужном месте сайта (самое актуальное, а не про ID)

    3) Как сделать вывод информации одного плагина в другой плагин.

    А у Вас, изивините, получилась заметка для себя... «да бы не забыть».

  • Код в файле хорошо продокументирован, полезного подчерпнул.

    У меня по написанию плагинов есть один вопром, может сможете помочь. Вопрос касается урлов в фронтенд части. К примеру, я хочу, чтобы плагин формировал свои собственные урлы. К примеру, мы подключаем плагин к какой-то странице и уже от неё формировались бы свои урлы, подгружающие тот или иной контент плагина.

    Нечто подобное видел в NextGen Gallery, но чтобы добраться до сути. надо слишком много кода перелопатить, поэтому хотел бы кратко узнать о теории этого вопроса. Заранее большое спасибо

  • Спасибо! Как раз это искал... Все понятно. +1

  • Спасибо статья позновательная, но вроде еще есть такое понятие как шорткоды в вордпресе, вот тут плагин пишут с их использованием

Ваш комментарий

XHTML: вы можете воспользоваться следующими тагами: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>