Набор модулей as_admintool написан в основном для людей (типа меня :),
кому часто приходится выполнять административные задачи на одном или
нескольких сайтах : выполнять SQL запросы, делать резервные копии данных БД,
восстанавливаться из них, и т.п.
Во-первых, хотелось сделать гибкое и расширяемое средство,
позволяющее легко наращивать функционал и делать его единым по стилю.
Во-вторых, решено было сразу использовать асинхронные AJAX вызовы, где это возможно.
В результате был сделан пустой класс-контейнер, и набор подключаемых к нему
модулей (плагинов), собственно и выполняющих отдельные задачи.
Также предлагается плагин-заглушка, на котором легче понять принцип написания
новых модулей, и который может быть для них точкой старта разработки.
Разобравшись во внутренней "кухне", любой PHP-программист может дописать
свои плагины.
Внимание: ввиду широкого использования Javascript и DHTML,
необходимо тестировать модули на кросс-браузерную совместимость, если планируется использовать
в Интернет.
Как уже говорилось, подключите нужные модули к своему скрипту, используя функции require_once() или include_once(). Не забудьте, что все плагины должны идти ПОСЛЕ подключения основного файла - require_once('as_admintool.php')
Листинг 1: секция подключений
require_once('as_admintool.php'); require_once('as_admintool_sqlqry.php'); // плагин SQL запросовТеперь Вы можете создать объект класса CAsAdminTool и заполнить его страницами для выполнения SQL-запросов. Можно добавить более чем одну SQL-страницу - например, если понадобится одновременно иметь результаты двух разных запросов и переключаться между ними для анализа. (И как мы увидим позднее, у каждой страницы может быть свой набор "предопределенных" SQL запросов ).
Когда все страницы добавлены, вызываем метод Draw().
Листинг 2: создание объекта CAsAdminTool object, добавление страниц и вывод окна.
$adminobj = new CAsAdminTool(800,620); // desired width and height passed $adminobj->AddPage(ADM_SQLQUERY,'SQL Queries page 1', 'predef-qry1.txt'); $adminobj->AddPage(ADM_SQLQUERY,'SQL Queries (page 2)', 'predef-qry2.txt'); $adminobj->Draw();
Ну вот, мы получили экран с двумя страницами для выполнения SQL-запросов.
Где происходит их отработка и формирование HTML кода с результатом, когда мы нажимаем кнопку "Выполнить" ?
as_admintool написан таким образом, что все модули плагины посылают AJAX-запросы на тот же скрипт,
из которого они вызваны.
Для приема запроса от клиента и отправки ему HTML кода с результатами,
Вы должны где-то в начале своего скрипта разместить вызов статического метода CAsAdminTool::PerformAction(),
и сделать это нужно ДО первого вывода данных в браузер клиента (функции echo, print(),Header(),
посылка cookies и т.п.).
В противном случае весь этот вывод улетит в AJAX ответ клиенту, нарушив работу скриптов.
С другой стороны, обработка запросов должна проходить после всех проверок безопасности
(чтобы убедиться, что SQL запрос, например, пришел от авторизованного клиента).
Поэтому выбирайте правильное место в своем скрипте для помещения CAsAdminTool::PerformAction().
Следующий листинг показывает вариант такого кода (мы предполагаем, что есть специальная переменная сессии,
хранящая уровень полномочий подключенного пользователя):
Листинг 3: образец кода с проверкой уровня доступа
require_once('as_admintool.php'); require_once('as_admintool_sqlqry.php'); // localize interface here or just change titles, if needed: $as_iface['parameters'] ='Параметры запроса'; $as_iface['predef-qry'] ='Предопр.запросв...'; $as_iface['execqry'] ='Выпаолнить SQL'; $as_iface['explainqry'] ='Show execution plan'; $as_iface['qryresult'] ='Результат запроса'; $as_iface['msg_waiting'] ='Ожидаем ответа...'; // some CSS tuning $as_cssclass['pagebody'] = 'frmtable'; if(!isset($_SESSION)) session_start(); $as_adm_qryaccess = empty($_SESSION['access_level'])? 0 : $_SESSION['access_level']; // sqlqry плагин может работать с уровнями доступа : 0-1-2 ConnectDb(); // Ваш код подключения к БД # Client request executing code: this is a mandatory line, # You add it before any HTML drawing code ! # You can check user access level before this, to avoid unauthorized calls if(!empty($admt_call_handler)) CAsAdminTool::PerformAction(); HTML_Header(); // function that draws your html header block, at least <HTML><BODY> and all CSS styles or css file reference... if($access gt; 1 ) { $adminobj = new CAsAdminTool; $adminobj-gt;SetJsPath('js/'); // if as_jsfunclib.js file is not in cur.dir $adminobj-gt;AddPage(ADM_SQLQUERY,'SQL запросы', 'predef-qry1.txt'); $adminobj-gt;AddPage(ADM_SQLQUERY,'SQL запросы-2', 'predef-qry2.txt'); $adminobj-gt;Draw(); } else echo "access denied !";
Далее - полный список методов класса CAsAdminTool.
конструктор: CAsAdminTool($width='920',$height='600') |
$width - ширина "рамки" (property sheet), содержащей все "админские" страницы; по умолчанию 920 пикс. $height - высота, по умолчанию 600. Пример: $obj = new CAsAdminTool(800,400); |
AddPage($pagetype, $pagetitle, $userparam1='', $userparam2='',$userparam3='') | Регистрирует одну страницу администраторских функций.
$pagetype - строчный ID одного из "зарегистрированных" типов. $pagetitle - Титульный текст (выводится на переключающем "язычке" вверху экрана) $userparam1,2,3 - дополнительные параметры, которые передаются в соответствующие функции отрисовки страниц, так чтобы у каждой могли быть свои специфические наборы параметров. В образцовом скрипте sample.php это используется, чтобы у каждого экрана SQL запросов был свой список предопределенных запросов, выбираемых в select-боксе. Пример: $obj->AddPage('sqlqry', 'Sql query - page 1','','mydatabase'); |
SetJsPath($strk) | Задает виртуальный путь к файлу as_jsfunclib.js, используемому во всех модулях проекта.
Пример: $obj->SetJsPath('js/'); |
Draw($initpage=false) | Метод, выполняющий вывод на экран подготовленных рабочих страниц администратора.
Параметр $initpage может задать номер "изначально" активной страницы набора.
Пример: $obj->Draw(2); |
PerformAction() | Специальный статический метод, который перехватывает управление в скрипте на сервере,
если обнаружен пришедший от клиента набор POST-переменных с параметром adm_action_type,
и в зависимости от значения этого параметра вызывает соответствующую функцию обработки
запроса. Повторюсь, вызов этого метода надо расположить в скрипте ДО первого вывода HTML кода.
Пример: CAsAdminTool::PerformAction(); |
Чтобы иметь возможность добавления страниц SQL запросов в свой администраторский интерфейс, Вы добавляете строку require_once('as_admintool_sqlqry.php') :
require_once('as_admintool.php'); ... require_once('as_admintool_sqlqry.php');При этом регистрируется тип 'sqlqry' (его же задает константа ASADM_SQLQUERY), так что теперь можно добавлять страницы SQL запросов: (AddPage()) :
$adminobj-gt;AddPage('sqlqry','Sql запросы');
Использование "as_admintool_sqlqry", подробное описание
Метод AddPage({TYPE},{title},$par1,$par2) для типа sqlqry имеет следующие пользовательские параметры:
Параметр $par1 - задает список предопределенных SQL запросов,
Параметр $par2 - имя базы данных, если оно отличается от основного (можно делать запросы в другую базу).
Предопределенные SQL запросы
Каждая страница sqlqry может иметь свой набор "стандартных" запросов, которые не придется вводить вручную,
а достаточно будет выбрать их название в соответствующем select-боксе, и текст запроса будет выодится
в текстовом поле ввода.
Для задания списка таких запросов можно подготовить переменную-массив следующего вида:
каждая строка - это массив двух и более значений:
array('query label', 'SQL query text' [,Параметр_1_prompt [,...])
Нулевой элемент массива-строки - название запроса,
первый - сам текст SQL запроса (с макросами &P{nn}, если надо),
остальные - это заголовки под поля ввода параметров, если запрос - "параметрический".
Эти заголовки будут выводиться над полями ввода при выборе данного SQL запроса в select-боксе.
Приготовив массив, мы передаем его как параметр метода AddPage:
$myqueries = array(); $myqueries[] = array('Find dept',"SELECT * from depts where deptname like '&P1%'",'search for dept:'); $myqueries[] = array('Find person',"SELECT * from employees where name like '&P1%'",'person name'); $adminobj->AddPage('sqlqry', 'My queries',$myqueries);Ворзможен другой вариант, позволяющий вынести список запросов в отдельный файл: мы готовим текстовый файл с нашими запросами, где одна строка задает описание одного запроса, при этом его параметры идут в том же порядке, что и ранее, разделяясь символом "|":
label | SQL-query-text [|param1-prompt|...]Если нужно, чтобы в окне ввода наш запрос отобразился как мульти-строчный (с символами перевода строки), используйте комбинацию "{CRLF}" в нужных местах (только без кавычек).
Сотрудники в подразделении|SELECT * from employees WHERE deptname LIKE '&P1%'|Department name Получить все товары нужного типа и класса|SELECT * from goods WHERE good_class='&P1' AND good_name='&P2'|тип|класс Два запроса сразу|SELECT SYSDATE(){CRLF}/{CRLF}SELECT * FROM mytable
Константы и глобальные переменные в as_admintool_sqlqry
ASADM_SQLQUERY эквивалентна строке 'sqlqry', уникальное "внутреннее" имя плагина.
ASADM_MAXRECORDS максимальное кол-во записей, возвращаемое одним запросом.
(эквивалентно заданию в запросе MySQL опции LIMIT 0,NNN. - делается для защиты от "огромных" таблиц, запрос к которым
может как подвесить сервер, так и привести к зависанию у клиента. По умолчанию 200.
Чтобы отключить этот ограничитель, задайте значение 0.
$as_adm_qryaccess - эта переменная должна быть задана до вызова вода метода
CAsAdminTool::PerformAction() - она задает уровень ограничений на типы выполняемых запросов.
Выбирайте ее значение в соответствии с уровнем полномочий подключенного пользователя.
ASADM_QRYPARAM число полей под ввод параметров, выводимых на странице SQL запросов По умолчанию 4. Если задать бОльшее число, поля параметров будут ыводится по четыре в одной строке.
Пользовательские "HREF" колонки
Что если мы хотим иметь в конце строки данных, возвращенных нашим запросом, иметь HTML-ссылку, открывающую
полную информацию, относяющуюся к данной записи ?
Например, найдя сотрудника по введенному фрагменту фамилии,
мы хотим сразу перейти на экран полных данных по этому сотруднику, который выводится скриптом empdata.php?empid=NNN
Для таких случаев была добавлена функция вставки user-defined колонок (UDC).
Для этого в массиве описания одного предопределенного запроса надо включить строку, начинающуюся с #HREF :
Синтаксис UDC-колонки :
#HREF ^ {column_number} ^ HTML-code_with_{ID}Описание HREF-ссылки начинается с символов "#HREF", после которых через символ-разделитель "^" идут параметры : column_number 0-based номер колонки в текущей строке рекорд-сета, из которой будет браться ключевое значение (например, ID найденного сотрудника).
Пример
Есть запрос, возвращающий список сотрудников, включая ИД сотрудника в первой колонке:
SELECT emp_id, emp_name ... FROM employees ...
Мы хотим вывести список, дополнив его колонкой с ahchor-тегом <A HREF> , который ведет на скрипт
с полнывми данными по сотруднику, "empdata.php?emp_id=NNN".
Для этого делаем следующее описание запроса (в строке файла-списка):
Query title|SELECT emp_id, emp_name ... FROM employees|#HREF^0^<A HREF='empdata.php?emp_id={ID}'>open info</a>Обратите внимание, что номера колонок начинаются с нуля, т.е. наша первая колонка с ID сотрудника имеет номер "0". Если Вы формируете массив запросов в переменной, то добавляете туда элемент аналогичной #HREF-конструкцией:
$myqueries[] = array('Find person',"SELECT * from employees where name like '&P1%'",'person name',"#HREF^0^....");
require_once('as_admintool.php'); require_once('as_admintool_backup.php'); // регистрируем плагин ... $bckp_folder = 'backups/'; // Папка для файлов резервных копий, должна быть заранее создана $bckp_list = array('mytable1','mytable2'); # список таблиц для сохранения $db_name = 'mydatabase'; $adminobj->AddPage(ASADM_BACKUP,'my backups', $bckp_list, $bckp_folder, $db_name); ... $adminobj->Draw();
Как и во всех плагинах, второй параметр $title задает текст заголовка страницы (для язычка переключения).
Третий параметр ($bckp_list) может быть массивом, содержащим список всех таблиц, которые требуется архивировать, или именем текстового файла, содержащего все имена таблиц (по одному в строке) Если нужно, чтобы были выведены ВСЕ таблице в базе, передается пустая строка.
Необязательный четверый параметр - имя папки, куда будет формироваться файл резервной копии. Папка "по умолчанию" может быть задана однократно через глобальную переменную $as_admt_bckpfolder, чтобы не передавать значение многократно через AddPage().
Необязательный 5-ый Параметр это имя базы, если оно отлично от текущего.
// передаем список таблиц в массиве: $mytables = array('users','employees','depts','orderlist','clientlist'); $adminobj->AddPage(ASADM_BACKUP,'my backups', $mytables, $bckp_folder,'mydb');
Список глобальных переменных и констант as_admintool_backup
ASADM_BACKUP_GZIP - задает режим формирования файлов бэкапа в сжатом gzip-формате.
Если не ноль, все бэкап файлы сразу формируются в gfzip. К имени файла в этом случае добавляется
расширение ".gz". По умолчанию включено - 1.
$as_admt_bckpfolder - базовая папка для файлов бэкапа. По умолчанию : 'backup/'
$as_admt_bcktemplate шаблон для имени создаваемого файла бэкапа.
Может содержать элементы, представляющие текующу дату-времени:
YYYY | год (4 цифры) |
YY | год (2 цифры) |
MM | месяц (2 цифры with leading zero) |
DD | день (2 цифры) |
HH | часы |
MI | минуты |
SS | секунды |
Значение по умолчанию 'backup-YYYY-MM-DD-HHMI'.
Расширение '.xml' (или xml.gz) доьбавляется программно, так что не включайте его в шаблон.
Если пользователь в соответствующем поле введет свое имя файла, оно будет использовано вместо
шаблонного.
Добавление функции 'Restore':
require_once('as_admintool_restore.php'); ... $adminobj->AddPage('restore','Restore from backups',$backupfolder,$db_name); ... $adminobj->Draw();
Работа с плагином "as_admintool_restore"
На странице "Restore" администратор может выбрать один из файлов, находящихся в папке backup,
(из них формируется список опций в select-боксе выбора исходного файла), а также ввести имена отдельных
таблиц, которые он хочет восстановить (если поле "Restore only" оставить пустым, все таблицы, сохраненные в выбранном
бэкап-файле, будут восстановлены, с потерей текущего содержимого).
Процесс запускается кнопкой "Start restore".
ВНИМАНИЕ: файл бэкапа может содержать большой объем данных, и клиент может прервать сеанс работы по таймауту. Как в этом случае поведет себя сервер - зависит от настроек на его стороне. В частности, выполнение скрипта может быть прервано, и тогда часть данных окажется не занесена. Поэтому запуская операции backup, restore, учитывайте размер данных, подлежащих сохранению-восстановлению.
Список глобальных переменных и констант as_admintool_restore
Как и в предыдущем плагине, as_admintool_backup, здесь используется значение той же глобальной переменной
для папки бэкапов :
$as_admt_bckpfolder
Если формируется несколько страниц "восстановления", для каждой можно задать свою папку
backup и свою базу, куда восстанавливать данные - для этого используются 3-ий и 4-ый параметр метода
AddPage().
Любой файл в папке backup, имеющий расширение '.xml' или '.gz' будет интерпретироваться
как резервная копия, и попадает в список восстановления.
С помощью модуля Web-администратор может управлять файлами через WEB-интерфейс :
загружать файлы в папки на сервере, скачивать их на локальный компьютер (например, php-скрипт обычным способом по HTTP не скачать),
и удалять.
Это единственный плагин, который не вписывается полностью в AJAX-модель, т.к.
аплоад файлов (загрузка на сервер) не реализуема без стандартного FORM/POST-механизма
(либо реализуема на ограниченном количестве браузеров, или с привлечением дополнительных компонент)
Можно "защитить" отдельные имена файлов от модификации (перезаписи или удаления), если указать их имена в массиве $asdt_fmgr_protect.
Работа с плагином "as_admintool_filemgr.php"
Добавьте строку require_once('as_admintool_filmgr.php') в начале своего скрипта.
И оператор AddPage() с нужными параметрами:
require_once('as_admintool.php'); require_once('as_admintool_filemgr.php'); ... $foldlst = array(array('./','текущая папка'), 'img/', array('scripts/','Папка скриптов Js'), 'backups/','Папка бэкапов'); $adminobj->AddPage(ASADM_FILEMGR,'Файл-менеджер', $foldlst); $adminobj->Draw();Как видим, в третьем параметре передается переменная - массив папок, "видимых" нашему файл-менеджеру. Если элемент массива - простая строка, ее содержимое считается именем (путем) папки. Можно передать не только папку, но ее "словесное" представление в select-боксе, для чего передается не строка, а 2-мерный массив (см. выше для папок "scripts/", "backups/").
Список глобальных переменных и констант as_admintool_filemgr
Исходные текстовые файлы с данными для импорта копируются в одну папку на сервере, ее имя (путь) передается как параметр методу AddPage().
Пример использования плагина
require_once('as_admintool.php'); require_once('as_admintool_slqimport.php'); $tables = array('employees','departments','salaries'); # only these tables can be imported from txt files $adminobj = new CAsAdminTool(800,620); $adminobj->AddPage(ASADM_SQLIMPORT,'Data importing', 'data-files/',$tables); $adminobj->Draw();Параметры fro sqlimport плагин В третьем параметре в метод AddPage() передается имя папки с файлами, а необязательный четвертый - массив с именами таблиц, "разрешенных" для импорта.
Процесс импорта данных
На странице "импорта" Вы выбираете таблицу, в которую будете импортировать, и исходный файл (если он есть).
Если файл был помещен в папку после входа на страницу администратора, содержимое select-бокса можно обновить,
чтобы он там появился - для этого есть кнопка "обновления списка".
Когда выбор сделан, нажимаете "Select fields for columns...". В ответ должна отобразиться табличная форма
со списком данных в выбранном файле, где для каждой колонки данных вам нужно будет выбрать
поле таблицы, в которое эта колонка будет заноситься. (В таблицу выводятся первые 20 строк из файла)
Символ разделителя в исходном файле определяется автоматически по максимуму полученных колонок в строках.
Выбирать поле для ВСЕХ распознвнных колонок необязательно - пимпорт будет выполнен, если задано хотя бы одно
приемное поле в таблице.
Перед стартом импорта не забудьте включить режим предварительной очистки таблицы, если нужно.
Несколько javascript-функций, которые используются во многих скриптах сервера, в том числе и во всех
модулях as_Admintool, оформлены в отдельный файл js-библиотеки, as_jsfunclib.js -
это сборка полезных функций, найденных в Сети, частично модифицированных и написанных самостоятельно.
Например, для создания объекта XMLHttpRequest в любом браузере, используется часто упоминаемая в интернет функция NewXMLHttpRequest().
Для сбора значений всех полей HTML формы, отправляемых в XMLHttpRequest, применяется функция
ComputeParamString(frmname, skipempty, fldlist), в которой
frmname - имя формы (атрибут "name" тега <FORM>),
skipempty - переменная, включающая режим пропуска пустых значений,
fldlist - массив, явно задающий список имен полей, подлежащих передаче (если не нужно передавать ВСЕ поля формы)