Основы настройки консоли WordPress

Что мы будем создавать

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

Что мы будем создавать

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

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

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

  • Прямо сейчас;
  • Свежие публикации;
  • Быстрая публикация;
  • Новости WordPress;
  • Добро пожаловать.

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

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

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

Я также расскажу о некоторых основных командах Linux, с помощью которых мы будем подтягивать информацию о сервере и вставлять ее в наш виджет консоли.

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

Работа нашего плагина основана на Linux Dash

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

  • Информация о сервере: операционная система, ядро Linux, время обновления и т.д.;
  • Загрузка CPU: средняя загрузка процессора за 1, 5 и 15 минут;
  • Использование оперативной памяти физического ОЗУ и файла подкачки;
  • Использование диска;
  • Установленное программное обеспечение;
  • Процессы;
  • Ethernet;
  • Производительность сети;
  • Статистика IO.

Что вам необходимо

  • Среда Linux. Возможно использование Mac OS X, но некоторые команды для проверки вышеуказанных метрик будут не доступны, так что если после отправки команды вам выдается ошибка, вы будете знать, что в Mac эта команда не поддерживается;
  • Базовое понимание Shell;
  • Базовое понимание плагинов WordPress.

Каркас структуры плагина

Давайте создадим простой плагин и назовем его Server Dashboard. Мы начнем с некоторых базовых вещей. Традиционное Привет, Мир поможет сделать добавление виджета в консоль немного интереснее.

На самом деле это просто.

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

Каркас структуры плагина

Вставьте этот код в файл serverdashboard.php:

<?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 AXStatBoard;
require_once plugin_dir_path( __FILE__ ) . '/widget.php' ;

class Dashboard {
  protected static $_instance=NULL;

  function __construct() {
  }

  /**
   * Создание уникального объекта через приложение
   */
  public static function instance() {
    return self::$_instance = self::$_instance ?: new self();
  }

  /**
   * Обращение запуска настройки
   */
  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', // Жетон для идентификации этого виджета
                 'Hello World', //Заголовок виджета
                 function () {
                   echo 'Hey, I'm the body of widget. Thanks for bring me to the life.';
                 } //функция для вывода контента виджета, здесь я использую закрытие
      );

    }

}

Dashboard::instance()->run();
?><br><br>

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

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

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

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

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

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


Обновите страницу консоли. Плагин выводит наш виджет. Обратите внимание на id элемента div виджета:

Обновите страницу консоли

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

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

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

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

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:

	/**
 * Добавление javascript
 */
function add_asset() {
  wp_enqueue_script( 'google-chart', 'https://www.google.com/jsapi' );
}

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

function add_dashboard_widgets() {
    syslog(LOG_DEBUG, "Run");

    wp_add_dashboard_widget(
        'hello_world_dashboard_widget', // Жетон для идентификации виджета
                 'Hello World', //Заголовок виджета
                 function () {
                   echo <<<'EOD'
Hey, I'm the body of widget. Thanks for bring me to the life.
      <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;
                  } //функция для вывода контента виджета, здесь я использую закрытие
      );    
<br><br>

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

вывели диаграмму в этом элементе

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

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

Извлечение метрик сервера

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

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

$df = `df -h`;
$df = explode("n", $df);
if (is_array($df) && count($df)>=2) {
  array_shift($df); //Get rid the first line
  $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

Чтобы упростить получение данных прямо из команды Shell, мы можем объединить ее с awk.

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

Если вы захотите узнать о awk больше, ознакомьтесь с этим источником.

В целом мы используем awk для обработки каждой строки вывода, и в каждой строке записи будут разделены отступами или пробелами, а доступ к элементам может быть обеспечен через переменные: $ 1 для первого элемента, $ 2 — для второго и так далее.

Синтаксис:

[command_we_run] | awk ' { print $1, $3, ...}'.

Давайте рассмотрим следующий пример:

☁  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 | awk ' {print $3, $4, $5, $9} '

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 содержит девять полей, разделенных пробелами:

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

Это:

  • drwxr-xr-x
  • 4
  • kureikain
  • staff
  • 136B
  • Mar
  • 29
  • 01:27
  • Tests

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

kureikain staff 136B tests<br>

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

Фильтрация данных с помощью GREP

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

Например:

[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 отображает данные об использовании оперативной памяти — физической памяти и файла подкачки; однако это поле включает в себя две других строки: всего / используется / свободно и — / + буфер / кэш, которые нам не нужны.

Мы хотим вытащить только информацию о физической памяти и файле подкачки, то есть данные строки 3 и строки 5. Это можно сделать с помощью grep с переключателем -E. Этот переключатель позволяет использовать для поиска регулярные выражения.

Так как мы хотим найти строку со словами Mem и Swap, давайте зададим их следующим образом:
grep -E «Mem|Swap».

В результате мы получим:

[vagrant@vagrant-centos64 ~]$ free -m | grep -E "Mem|Swap"
Mem:           589        536         52          0          8        271
Swap:          255          0        255

Так намного компактнее. Объединив grep и awk, мы можем отфильтровать данные и получить только ту информацию, которая нам нужна:

[vagrant@vagrant-centos64 ~]$ free -m | grep -E "Mem|Swap" | awk '{print $1, $2, $3, $4}'
Mem: 589 537 52
Swap: 255 0 255

Команды Linux для получения информации о сервере

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

Проверка сетевого трафика:

$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

Проверка использования дискового пространства:

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

Проверка использования оперативной памяти:

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 должен располагаться в корневой папке плагина. Класс buzz пространства имен AXStatBoardBar должен располагаться в папке Barbuzz.php:

Создание виджета

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

Помня это, давайте приступим к разработке метода автоматического загрузчика:

<?php
namespace AXStatBoard;

class Dashboard {
  //..
  public function load_class($classname)
  {
    if (FALSE === $pos = strpos($classname, 'AXStatBoard')) {
      return false;
    }
    $classname = substr($classname, $pos+1 + strlen('AXStatBoard'));
    $filepath = $this->_plugin_dir . strtolower(str_replace('\', '/', $classname) . '.php');
    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>
  //..
}

Итак, что здесь происходит? Наш плагин использует пространство имен AXStatBoard. Таким образом, мы убеждаемся, что запрашиваемый класс в рамках данного пространства имен должен обрабатываться нашим плагином, в противном случае автоматический загрузчик не способен его загрузить.

Затем мы убираем AXStatBoard из имени класса и заменяем на путь к папке плагина. Обратная косая черта в пространстве имен заменяется на разделитель /, и к имени добавляется расширение php. Это означает, что пространство имен будет использоваться в качестве пути к папке, содержащей файл класса, и имя класса будет использоваться в качестве имени файла.

Это происходит, естественно, только в тех случаях, если файл существует. Теперь мы у нас есть автоматический загрузчик, однако нам нужно, чтобы PHP знал, что этот он существует, и мы хотим использовать его. Для этого в PHP существует функция spl_autoload_register. Мы вставим ее в класс конструктора.

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

Исходя из того, что вы знакомы с функцией wp_add_dashboard_widget, нам нужно задать для нее заголовок и содержимое. Соответственно для каждого виджета будет задаваться класс для вывода заголовка и содержимого. Мы назовем эти классы Provider виджета.

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

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

<?php
namespace AXStatBoardWidget;

interface Provider {

  function get_title();
  function get_content();
  function get_metric();
}

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

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

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

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

Мы можем легко добавить другие провайдеры — просто создать объект, который реализует класс провайдера и связать его с классом Widget.

Создайте в корневой папке плагина файл widget.php со следующим содержимым:

<br><?php<br>namespace AXStatBoard;<br>use AXStatBoardWidgetProvider;<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 . $name;<br>    $widget_provider = $this->get_provider($name);<br>    if (empty($widget_provider)) {<br>      return false;<br>    }<br><br>    wp_add_dashboard_widget(<br>      $slugid,<br>      $widget_provider->get_title(),<br>      array($widget_provider, 'get_content'));<br>    return true;<br>  }<br>}<br><br>

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

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

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

<?php

/**
 * Установка переменной и инициализация провайдера виджета
 */
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\' . ucwords($item);
    Widget::instance()->add_provider($item, new $classname());
  }
}<br><br>

Мы помещаем все классы провайдеров виджетов в пространстве имен AXStatBoardWidget, поэтому они будут располагаться в папке виджета. Нам нужно отслеживать девять видов метрик, поэтому мы называем класс соответственно массиву _dashboard_widgets, приведенному выше.

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

создаем новый экземпляр его провайдера

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

Через цикл мы обрабатываем все добавленные провайдеры и регистрируем их. Внеся соответствующие изменения в add_dashboard_widgets файла serverdashboard.php, мы получим следующий код:

<br>  /**
  * Регистрация провайдера виджета консоли для вывода его на консоль
  */
 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() также обновляется для нового подключения:

/**
   * Обращение начала настройки
   */
  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'));
  }

  /**
   * Встроенный JavaScript
   */
  function footer() {
    echo '
      <script>google.load("visualization", "1", {packages:["corechart"]})</script>
';
  }

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

<?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 AXStatBoard;

use AXStatBoardWidget;

class Dashboard {
  protected static $_instance=NULL;
  protected $_dashboard_widget = array();
  protected $_plugin_dir=NULL;

  /**
   * Класс автозагрузки в пространстве имен плагина
   */
  public function load_class($classname)
  {
    if (FALSE === $pos = strpos($classname, 'AXStatBoard')) {
      return false;
    }
    $classname = substr($classname, $pos+1 + strlen('AXStatBoard'));
    $filepath = $this->_plugin_dir . strtolower(str_replace('\', '/', $classname) . '.php');
    if (!file_exists($filepath)) {
      return false;
    }
    include $filepath;
  }

  /**
   * Установка переменной и инициализация провайдера виджета
   */
  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\' . ucwords($item);
      Widget::instance()->add_provider($item, new $classname());
    }
  }

  /**
   * Создание уникального экземпляра объекта через приложение
   */
  public static function instance() {
    return self::$_instance = self::$_instance ?: new self();
  }

  /**
   * Обращение начала настройки
   */
  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'));
  }

  /**
   * Регистрация провайдера виджета консоли для вывода его на консоль
   */
  function add_dashboard_widgets() {
    $widget = Widget::instance();
    foreach ($widget->get_provider() as $name=>$provider) {
      $widget->register($name);
    }
  }

  /**
   * Загрузка элементов: таблицы стилей, 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');
  }

  /**
   * Встроенный JavaScript
   */
  function footer() {
    echo '
      <script>google.load("visualization", "1", {packages:["corechart"]})</script>
';
  }
}

Dashboard::instance()->run();

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

Что дальше?

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

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

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

Перевод статьи «The Fundamentals of Building a WordPress Server Dashboard» был подготовлен дружной командой проекта Сайтостроение от А до Я.