Только для читателей Lifeexample возможно открыть интернет-магазин на Moguta.CMS со скидкой в 15%

<<< PHP Кодировка страницы || Счетчик скачиваний для WordPress >>>

Пишем плагин WordPress

27.11.2011
Пишем плагин для WordPress

Здравствуй уважаемый читатель блога LifeExample, в этой статье я хочу на примере показать, как самостоятельно можно написать плагин для WordPress. Сразу скажу, что статья большая, разбивать ее на несколько частей я намеренно не стал. Сначала определимся с тем, что такое плагин WordPress, и зачем он нужен. Тебе читатель наверняка известна популярная и бесплатная система управления сайтом WordPress. Так вот разработчики WordPress реализовали гибкую систему плагинов к этой платформе. Другими словами, если что то не хватает в движке WordPress то можно воспользоваться одним из множества плагинов и функция, которой не хватало, будет доступна. Например, хочу я, чтобы у меня на сайте была реализована форма обратной связи, такой функции WordPress по умолчанию не предоставляет, поэтому я скачиваю популярный плагин Contact Form 7, активирую его и получаю готовую форму обратной связи.

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

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

К сожалению далеко не всегда удается найти подходящий плагин в сети интернета, поскольку потребности у каждого разные, но с навыками самостоятельного написания плагинов можно реализовать любую узконаправленную задачу, и сегодня речь пойдет о написании собственного плагина. Плагин который мы сегодня напишем навряд ли полностью подойдёт кому-то по его прямому назначению, но несомненно окажется хорошим пособием для начинающих писателей плагинов для WordPress.
И так писать мы будем плагин реализующий каталог для интернет магазина.

Целью плагина является: импорт содержимого из .csv файла в таблицу базы данных сайта и дальнейший вывод этих данных на одной из страниц.

Для ленивых:

вот готовый плагин ( Скачали: 1075 чел. ) 

.

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

  1. Предоставить администратору сайта возможность выбора .csv файла на локальной машине, прямо из панели администрирования.
  2. Создать таблицу каталога в базе.
  3. Импортировать данные из файла в таблицу.
  4. Предоставить возможность вывода каталога в любом месте сайта.

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

Пишем плагин WordPress собственными руками (Шаг 1)

  1. В директории плагинов …\wp-content\plugins\ создадим каталог и дадим ему имя my_plagin
  2. В созданный каталог добавим файл my_plagin.php, кодировка файла должна быть uft-8 о том как это сделать можно прочесть в статье «PHP Кодировка страницы»

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

1
2
3
4
5
6
7
<?php
/*
   Plugin Name: Каталог для интернет магазина
   Author: Mark Avdeev
   Author URI: www.lifeexample.ru
*/

?>

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

Пишем плагин WordPress собственными руками (Шаг 2)

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

Для того, чтобы после активации плагина, в меню «Параметры», появилась ссылка на меню настроек нашего плагина, мы напишем функцию catalog_admin_menu внутри, которой выполним команду add_options_page, передав необходимые параметры.

1
2
3
function catalog_admin_menu(){
    add_options_page('Каталог', 'Каталог', 8, basename(__FILE__), 'create_catalog');
}

В параметрах команды add_options_page , мы указали, что новый пункт меню «параметры» будет называться «Каталог», и что доступ к настройкам имеют только пользователи с правами администратора, а также то что за вывод и обработку самих настроек будет отвечать функция create_catalog.

Добавим в тело скрипта строку , отвечающую за вывод пункта в меню.

1
add_action('admin_menu', 'catalog_admin_menu');

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

Настройки плагина

Создадим в скрипте нашего плагина функцию create_catalog(). В коде функции будет выполняться вывод формы настроек, создание новой таблицы и обработка csv файла. Сначала я приведу полный код этой функции.<.p>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<?php
function create_catalog() {
global $wpdb;
    if ($_REQUEST['open_file']) {
    //если нажата кнопка "загрузить каталог"
        if ($_FILES['file']['name']!='' && $_FILES['file']['error']==0){ //проверяем загрузился указаный фаил или нет
            $info=pathinfo($_FILES['file']['name']);
            //копируем полученный csv фаил в папку catalog в корне сайта
            if (copy($_FILES['file']['tmp_name'],$_SERVER['DOCUMENT_ROOT'].'/catalog/CatalogPard.'.$info['extension'])){
                // создаем в базе таблицу, если же он есть то пропускаем этот шаг.
            require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
       
               $table_name = $wpdb->prefix."catalog_pard";
                $sql = "DROP TABLE `".$table_name."`";
                $wpdb->query($sql);
                if($wpdb->get_var("SHOW TABLES LIKE $table_name") != $table_name){
                     $sql = "CREATE TABLE IF NOT EXISTS `$table_name` (
                              `id` int(11) NOT NULL AUTO_INCREMENT,
                              `field1` varchar(40) NOT NULL,
                              `field2` varchar(40) NOT NULL,
                              `field3` varchar(40) NOT NULL,
                              `field4` varchar(40) NOT NULL,
                              `field5` varchar(40) NOT NULL,                           
                              PRIMARY KEY (`id`)
                            ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;"
;
               
                      dbDelta($sql);
                     echo '<div id="message" class="updated fade"><p><strong>Каталог обновлен.</strong></p></div>';
                 }
                                       
                $file = file_get_contents($_SERVER['DOCUMENT_ROOT'].'/catalog/CatalogPard.'.$info['extension']);
                    if ($file){
                        $strings = explode("\n",$file); // построчно разбиваем фаил
                            for($i=0; $i<(count($strings)-1); $i++){//из каждой строки вырезаем значения полей
                                    if($found = explode(";",iconv("WINDOWS-1251","UTF-8", $strings[$i]))){
                                        //записываем их в базу
                                        $sql='INSERT INTO `'.$table_name.'` VALUES("","'.$found[0].'","'.$found[1].'","'.$found[2].'","'.$found[3].'","'.$found[4].'");';
                                        dbDelta($sql); 
                                }      
                            }
                   
               
                }
                    else echo "Не найден указаный CSV фаил! <font color='blue'>".$_SERVER['DOCUMENT_ROOT'].'/catalog/CatalogPard.'.$info['extension']."</font>";
               
            }
            else echo "Неудалось передать указаный фаил.";
        }
        else $error="<font color='red'>Фаил не загружен!</font> Возможно вы не указали какой фаил хотите загрузить.";
    }
   
    ?>
    <div class="wrap">
    <h2>Каталог </h2>
    <form method="post" action="" enctype="multipart/form-data">
        <h3>Выполнить загрузку каталога </h3>
        <em>Для обновления каталога, выберите фаил с расширением <font color="blue">.csv</font>, расположенного на вашем компьютере.<em/>
        <br/>
        <br/><input type="file"   name="file" />
        <br/>
        <br/>
        <input type="submit" name="open_file" value="Загрузить каталог" />
        <br/>
        <br/>
        <?=$error?>
   </form> 
    </div>
<?
}
?>

Функция получилась объемная, т.к. на ее плечах лежит выполнение не одного маленького процесса, а сразу трех серьезных. Много говорить тут не о чем, но тем не менее я выделю несколько частей этой функции и объясню что каждая из них делает. Начнем с самой простой части, которая выводит формы настроек:

1
2
3
4
5
6
7
8
9
10
11
<div class="wrap">
    <h2>Каталог </h2>
    <form method="post" action="" enctype="multipart/form-data">
        <h3>Выполнить загрузку каталога </h3>
        <em>Для обновления каталога, выберите фаил с расширением .csv, расположенного на вашем компьютере.<em/>
       
        <br/><input type="file"   name="file" />
        <br/><input type="submit" name="open_file" value="Загрузить каталог" />
        <?=$error?>
   </form> 
</div>

Тут все предельно просто, обычная форма, обычный HTML код, единственное, что нужно отметить это параметр enctype в теге form, он должен иметь значение multipart/form-data, для того чтобы форма могла получить выбранный фаил.
Второй кусочек кода, о котором я хочу сказать служит для удаления старой таблицы плагина из бд и создания новой. Выглядит он следующим образом:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?
$table_name = $wpdb->prefix."catalog_pard";
$sql = "DROP TABLE `".$table_name."`";
$wpdb->query($sql);
if($wpdb->get_var("SHOW TABLES LIKE $table_name") != $table_name){
$sql = "CREATE TABLE IF NOT EXISTS `$table_name` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
`field1` varchar(40) NOT NULL,
`field2` varchar(40) NOT NULL,
 `field3` varchar(40) NOT NULL,
 `field4` varchar(40) NOT NULL,
 `field5` varchar(40) NOT NULL,                        
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;"
;
  dbDelta($sql);
 echo '<div id="message" class="updated fade"><p><strong>Каталог обновлен.</strong></p></div>';
}
?>

Если вы присмотритесь, то увидите, что тут используются не стандартные php команды для работы с бд, о которых я рассказывал в цикле статей по работе с базой даннЫх на PHP, а команды движка WordPress, такие как dbDelta и методы глобального объекта $wpdb для работы с бд. Если почитать руководство от WordPress, то можно найти много полезной информации по работе с бд средствами этого движка. В данном примере используется лишь малая часть заложеного функционала, а именно:

  1. Мы получаем префикс таблиц указаный в файле конфигурации сайта с помощью метда $wpdb->prefix.
  2. Выполняем запрос к базе $wpdb->query(), удаляя старую таблицу плагина.
  3. $wpdb->get_var() получаем имя таблицы из всех имеющихся, для проверки.
  4. Снова выполняем запрос к базе, но уже с использованием функции dbDelta(), созавая новую таблицу каталога с импровизированными полями field1- field5.

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

Пишем плагин WordPress собственными руками (Шаг 3)

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

Так вот shortcode это конструкция вида [name atr1=»1″ atr2=»2″] где name –это обозначение шорткода, а atr1 и atr2 параметры, причем параметров может быть сколько угодно.

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function catalog_print(){
        global $wpdb;
        $table_name = $wpdb->prefix."catalog";
        $sql = "SELECT * FROM ".$table_name;
         
        $result = $wpdb->get_results($sql, ARRAY_A);

        $rrr.="<table><tr>";
         foreach($result[0] as $name=>$value){
            $rrr.="<th>".$name."</th>";
         }
        $rrr.="</tr>";  
         foreach($result as $row){
            $rrr.="<tr>";  
             foreach($row as $name=>$value){
                $rrr.="<td>".$value."</td>";
             }
             $rrr.="</tr>";  
            }
            $rrr.="</table>";
         return $rrr;  
}

add_shortcode('catalog', 'catalog_print');

Теперь создадим страницу средствами движка Worpress и в ее тело вставим конструкцию [catalog] , если вы все сделали правильно, то при просмотре сайта в том месте где вставили [catalog], вы увидите содержимое таблицы каталога из базы данных.

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

Спасибо за внимание, надеюсь статья окажется полезной.

Чтобы не пропустить публикацию следующей статьи подписывайтесь на рассылку по E-mail или RSS ленту блога.

Нравится

Комментарии

  • Максим

    Спасибо, очень интересно!

  • Олег

    Спасибо, для новичка самое оно!

  • Евгений

    Супер!
    Всё заработало с первого раза ))

  • Евгений

    А как в обычной странице грамотно обработать шорткод, когда плагин отключен?
    Т.е. на странице тогда будет показываться просто текст «[catalog]» — а как его НЕ показывать ))

    • Убрать руками с того места где он выводится.

  • марина

    Задача: есть внешняя таблица csv, всего два поля, номер карты и скидка по ней. Из вордпресс надо ее импортировать (раз в неделю замена). Пользователь может на определенной странице узнать значение скидки по своей карте. Пусть это будет не со страницы вордпресс, а просто автономной html. Пусть это будет не импорт в бд вордпресс, а обращение к csv на сервере. Как это лучше реализовать?

  • Андрей Семенов

    В последнем коде в строке 3 (обработчик шорткода) неверно!!!
    $table_name = $wpdb->prefix.»catalog»;
    должно быть $table_name = $wpdb->prefix.»catalog_pard»;
    интересно, как это заработало у Евгения с первого раза и без правки кода.

    А еще у меня неверная кодировка, надо бы добавить строчечку с указанием.

  • Андрей Семенов

    Надо в тексте указать что разделителем в csv нужно брать «;» и кодировочку выбирать вин-1251

  • Valery

    подскажите, как в админке использовать «Менеджер файлов», чтобы реализовать загрузку файлов с бибилиотеки..?

  • Ирина

    Ура, получилось! Огромное спасибо автору, доходчиво, просто и действенно!

  • Алексей

    Добрый день! А можно как-то вместо загрузки из csv? сделать так , что бы на странице плагина была форма с 6 полями, каждый раз когда их заполнят, эти данны попадут в таблицу бд! а вот уже потом выводить такой каталог на странице сайта?

  • Николай

    Доброго дня!

    Подскажите, как можно реализовать вывод в виде виджета?

  • Антон

    Здравствуйте. не подскажете, почему при выводе страницы у меня вместо русского ящыка выводятся знаки вопроса?

  • stari

    при загрузке файла такая ошибка, как исправить подскажите? Warning: copy(…www/catalog/CatalogPard.csv) [function.copy]: failed to open stream: No such file or directory in ……www\wp-content\plugins\catalog\catalog.php on line 21
    Неудалось передать указаный фаил.

  • Оставить комментарий

    Подписаться на комментарии к этой статье по RSS

    Яндекс.Метрика