Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Диплом Телицкий.doc
Скачиваний:
206
Добавлен:
09.02.2016
Размер:
4.72 Mб
Скачать

Использование adOdb

ADOdb - это абстрактный слой на php по управлению базами данных, работающих под BSD. ADOdb поддерживает ряд ведущих баз данных. Сама Joomla не поддерживает ADOdb, а лишь эмулирует некоторую функциюнальность в своих базах данных. Мы должны использовать ADOdb методы, если мы портируем существующее приложение, использующее ADOdb, или создаем расширение, работающее standalone с использованием ADOdb. Joomla! использует JRecordSet класс для эмуляции класса ADORecordSet. JRecordSet класс еще не закончен, и обладает далеко не всеми методами класса ADORecordSet. В этом примере мы покажем простейшее использование класса JRecordSet ($row - это массив).

$db =& JFactory::getDBO();

$rs = $db->Execute('SELECT * FROM #__test');

while ($row = $rs->FetchRow())

{

// обрабатываем $row

}

Для большей информации о ADOdb читайте http://adodb.sourceforge.net/

JTable

Joomla! предоставляет нам мощный абстрактный класс JTable; при этом мы можем выполненять все основные функции по работе с таблицей. Для каждой таблицы, которую мы хотим использовать в классе JTable, мы должны создать новый подкласс. При создании подкласса JTable, мы должны придерживаться некоторых правил. Эти правила позволят нам интегрировать наше расширение в фрэймворк Joomla. Итак, каждый подкласс JTable должен быть распложен в отдельном файле в каталоге tables (в административной части компонента). Имя создаваемого класса должно иметь префикс table. Имя файла обязательно должно быть в единственном числе. Используем описанную выше схему таблицы, чтобы показать на примере как работать с классом JTable. Класс должен называться TableFoobar и расположен в каталоге JPATH_COMPONENT_ADMINISTRATOR.DS.'tables'.DS.'foobar.php'. При первом использовании нашего класса мы должны определить глобальные свойства. Глобальные свойства соответствуют полям таблицы и должны иметь такие же названия. Мы используем эти свойства как буфер для хранения отдельных записей. Во-вторых. В целях использования метода JTable::getInstance() мы должны определить конструктор. В-третьих нам нужно переопределить метод check(). Этот метод проверяет содержимое буфера и возвращает булев результат. Если метод вернул значение false, то используем метод setError() для пояснения ошибки.

/**

* обработчик таблицы #__myextenstion_foobars

*

*/

class TableFoobar extends JTable

{

/** @var int Primary key */

var $id = null;

/** @var string Content */

var $content = null;

/** @var int Checked-out owner */

var $checked_out = null;

/** @var string Checked-out time */

var $checked_out_time = null;

/** @var string Parameters */

var $params = null;

/** @var int Order position */

var $ordering = null;

/** @var int Number of views */

 

var $hits = null;

/**

* Constructor

*

* @param database Database object

*/

function __construct( &$db )

{

parent::__construct('#__myextension_foobars', 'id', $db);

}

/**

* Проверка

*

* @return boolean True if buffer is valid

*/

function check()

{

if(!$this->content)

{

$this->setError(JText::_('Ваш Foobar должен содержать контент'));

return false;

}

return true;

}

}

Теперь, когда мы создали TableFoobar класс нужно инстанцировать объект с помощью статического метода JTable:: getInstance().

JTable::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR.DS.'tables');

$table = JTable::getInstance('foobar', 'Table');

Заметьте, что мы подключаем не foobar.php а только каталог с таблицами. Когда JTable начинает инстанцировать TableFoobar на объект, автоматически подключается foobar.php.

CRUD

CRUD (Create Read Update Delete) - это общее название основных задач по управлению таблицей. Все CRUD примеры $table ссылаются на класс TableFoobar и $id ссылается на идентификатор записи которую мы в данный момент обрабатываем. В этом примере мы создаем новую запись; $table - экземпляр класса TableFoobar.

$table->reset();

$table->set('content', "Наш контент");

$table->set('ordering', $table->getNextOrder());

if ($table->check())

{

if (!$table->store())

{

// обработчик ошибок записи

// используем $table->getError()

}

}

else

{

// обработчик ошибки проверки буфера

// тоже используем $table->getError()

}

Метод reset() очищает наш буфер и приводит значения всех свойств к значениям по-умолчанию. Метод getNextOrder() определяет следующий по порядку вложенности элемент. Если запись не существующая, то он ставит значение 1. Давайте рассмотрим наш пример подробнее. Некоторые из полей имели значение по-умолчанию, и после записи, значение даты будет пустым. После выполнения предыдущего примера буфер $table выглядит так:

[id] => 1

[content] => Наш контент

[checked_out] =>

[checked_out_time] =>

[params] =>

[ordering] => 1

[hits] => 0

После выполнения метода store() (сохранения записи), мы можем загрузить его:

$table->load($table->id);

Теперь наш буфер выглядит так:

[id] => 1

[content] => Наш контент

[checked_out] => 0

[checked_out_time] => 0000-00-00 00:00:00

[params] =>

[ordering] => 1

[hits] => 0

Вместо загрузки нашей сохраненной записи, мы могли бы изначально верно установить значения по-умолчанию, и нам бы не пришлось перезагружать запись. Однако некоторые значения по-умолчанию зависят от типа данных. Поэтому нам нужно переопределить метод reset(). Для примера значение checked_out_time будет равно $db->getNullDate(). Итак для загрузки конкретной записи используем метод:

if (!$table->load($id))

{

// обработчик загрузки

// используем $table->getError() для ловли ошибок

}

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

// установка значений

$table->reset();

$table->setVar('id', $id);

$table->setVar('content', JRequest::getString('content'));

if ($table->check())

{

if (!$table->store())

{

// обрабатываем ошибки записи с помощью $table->getError()

}

}

else

{

// обрабатываем ошибки ввода в буфер $table->getError()

}

Последнее что мы расмотрим - это удаление записи:

if (!$table->delete($id))

{

// обрабатываем ошибки

}

Если мы не указываем в методе delete() номер id, то id будет браться из буфера. Если наша запись в таблице имеет родственные записи с другими таблицами, то мы должны сначала выполнить проверку методом canDelete(). Этот метод имеет всего один параметр в виде двумерного массива. Внутри массива должно быть несколько ключей - idfield, name, joinfield, и label. idfield - это имя первичного ключа в соответствующей таблице. name - это название самой таблицы. joinfield - это имя внешнего ключа соответствующей таблицы. label - это описание отношения между таблицами, для вывода сообщения об ошибке, если родственных связей не найдено. Представьте что есть еще одна таблица #__myextension_children. Эта таблица имеет первичный ключ childid и внешний ключ primary, который ссылается на запись в таблице #__myextension_foobars. В этом примере мы проверим нет ли зависимости между записями таблицамы #__myextension_children и #__myextension_foobars, перед удалением записи из таблицы #__myextension_foobars.

$join1 = array('idfield' => 'childid',

'name' => '#__myextension_children',

'joinfield' => 'parent',

'label' => 'Children');

 

$joins = array($join1);

if ($table->canDelete($id, $joins))

{

if (!$table->delete($id))

{

// обрабатываем ошибки удаления

}

}

else

{

// обрабатываем в случае нахождения зависимостей

}

Мы можем определить более одной межтабличной связи. Допустим еще существует таблица #__myextension_illegitimate_children:

$join1 = array('idfield' => 'childid',

'name' => '#__myextension_children',

'joinfield' => 'parent',

'label' => 'Children');

$join2 = array('idfield' => 'ichildid',

'name' => '#__myextension_illegitimate_children',

'joinfield' => 'parent',

'label' => 'illegitimate Children');

$joins = array($join1, $join2);