Статьи

Основы построения панели управления WordPress-сервером

Конечный продукт
Что вы будете создавать

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

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

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

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

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

Поскольку виджеты очень гибкие и доступны прямо на первом экране администратора, мы можем использовать их для отображения ресурсов сервера: состояния диска, использования ОЗУ, использования ЦП и информации об операционной системе. Мы будем называть эти ресурсы «метрики» для краткости.

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

Для этого мы также изучим некоторые основные команды Linux, чтобы получить информацию о сервере и заполнить нашу панель управления виджетами. Мы будем использовать API-интерфейсы для кеширования этих данных. Cronjobs будет использовать для автоматического извлечения этих данных, а не получать их по требованию при каждом запросе

Работа нашего плагина вдохновлена Linux Dash .

Наш плагин поддерживает девять видов метрик. В результате у нас будет девять виджетов панели инструментов.

  1. Информация о сервере: операционная система, ядро ​​Linux, время работы и т. Д.
  2. Загрузка процессора: средняя загрузка процессора за 1, 5 и 15 минут
  3. Использование ОЗУ физической ОЗУ и файла подкачки
  4. Использование диска
  5. Установленное программное обеспечение
  6. Процессы
  7. Ethernet
  8. Производительность сети
  9. IO stat
  1. Окружение Linux. Mac OS X по-прежнему является опцией, но некоторые команды для проверки вышеуказанных показателей недоступны, поэтому, если вы получите сообщение об ошибке «команда не найдена», то вы знаете, что Mac не поддерживает эту команду.
  2. Основное понимание оболочки
  3. Базовое понимание плагина WordPress.

Давайте создадим простой плагин и назовем его « Панель управления сервером» . Начнем с некоторых основных вещей. Традиционный Hello World поможет вам попробовать добавить виджет на панель инструментов.

На самом деле это легко.

Создайте папку вызова панели инструментов сервера внутри wp-content/plugins и файла serverdashboard.php . Расположение папок выглядит следующим образом. Просто сфокусируйтесь на основном файле и игнорируйте корзину, тесты, виджеты и так далее.

Используйте этот код для serverdashboard.php

01
02
03
04
05
06
07
08
09
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
<?php
/*
Plugin Name: Server Dashboard
Version: 0.1-alpha
Description: Server Status Dashboard
Author: Vinh
Author URI: http://axcoto.com
Plugin URI: http://axcoto.com
Text Domain: Server Dashboard
Domain Path: /languages
 */
namespace AX\StatBoard;
require_once plugin_dir_path( __FILE__ ) .
 
class Dashboard {
  protected static $_instance=NULL;
 
  function __construct() {
  }
 
  /**
   * Create an unique instance throught the app
   */
  public static function instance() {
    return self::$_instance = self::$_instance ?: new self();
  }
 
  /**
   * Start to setup hook
   */
  public function run() {
    add_action( ‘wp_dashboard_setup’, array( $this, ‘add_dashboard_widgets’ ) );
  }
 
  function remove_dashboard_widgets() {
 
  }
 
  function add_dashboard_widgets() {
    syslog(LOG_DEBUG, «Run»);
 
    wp_add_dashboard_widget(
        ‘hello_world_dashboard_widget’, // A Slug to identify this widget
                 ‘Hello World’, //Widget title
                 function () {
                   echo ‘Hey, I\’m the body of widget.
                 } //function to render content of widget, I’m using a closure here
      );
 
    }
  
}
 
Dashboard::instance()->run();
?><br><br>

Я использовал пространство имен AX\StatBoard чтобы избежать конфликта имен с различными классами плагинов, именами функций тем и другими плагинами.

Я также использовал шаблон Singleton для получения уникального экземпляра класса плагина. Я создал метод run для регистрации хуков или фильтров в WordPress.

Чтобы добавить виджет, мы должны подключиться к действию wp_dashboard_setup . Эти хуки дают нам доступ к опции настройки, связанной с Dashboard. Это позволяет нам добавлять или удалять виджет панели мониторинга из WordPress.

Внутри функции hook мы используем wp_add_dashboard_widget для регистрации виджета. Требуются аргументы в следующем порядке:

  1. Идентификатор виджета используется для идентификации слаг для вашего виджета. Этот слаг используется при рендеринге идентификатора CSS, класса и ключей в массиве виджетов.
  2. Заголовок виджета отображается в заголовке окна виджета
  3. Обратный вызов для отображения содержимого виджета. Он должен выводить контент напрямую, возвращать не нужно.

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

Обновите вашу панель. Наш плагин показывает свой виджет. Обратите внимание на id элемента div виджета.


Наш плагин виджет отображается с его идентификатором и содержанием

Давайте продвинем это. Мы покажем круговую диаграмму с некоторыми фиктивными данными. Для простоты я буду использовать Google Chart API. Позже мы будем широко использовать его для метрик сервера, поскольку лучше визуализировать данные такого типа.

Если вам не нравится Google Chart, вы можете избавиться от него и добавить свою любимую библиотеку диаграмм. Помните, что это учебное пособие, поэтому не ограничивайте себя — используйте все, что вам удобно!

Нам нужно загрузить скрипт Google Chart. Измените метод run() чтобы зарегистрировать еще один хук.

1
2
3
4
public function run() {
   add_action( ‘wp_dashboard_setup’, array( $this, ‘add_dashboard_widgets’ ) );
   add_action( ‘admin_enqueue_scripts’, array($this, ‘add_asset’));
 }

admin_enqueue_scripts — это действие, которое вам нужно подключить для добавления собственного скрипта в панель администратора. Мы добавим еще один вызов метода add_asset в наш класс для обработки загрузки скрипта. Реализация add_asset .

1
2
3
4
5
6
/**
  * Add javascript
  */
 function add_asset() {
   wp_enqueue_script( ‘google-chart’, ‘https://www.google.com/jsapi’ );
 }

У нас есть библиотека графиков. Теперь мы должны сделать это внутри нашей панели. Вы можете поиграть с Google Chart . Мы просто будем использовать их пример сейчас.

01
02
03
04
05
06
07
08
09
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
function add_dashboard_widgets() {
    syslog(LOG_DEBUG, «Run»);
 
    wp_add_dashboard_widget(
        ‘hello_world_dashboard_widget’, // A Slug to identify this widget
                 ‘Hello World’, //Widget title
                 function () {
                   echo <<<‘EOD’
Hey, I’m the body of widget.
      <div id=»hello_piechart»>
      </div>
      <script type=»text/javascript»>
      google.load(«visualization», «1», {packages:[«corechart»]});
      google.setOnLoadCallback(drawChart);
      function drawChart() {
        var data = google.visualization.arrayToDataTable([
          [‘Task’, ‘Hours per Day’],
          [‘Work’, 11],
          [‘Eat’, 2],
          [‘Commute’, 2],
          [‘Watch TV’, 2],
          [‘Sleep’, 7]
        ]);
 
        var options = {
          title: ‘Sample Pie Chart’,
          is3D: true,
        };
 
        var chart = new google.visualization.PieChart(document.getElementById(‘hello_piechart’));
        chart.draw(data, options);
      }
    </script>
EOD;
                  } //function to render content of widget, I’m using a closure here
      );
<br><br>

Мы просто добавляем еще один элемент div с идентификатором hello_piechart и отображаем диаграмму в этом элементе. Давайте посмотрим, что мы получили сейчас:

Обратите внимание на идентификатор элемента виджета.

Теперь, когда мы знаем, как добавить наш собственный блок виджетов на панель инструментов, и теперь, когда мы знаем, как заставить Google Chart отображать информацию, мы можем объединить их, чтобы показать больше информации.

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

При получении метрик сервера мы будем использовать команду Linux для получения этой информации. В PHP мы можем использовать backtick « или shell_exec для вызова команды оболочки и получения выходных данных.

Мы можем проанализировать вывод, чтобы получить данные сервера. Например, для получения статуса использования диска мы можем использовать команду df -h . Мы знаем формат вывода, поэтому мы можем проанализировать его, чтобы получить то, что мы хотим.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
$df = `df -h`;
   $df = explode(«\n», $df);
   if (is_array($df) && count($df)>=2) {
     array_shift($df);
     $df = array_map(function ($line) {
       if (empty($line)) {
         return NULL;
       }
       $segment=preg_split(‘/\s+/’, $line);
        
       return array(
         ‘filesystem’ => $segment[0],
         ‘size’ => $segment[1],
         ‘used’ => $segment[2],
         ‘available’ => $segment[3],
         ‘use_percent’ => $segment[4],
       );
     }, $df);
     var_dump($df);
   }

Чтобы помочь очистить вывод прямо из команды оболочки, мы можем объединить с awk . Эта ссылка выглядит страшно с большим количеством информации, но мы просто будем использовать ее очень мало в этом уроке. Объяснение awk выходит за рамки данного руководства.

Если вы хотите узнать больше о awk, используйте эту таблицу . По сути, мы используем awk для обработки каждой строки вывода, и в каждой строке строка будет разделена на табуляцию или пробел, и к элементу можно будет обращаться как к переменной с $ 1 для первого элемента, $ 2 для второго элемента и так далее. Синтаксис: [command_we_run] | awk ' { print $1, $3, ...}' [command_we_run] | awk ' { print $1, $3, ...}' .
Давайте посмотрим на следующий пример:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
☁ Server Dashboard [master] ls -lh
total 32
-rw-r—r— 1 kureikain staff 2.6K Apr 11 00:46 Server Dashboard.php
drwxr-xr-x 3 kureikain staff 102B Mar 29 01:27 bin
-rw-r—r— 1 kureikain staff 98B Apr 5 18:53 loader.js
-rw-r—r— 1 kureikain staff 321B Mar 29 01:27 phpunit.xml
drwxr-xr-x 4 kureikain staff 136B Mar 29 01:27 tests
drwxr-xr-x 12 kureikain staff 408B Apr 13 17:37 widget
-rw-r—r— 1 kureikain staff 1.1K Apr 6 01:04 widget.php
☁ Server Dashboard [master] ls -lh |
 
kureikain staff 2.6K Server
kureikain staff 102B bin
kureikain staff 98B loader.js
kureikain staff 321B phpunit.xml
kureikain staff 136B tests
kureikain staff 408B widget
kureikain staff 1.1K widget.php<br><br>

Как видите, каждая строка ls -la содержит девять полей:

1
drwxr-xr-x 4 kureikain staff 136B Mar 29 01:27 tests

Разделив пробелами, эти 9 полей:

  1. drwxr-хт-х
  2. 4
  3. kureikain
  4. штат сотрудников
  5. 136В
  6. март
  7. 29
  8. 1:27
  9. тесты

Я могу использовать awk, чтобы просто взять имя, группу, размер и имя файла / папки в соответствующем поле 3, 4, 5, 9 awk ' {print $3, $4, $5, $9} ' и я увижу:

1
kureikain staff 136B tests<br>

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

Некоторые команды выводят дополнительные данные, которые нам не нужны; следовательно, с PHP требуется немного дополнительных усилий для его очистки.

Например:

1
2
3
4
5
[vagrant@vagrant-centos64 ~]$ free -m
             total used free shared buffers cached
Mem: 589 537 51 0 8 271
-/+ buffers/cache: 258 330
Swap: 255 0 255

free -m показывает использование ОЗУ с памятью и файлом подкачки; однако он включает две другие строки с общим / используемым / свободным и — / + буферами / кешем, которые нам могут не понадобиться.

Мы хотим получить только информацию о Mem и Swap, то есть строку 3 и строку 5. Один из способов добиться этого — использовать grep с ключом -E . Этот переключатель позволяет использовать регулярный экспресс для поиска. Поскольку мы хотим найти строку со словами Mem и Swap, давайте объединимся с grep -E "Mem|Swap" .
Вот результат.

1
2
3
[vagrant@vagrant-centos64 ~]$ free -m |
Mem: 589 536 52 0 8 271
Swap: 255 0 255

Так что это намного чище. Сочетая grep и awk мы можем очистить данные и получить только то, что нам нужно.

1
2
3
[vagrant@vagrant-centos64 ~]$ free -m |
Mem: 589 537 52
Swap: 255 0 255

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

1
2
3
4
5
6
7
8
9
$netstat -in
 
Kernel Interface table
Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg
eth0 1500 0 5538339494 0 0 0 6216082004 0 0 0 BMRU
eth0:1 1500 0 — no statistics available — BMRU
eth1 1500 0 96707328840 0 0 0 102776317608 0 0 0 BMRU
eth2 1500 0 33 0 0 0 7 0 0 0 BMRU
lo 16436 0 29461422 0 0 0 29461422 0 0 0 LRU
01
02
03
04
05
06
07
08
09
10
df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda7 2.0G 660M 1.3G 35% /
/dev/sda8 1.0T 632G 340G 66% /home
/dev/sda6 2.0G 68M 1.9G 4% /tmp
/dev/sda5 20G 1.5G 18G 8% /var
/dev/sda2 20G 2.1G 17G 12% /usr
/dev/sda1 194M 25M 160M 14% /boot
/dev/hdb1 459G 277G 159G 64% /backup
tmpfs 16G 0 16G 0% /dev/shm
1
2
3
4
5
free -m
             total used free shared buffers cached
Mem: 32189 32129 59 0 419 9052
-/+ buffers/cache: 22656 9532
Swap: 32767 4 3276

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

Мы немного реорганизовали наш оригинальный класс в предыдущем разделе. Обратите внимание, что, если не указано иное, мы будем создавать все файлы и папки в каталоге нашего плагина.

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

Мы будем использовать пространства имен в качестве пути и имя класса в качестве имени файла. Например, класс foo в пространстве имен AX\StatBoard должен находиться в корне папки плагина. AX\StatBoard\Bar класса в пространстве имен AX\StatBoard\Bar должно быть в Bar\buzz.php

Структура макета папки с пространством имен, именем класса и именем файла для автоматической загрузки.

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
<?php
namespace AX\StatBoard;
 
class Dashboard {
  //..
  public function load_class($classname)
  {
    if (FALSE === $pos = strpos($classname, ‘AX\StatBoard’)) {
      return false;
    }
    $classname = substr($classname, $pos+1 + strlen(‘AX\StatBoard’));
    $filepath = $this->_plugin_dir .
    if (!file_exists($filepath)) {
      return false;
    }
    include $filepath;
  } <br><br> /**<br> * Setup variable and intialize widget provider<br> */<br> function __construct() {<br> $this->_plugin_dir = plugin_dir_path( __FILE__ ) ;<br> spl_autoload_register(array($this, ‘load_class’));<br> }<br><br>
  //..
}

Итак, что здесь происходит? Наш плагин использует пространство имен AX\StatBoard . Таким образом, мы гарантируем, что запрошенный класс в этом пространстве имен должен обрабатываться нашим плагином, иначе наш автозагрузчик не сможет их загрузить. Затем мы убираем AX \ StatBoard в имени класса и заменяем его на путь к папке плагина. Пространство имен обратной косой черты \ in заменяется разделителем / path и добавляет расширение php . Это означает, что пространство имен будет использоваться в качестве пути к папке, содержащей файл класса, а имя класса — это имя файла. Включение происходит только в том случае, если файл существует. Теперь у нас есть автозагрузчик, нам все еще нужно сообщить PHP, что у нас есть автозагрузчик, и мы хотим его использовать. PHP включает в себя spl_autoload_register для этой цели. Мы помещаем это в наш конструктор класса.

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

Предполагая, что вы знаете о функции wp_add_dashboard_widget , мы должны дать ей заголовок и содержимое. В соответствии с каждым виджетом у нас будет класс для отображения заголовка и содержимого для него. Мы называем эти классы виджетом Provider . Все поставщики виджетов должны определять get_title() и get_content() для отображения содержимого.
Для этого мы создадим интерфейс Provider , и наш класс провайдера виджетов реализует этот интерфейс. Нам также нужно создать еще один вызов метода get_metric() для извлечения данных сервера.

Создайте файл widget/provider.php с таким содержимым:

1
2
3
4
5
6
7
8
9
<?php
namespace AX\StatBoard\Widget;
 
interface Provider {
   
  function get_title();
  function get_content();
  function get_metric();
}

Это интерфейс. Мы требовали, чтобы каждый поставщик виджетов реализовывал этот интерфейс, и поэтому мы гарантируем, что класс поставщика виджетов tat всегда имеет эти три метода.

Мы создадим еще один класс Widget для управления этими провайдерами. Мы создаем классы провайдеров, затем передаем их классу Widget и рассматриваем класс Widget как единую точку, которую мы можем запрашивать у поставщика, когда нам это нужно. Мы можем просто поместить все в наш основной файл плагина и просто создать экземпляр класса с new оператором, когда нам это нужно, но потом это сложно поддерживать.

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

widget.php файл widget.php в корневом каталоге папки плагина.

1
<br><?php<br>namespace AX\StatBoard;<br>use AX\StatBoard\Widget\Provider;<br><br>class Widget {<br> const WIDGET_SLUG_PREFIX = ‘AX’;<br><br> protected $_providers = array();<br> protected static $_instance;<br><br> static function instance() {<br> return self::$_instance = self::$_instance ?: new self();<br> }<br><br> function __construct() {<br> }<br><br> /**<br> * Add a widget provider<br> * @param string widget name<br> * @param provider object to handle widget content rendering<br> */ <br> public function add_provider($name, Provider $handler) {<br> $this->_providers[$name] = $handler;<br> return $this;<br> }<br><br> /**<br> * Get all provider or a particular provider<br> */<br> public function get_provider($name=NULL) {<br> if (!$name) {<br> return $this->_providers;<br> }<br> return $this->_providers[$name];<br> }<br><br> /**<br> * Register a widget to render it.<br> */<br> public function register($name) {<br> $slugid = self::WIDGET_SLUG_PREFIX .

Опять же, мы используем шаблон Singleton для нашего класса Widget. Краткое описание нашего метода здесь.

  1. Метод add_provider добавит объект поставщика виджетов в список поставщиков виджетов. Мы также используем подсказки типов, чтобы гарантировать, что передача объекта в add_provider должна быть Провайдером , реализуя наш интерфейс Provider .
  2. Метод get_provider может вернуть список всех провайдеров или конкретного провайдера.
  3. Метод register фактически зарегистрирует наш провайдерский объект в WordPress для визуализации виджета панели мониторинга с помощью wp_add_dashboard_widget . Идентификатор виджета генерируется на основе префикса, предварительно определенной константы и имени класса виджета. Заголовок и контент будут извлекаться через get_title and get_content провайдера. Мы убедились, что они реализуют наш интерфейс провайдера. С помощью этого метода регистра мы абстрагируем реализацию добавления виджета на панель инструментов. Все, что нам нужно сделать сейчас, это вызвать register с именем провайдера, который мы добавили ранее с помощью add_provider . Имея это в виду, когда WordPress API меняется, нам не нужно заходить в каждое место wp_add_dashboard_widget , мы просто обновляем в одном месте.

Возвращаясь к нашему исходному файлу основного плагина serverdashboard.php , мы инициализируем всех провайдеров и добавляем их в список провайдеров объекта Widget.

01
02
03
04
05
06
07
08
09
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
<?php
  
 /**
  * Setup variable and intialize widget provider
  */
 function __construct() {
   $this->_plugin_dir = plugin_dir_path( __FILE__ ) ;
   spl_autoload_register(array($this, ‘load_class’));
 
   $this->_dashboard_widget = array(
     ‘server’,
     ‘cpu_load’,
 
     ‘ram’,
      
     ‘disk’,
     ‘diskio’,
 
     ‘software’,
     ‘ethernet’,
      
     ‘internetspeed’,
     ‘networkio’,
     ‘process’,
   );
 
   foreach ($this->_dashboard_widget as $item) {
     if (!file_exists($this->_plugin_dir . ‘/widget/’ . $item . ‘.php’)) {
       continue;
     }
     $classname = ‘AX\\StatBoard\\Widget\\’ .
     Widget::instance()->add_provider($item, new $classname());
   }
 }<br><br>

Мы поместим все классы провайдера виджетов в пространство имен AX\StatBoard\Widget и поэтому они будут находиться внутри widget папки . Мы поддерживаем девять видов метрик и _dashboard_widgets класс, соответствующий массиву _dashboard_widgets выше.

Для каждого виджета мы создаем новый экземпляр его провайдера и добавляем в класс Widget . Вот что мы получим позже с этой структурой:

Помните, что мы подключились к wp_dashboard_setup , и внутри него мы вызываем функцию wp_add_dashboard_widget чтобы добавить новый виджет на панель инструментов. Далее у нас есть метод register для этой цели. Мы будем перебирать всех добавленных провайдеров и регистрировать их. Обновите содержимое add_dashboard_widgets serverdashboard.php :

1
2
3
4
5
6
7
8
9
<br> /**
  * Register dashboard widget proider to show up on dashboard
  */
 function add_dashboard_widgets() {
   $widget = Widget::instance();
   foreach ($widget->get_provider() as $name=>$provider) {
     $widget->register($name);
   }
 }<br><br>

Далее мы подключимся к admin_footer для вывода встроенного JavaScript внизу страницы администратора для инициализации пакета класса Google Chart. Наш метод run() также обновлен для нового хука.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
/**
   * Start to setup hook
   */
  public function run() {
    add_action( ‘wp_dashboard_setup’, array( $this, ‘add_dashboard_widgets’ ) );
    add_action( ‘admin_enqueue_scripts’, array($this, ‘add_asset’));
    add_action( ‘admin_footer’, array($this, ‘footer’));
  }
   
  /**
   * Inline JavaScript for chart
   */
  function footer() {
    echo ‘
      <script>google.load(«visualization», «1», {packages:[«corechart»]})</script>
‘;
  }

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

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
<?php
/*
Plugin Name: Server Dashboard
Version: 0.1-alpha
Description: Server Status Dashboard
Author: Vinh
Author URI: http://axcoto.com
Plugin URI: http://axcoto.com
Text Domain: Server Dashboard
Domain Path: /languages
 */
namespace AX\StatBoard;
 
use AX\StatBoard\Widget;
 
class Dashboard {
  protected static $_instance=NULL;
  protected $_dashboard_widget = array();
  protected $_plugin_dir=NULL;
 
  /**
   * Auto load class under namespace of this plugin
   */
  public function load_class($classname)
  {
    if (FALSE === $pos = strpos($classname, ‘AX\StatBoard’)) {
      return false;
    }
    $classname = substr($classname, $pos+1 + strlen(‘AX\StatBoard’));
    $filepath = $this->_plugin_dir .
    if (!file_exists($filepath)) {
      return false;
    }
    include $filepath;
  }
   
  /**
   * Setup variable and intialize widget provider
   */
  function __construct() {
    $this->_plugin_dir = plugin_dir_path( __FILE__ ) ;
    spl_autoload_register(array($this, ‘load_class’));
 
    $this->_dashboard_widget = array(
      ‘server’,
      ‘cpuload’,
      ‘ram’,
      ‘disk’,
      ‘software’,
      ‘process’,
      ‘ethernet’,
      ‘networkio’,
       
      ‘iostat’,
    );
 
    foreach ($this->_dashboard_widget as $item) {
      if (!file_exists($this->_plugin_dir . ‘/widget/’ . $item . ‘.php’)) {
        continue;
      }
      $classname = ‘AX\\StatBoard\\Widget\\’ .
      Widget::instance()->add_provider($item, new $classname());
    }
  }
 
  /**
   * Create an unique instance throught the app
   */
  public static function instance() {
    return self::$_instance = self::$_instance ?: new self();
  }
 
  /**
   * Start to setup hook
   */
  public function run() {
    add_action( ‘wp_dashboard_setup’, array( $this, ‘add_dashboard_widgets’ ) );
    add_action( ‘admin_enqueue_scripts’, array($this, ‘add_asset’));
    add_action( ‘admin_footer’, array($this, ‘footer’));
  }
   
  /**
   * Register dashboard widget proider to show up on dashboard
   */
  function add_dashboard_widgets() {
    $widget = Widget::instance();
    foreach ($widget->get_provider() as $name=>$provider) {
      $widget->register($name);
    }
  }
 
  /**
   * Assets load: stylesheet, JS.
   */
  function add_asset() {
    syslog(LOG_DEBUG, «Loaded»);
    wp_enqueue_script( ‘google-chart’, ‘https://www.google.com/jsapi’ );
    //wp_enqueue_script( ‘plugin_dir_url’, plugin_dir_url(__FILE__) . ‘/loader.js’);
  }
 
  /**
   * Inline JavaScript for chart
   */
  function footer() {
    echo ‘
      <script>google.load(«visualization», «1», {packages:[«corechart»]})</script>
‘;
  }
}
 
Dashboard::instance()->run();

Мы в основном создаем экземпляр класса основного плагина и вызываем метод run. Который в свою очередь просто настроил список хуков. Каждый хук — это другой метод внутри класса. Мы также создаем и регистрируем объект нашего провайдера с помощью объекта Widget .

На данный момент мы все еще ничего не показываем; тем не менее, мы выложили структуру для нашего плагина и начали подключаться к Google Charts.

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