K4:Работа с классом kDBItem
From In-Portal Developers Guide
(Lang. side-box) |
Current revision (18:40, 26 November 2010) (view source) (Changed back to Russian) |
||
Line 1: | Line 1: | ||
{{toc | category = Системные классы | sortkey = 003.001}} | {{toc | category = Системные классы | sortkey = 003.001}} | ||
<!-- Пишите ПОСЛЕ этой строки, пожалуйста. Ничего не стирать! --> | <!-- Пишите ПОСЛЕ этой строки, пожалуйста. Ничего не стирать! --> | ||
- | + | Класс '''<code>kDBItem</code>''' - один из базовых классов. Он предоставляет методы для работы с данными, относящимися к одной записи. Для связи объектов класса '''<code>kDBItem</code>''' с прочими частями системы широко используются события. События происходящие во время выполнения методов класса '''<code>kDBItem</code>''' можно [[K4:Hooks|перехватывать]] и выполнять необходимые действия. И наоборот - в системе имеются события, при наступлении которых выполняются методы класса '''<code>kDBItem</code>'''. | |
- | == | + | == Загрузка из базы данных == |
- | + | Для загрузки из базы данных используется метод '''<code>Load</code>'''. Метод возвращает значение '''<code>true</code>''' в случае успешной загрузки данных и '''<code>false</code>''' в прочих случаях. Если требуется проверить факт успешной загрузки из базы данных у отдельно взятого объекта, то можно использовать метод '''<code>isLoaded</code>''', который возвращает статус последней загрузки объекта. Условия загрузки данных задаются параметрами метода. Они могут быть простыми и сложными. | |
- | + | Простое условие загрузки получается если первым параметром передаётся значение одного из полей записи. Обычно это '''<code>Integer</code>''' значение первичного ключа и тогда второй параметр не нужен. Если первым параметром передают значение другого поля, то вторым параметром должно быть название соответствующего поля. | |
<source lang="php"> | <source lang="php"> | ||
- | // | + | // получаем ссылку на объект. Третий параметр предотвращает автоматическую загрузку данных в объект |
$user =& $this->Application->recallObject('u', null, Array('skip_autoload' => true)); | $user =& $this->Application->recallObject('u', null, Array('skip_autoload' => true)); | ||
/* @var $user kDBItem */ | /* @var $user kDBItem */ | ||
- | // | + | // загружаем данные объекта с ID = 23 |
$user->Load(23); | $user->Load(23); | ||
- | // | + | // Тут могут быть всякие действия с объектом |
- | // | + | // Загружаем в объект данные пользователя по его адресу электронной почты |
$user->Load('erik@intechnic.com', 'Email'); | $user->Load('erik@intechnic.com', 'Email'); | ||
</source> | </source> | ||
- | + | Сложное условие загрузки получается если первым параметром передать массив, содержащий в качестве ключей имена полей а в качестве значений - значения, которые должны быть в соответствующих полях у загруженной записи. | |
<source lang="php"> | <source lang="php"> | ||
Line 33: | Line 33: | ||
</source> | </source> | ||
- | + | В итоге для загрузки данных будет использоваться SQL-запрос с условием следующего вида: | |
<source lang="sql"> | <source lang="sql"> | ||
Line 39: | Line 39: | ||
</source> | </source> | ||
- | == | + | == Изменение данных == |
- | '''<code>SetField</code>''' | + | Для изменения данных одного поля используются методы '''<code>SetField</code>''' и '''<code>SetDBField</code>'''. '''<code>SetDBField</code>''' записывает в поле значение параметра '''<code>$value</code>''' в точности таким как оно передано. '''<code>SetField</code>''' перед тем как записать значение, проверяет не назначен ли для поля [[K4:Formatters|форматер]], и если назначен, то трансформирует значение поля методом Parse [[K4:Formatters|форматера]]. |
<source lang="php"> | <source lang="php"> | ||
- | // | + | // например в случае с форматированием даты |
$user->SetField('dob', '12/22/1971'); | $user->SetField('dob', '12/22/1971'); | ||
- | // | + | // результат операции будет эквивалентен |
$user->SetDBField('dob', 62197200); | $user->SetDBField('dob', 62197200); | ||
</source> | </source> | ||
- | + | Часто бывает удобно поменять данные сразу в нескольких полях. Например, переписать значения полей, которые пришли в результате submit-а формы. Для этого имеются функции '''<code>SetFieldsFromHash</code>''' и '''<code>SetDBFieldsFromHash</code>'''. Они принимают в качестве параметра массив, содержащий имена полей и значения для них. '''<code>SetFieldsFromHash</code>''', как вышеупомянутый '''<code>SetField</code>''', вызывает метод '''<code>Parse</code>''' [[K4:Formatters|форматера]] для трансформации значений. | |
<source lang="php"> | <source lang="php"> | ||
Line 58: | Line 58: | ||
'dob' => '12/22/1971' | 'dob' => '12/22/1971' | ||
); | ); | ||
- | // | + | // обычно подобный массив получают из запроса конструкцией вида |
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); | $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); | ||
list ($id, $field_values) = each($items_info); | list ($id, $field_values) = each($items_info); | ||
- | // | + | // и, наконец - запись данных в объект |
$user->SetFieldsFromHash($field_values); | $user->SetFieldsFromHash($field_values); | ||
</source> | </source> | ||
- | + | Иногда, например при импорте данных, приходится один и тот же объект класса '''<code>kDBItem</code>''' использовать многократно с разными наборами данных. В таких случаях может оказаться полезным метод '''<code>Clear</code>''', выставляющий всем полям значения по умолчанию и таким образом гарантирующий, что в каждом наборе будут только его собственные данные. | |
- | == | + | == Определение изменившихся полей == |
- | + | Часто бывает полезно при изменении данных объекта также проверить какие именно поля менялись а какие - нет. Например, если какие-то действия есть смысл производить только при изменениях в определённых полях. Получить значение поля, которое было до изменения данных, сразу после загрузки данных из базы можно с помощью метода '''<code>GetOriginalField</code>'''. | |
- | == | + | == Проверка == |
- | + | Для проверки данных объекта применяется метод '''<code>Validate</code>'''. Если в ходе выполнения метода обнаруживается несоответствие данных предъявляемым к ним требованиям, то в свойство '''<code>FieldErrors</code>''' объекта, представляющее собой массив с именами полей в качестве ключей верхнего уровня, дописываются элементы второго уровня с ключами '''<code>'pseudo'</code>'''. Это коды ошибок, коротко описывающие сущность проблемы. Проверить есть ли в объекте такие коды можно методом '''<code>HasErrors</code>'''. | |
- | + | Увидеть эти коды можно в [[K4:Debugger|отладчик]], если открыть его после неудачной попытки сохранения записи. | |
<source lang="php"> | <source lang="php"> | ||
[Name] = Array | [Name] = Array | ||
Line 82: | Line 82: | ||
</source> | </source> | ||
- | + | Иногда бывает необходимо не только считывать информацию об ошибках в полях, но и записывать её. Например, при написании функций проверки данных, специфических для конкретной задачи. Тогда, для обозначения ошибок в поле следует использовать предоставляемый классом '''<code>kDBItem</code>''' метод '''<code>SetError</code>'''. | |
- | + | Например, при редактировании данных в форме можно выбрать из списка категорию, к которой отностится объект. Однако, перед сохранением в базу данных хорошо бы убедиться что категория с таким номером действительно существует: | |
<source lang="php"> | <source lang="php"> | ||
Line 98: | Line 98: | ||
$category_id = $object->getDBField('CategoryId'); | $category_id = $object->getDBField('CategoryId'); | ||
if (!$category_id) { | if (!$category_id) { | ||
- | // | + | // значение не задано - проверка не нужна |
return; | return; | ||
} | } | ||
if ($category_id == $object->GetOriginalField('CategoryId')) { | if ($category_id == $object->GetOriginalField('CategoryId')) { | ||
- | // | + | // значение не изменялось - проверка не нужна |
return; | return; | ||
} | } | ||
Line 116: | Line 116: | ||
</source> | </source> | ||
- | == | + | == Сохранение в базу данных == |
- | + | Для сохранения в базу данных используются методы '''<code>Create</code>''' и '''<code>Update</code>'''. Метод '''<code>Create</code>''' предназначен для создания новой записи. Метод '''<code>Update</code>''' - для изменения существующей записи. Оба эти метода по умолчанию, перед тем как записывать данные в базу, делают проверку методом '''<code>Validate</code>''', и производят запись только в случае если проверка пройдена успешно. В приведённом ниже примере делается импорт данных, правда, если данные создаваемого пользователя не пройдут проверку, то запись просто не будет создана. | |
<source lang="php"> | <source lang="php"> | ||
- | // | + | // считываем данные из внешнего источника данных в массив |
$sql = 'SELECT username, password, email | $sql = 'SELECT username, password, email | ||
FROM user'; | FROM user'; | ||
$users = $application->Conn->Query($sql); | $users = $application->Conn->Query($sql); | ||
- | // | + | // создаём объект класса kDBItem |
$user =& $application->recallObject('u.-item', null, Array('skip-autoload' => true)); | $user =& $application->recallObject('u.-item', null, Array('skip-autoload' => true)); | ||
/* @var $user kDBItem*/ | /* @var $user kDBItem*/ | ||
foreach ($users AS $user_data) { | foreach ($users AS $user_data) { | ||
- | // | + | // выставляем значения по умолчанию вызовом метода Clear |
$user->Clear(); | $user->Clear(); | ||
- | // | + | // выставляем значения полей импортируемой записи |
$user->SetDBField('Login', $user_data['username']); | $user->SetDBField('Login', $user_data['username']); | ||
$user->SetDBField('Email', $user_data['email']); | $user->SetDBField('Email', $user_data['email']); | ||
Line 139: | Line 139: | ||
$user->SetDBField('VerifyPassword', $user_data['password']); | $user->SetDBField('VerifyPassword', $user_data['password']); | ||
- | // | + | // вызываем метод Create для создания записи в нашей системе |
$user->Create(); | $user->Create(); | ||
} | } | ||
</source> | </source> | ||
- | == | + | == Использование событий == |
- | + | Четыре основных метода класса '''<code>kDBItem</code>''', способные непосредственно обращаться к базе данных - это методы: | |
* '''<code>Create</code>'''; | * '''<code>Create</code>'''; | ||
* '''<code>Load</code>'''; | * '''<code>Load</code>'''; | ||
* '''<code>Update</code>'''; | * '''<code>Update</code>'''; | ||
* '''<code>Delete</code>'''. | * '''<code>Delete</code>'''. | ||
- | + | Каждый из них в определённых ситуациях вызывает события, которые можно использовать для связи объекта класса '''<code>kDBItem</code>''' с остальными частями системы. Все эти четыре метода могут в ходе своего выполнения вызывать события '''<code>OnBeforeItem****</code>''' и '''<code>OnAfterItem****</code>''', где '''<code>****</code>''' - имя метода. Событие '''<code>OnBeforeItem****</code>''' вызывается до обращения к базе данных. Событие '''<code>OnAfterItem****</code>''' вызывается только после успешного обращения к базе данных. | |
- | + | Методы '''<code>Create</code>''' и '''<code>Update</code>''' могут вызывать ещё и событие '''<code>OnAfterItemValidate</code>'''. Это происходит в случае, если производилась проверка данных объекта и эта проверка прошла успешно. Событие '''<code>OnAfterItemValidate</code>''' вызывается до того как произойдёт обращение к базе данных. Ниже приведён пример того, как можно использовать событие <code>OnAfterItemDelete</code> для выполнения дополнительных действий после успешного удаления записи. | |
<source lang="php"> | <source lang="php"> | ||
Line 160: | Line 160: | ||
/* @var $object kDBItem */ | /* @var $object kDBItem */ | ||
- | // | + | // несмотря на то что запись в базе данных уже удалена, в памяти хранятся все её данные и |
- | // | + | // в зависимости от значения полей удалённой записи можно выполнять разные действия |
$topic_id = $object->GetDBField('TopicId'); | $topic_id = $object->GetDBField('TopicId'); | ||
if (!$topic_id) { | if (!$topic_id) { | ||
Line 176: | Line 176: | ||
</source> | </source> | ||
- | == | + | == Основные события, использующие этот класс == |
- | + | Основные события, которые используют класс '''<code>kDBItem</code>''' находятся в классе '''<code>kDBEventHandler</code>'''. | |
{| class="prettytable" | {| class="prettytable" | ||
- | ! | + | ! Основные События || Аналоги, используемые при работе с временными таблицами || Используемые методы kDBItem |
|- | |- | ||
| <code>OnNew</code> || <code>OnPreCreate</code> || <code>setID(0)</code> | | <code>OnNew</code> || <code>OnPreCreate</code> || <code>setID(0)</code> | ||
Line 189: | Line 189: | ||
|} | |} | ||
- | + | Эти события как правило инициируются непосредственно с web-страницы, то есть, их имена передаются в запросе к серверу. | |
- | + | Событие '''<code>OnNew</code>''' происходит при открытии формы ввода данных для создания новой записи. | |
- | * '''<code>OnCreate</code>''' - | + | * '''<code>OnCreate</code>''' - при отсылке данных на сервер для создания новой записи. |
- | * '''<code>OnUpdate</code>''' - | + | * '''<code>OnUpdate</code>''' - при отсылке данных на сервер для модификации существующей записи. |
<source lang="php"> | <source lang="php"> | ||
function OnUpdate(&$event) | function OnUpdate(&$event) | ||
{ | { | ||
- | // | + | // Получаем ссылку на объект класса kDBItem. |
$object =& $event->getObject( Array('skip_autoload' => true) ); | $object =& $event->getObject( Array('skip_autoload' => true) ); | ||
- | // | + | // Получаем данные из запроса. |
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); | $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); | ||
if ($items_info) { | if ($items_info) { | ||
foreach ($items_info as $id => $field_values) { | foreach ($items_info as $id => $field_values) { | ||
- | // | + | // Загружаем данные из базы по идентификатору записи |
$object->Load($id); | $object->Load($id); | ||
- | // | + | // Вставляем данные из запроса в объект. |
$object->SetFieldsFromHash($field_values); | $object->SetFieldsFromHash($field_values); | ||
$this->customProcessing($event, 'before'); | $this->customProcessing($event, 'before'); | ||
- | // | + | // Вызываем метод класса kDBItem. |
if ( $object->Update($id) ) { | if ( $object->Update($id) ) { | ||
$this->customProcessing($event, 'after'); | $this->customProcessing($event, 'after'); | ||
Line 229: | Line 229: | ||
</source> | </source> | ||
- | == | + | == См. также == |
* [[K4:Debugger|Debugger]] | * [[K4:Debugger|Debugger]] | ||
* [[K4:Formatters|Formatters]] | * [[K4:Formatters|Formatters]] | ||
* [[K4:Hooks|Hooks]] | * [[K4:Hooks|Hooks]] | ||
+ | |||
[[ru:{{FULLPAGENAME}}]] | [[ru:{{FULLPAGENAME}}]] | ||
[[en:KDBItem class]] | [[en:KDBItem class]] |
Current revision
| ||
---|---|---|
Статьи в этой категории | ||
|
Класс kDBItem
- один из базовых классов. Он предоставляет методы для работы с данными, относящимися к одной записи. Для связи объектов класса kDBItem
с прочими частями системы широко используются события. События происходящие во время выполнения методов класса kDBItem
можно перехватывать и выполнять необходимые действия. И наоборот - в системе имеются события, при наступлении которых выполняются методы класса kDBItem
.
Contents |
Загрузка из базы данных
Для загрузки из базы данных используется метод Load
. Метод возвращает значение true
в случае успешной загрузки данных и false
в прочих случаях. Если требуется проверить факт успешной загрузки из базы данных у отдельно взятого объекта, то можно использовать метод isLoaded
, который возвращает статус последней загрузки объекта. Условия загрузки данных задаются параметрами метода. Они могут быть простыми и сложными.
Простое условие загрузки получается если первым параметром передаётся значение одного из полей записи. Обычно это Integer
значение первичного ключа и тогда второй параметр не нужен. Если первым параметром передают значение другого поля, то вторым параметром должно быть название соответствующего поля.
// получаем ссылку на объект. Третий параметр предотвращает автоматическую загрузку данных в объект $user =& $this->Application->recallObject('u', null, Array('skip_autoload' => true)); /* @var $user kDBItem */ // загружаем данные объекта с ID = 23 $user->Load(23); // Тут могут быть всякие действия с объектом // Загружаем в объект данные пользователя по его адресу электронной почты $user->Load('erik@intechnic.com', 'Email');
Сложное условие загрузки получается если первым параметром передать массив, содержащий в качестве ключей имена полей а в качестве значений - значения, которые должны быть в соответствующих полях у загруженной записи.
$load_keys = Array( 'FirstName' => 'Erik', 'LastName' => 'Snarski' ); $user->Load($load_keys);
В итоге для загрузки данных будет использоваться SQL-запрос с условием следующего вида:
WHERE FirstName = 'Erik' AND LastName = 'Snarski'
Изменение данных
Для изменения данных одного поля используются методы SetField
и SetDBField
. SetDBField
записывает в поле значение параметра $value
в точности таким как оно передано. SetField
перед тем как записать значение, проверяет не назначен ли для поля форматер, и если назначен, то трансформирует значение поля методом Parse форматера.
// например в случае с форматированием даты $user->SetField('dob', '12/22/1971'); // результат операции будет эквивалентен $user->SetDBField('dob', 62197200);
Часто бывает удобно поменять данные сразу в нескольких полях. Например, переписать значения полей, которые пришли в результате submit-а формы. Для этого имеются функции SetFieldsFromHash
и SetDBFieldsFromHash
. Они принимают в качестве параметра массив, содержащий имена полей и значения для них. SetFieldsFromHash
, как вышеупомянутый SetField
, вызывает метод Parse
форматера для трансформации значений.
$field_values = Array( 'Email' => 'erik@intechnic.com', 'FirstName' => 'Erik', 'LastName' => 'Snarski', 'dob' => '12/22/1971' ); // обычно подобный массив получают из запроса конструкцией вида $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); list ($id, $field_values) = each($items_info); // и, наконец - запись данных в объект $user->SetFieldsFromHash($field_values);
Иногда, например при импорте данных, приходится один и тот же объект класса kDBItem
использовать многократно с разными наборами данных. В таких случаях может оказаться полезным метод Clear
, выставляющий всем полям значения по умолчанию и таким образом гарантирующий, что в каждом наборе будут только его собственные данные.
Определение изменившихся полей
Часто бывает полезно при изменении данных объекта также проверить какие именно поля менялись а какие - нет. Например, если какие-то действия есть смысл производить только при изменениях в определённых полях. Получить значение поля, которое было до изменения данных, сразу после загрузки данных из базы можно с помощью метода GetOriginalField
.
Проверка
Для проверки данных объекта применяется метод Validate
. Если в ходе выполнения метода обнаруживается несоответствие данных предъявляемым к ним требованиям, то в свойство FieldErrors
объекта, представляющее собой массив с именами полей в качестве ключей верхнего уровня, дописываются элементы второго уровня с ключами 'pseudo'
. Это коды ошибок, коротко описывающие сущность проблемы. Проверить есть ли в объекте такие коды можно методом HasErrors
.
Увидеть эти коды можно в отладчик, если открыть его после неудачной попытки сохранения записи.
[Name] = Array ( [pseudo] = required )
Иногда бывает необходимо не только считывать информацию об ошибках в полях, но и записывать её. Например, при написании функций проверки данных, специфических для конкретной задачи. Тогда, для обозначения ошибок в поле следует использовать предоставляемый классом kDBItem
метод SetError
.
Например, при редактировании данных в форме можно выбрать из списка категорию, к которой отностится объект. Однако, перед сохранением в базу данных хорошо бы убедиться что категория с таким номером действительно существует:
/** * * @param kEvent $event */ function OnBeforeItemUpdate(&$event) { $object =& $event->getObject(); /* @var $object kDBItem */ $category_id = $object->getDBField('CategoryId'); if (!$category_id) { // значение не задано - проверка не нужна return; } if ($category_id == $object->GetOriginalField('CategoryId')) { // значение не изменялось - проверка не нужна return; } $sql = 'SELECT COUNT(*) FROM ' . $this->Application->getUnitOption('c', 'TableName') . ' WHERE ' . $this->Application->getUnitOption('c', 'IDField') . ' = ' . $this->Conn->qstr($category_id); if (!$this->Conn->GetOne($sql)) { $object->SetError('CategoryId', 'invalid_category', 'la_error_InvalidCategory'); } }
Сохранение в базу данных
Для сохранения в базу данных используются методы Create
и Update
. Метод Create
предназначен для создания новой записи. Метод Update
- для изменения существующей записи. Оба эти метода по умолчанию, перед тем как записывать данные в базу, делают проверку методом Validate
, и производят запись только в случае если проверка пройдена успешно. В приведённом ниже примере делается импорт данных, правда, если данные создаваемого пользователя не пройдут проверку, то запись просто не будет создана.
// считываем данные из внешнего источника данных в массив $sql = 'SELECT username, password, email FROM user'; $users = $application->Conn->Query($sql); // создаём объект класса kDBItem $user =& $application->recallObject('u.-item', null, Array('skip-autoload' => true)); /* @var $user kDBItem*/ foreach ($users AS $user_data) { // выставляем значения по умолчанию вызовом метода Clear $user->Clear(); // выставляем значения полей импортируемой записи $user->SetDBField('Login', $user_data['username']); $user->SetDBField('Email', $user_data['email']); $user->SetDBField('Password', $user_data['password']); $user->SetDBField('VerifyPassword', $user_data['password']); // вызываем метод Create для создания записи в нашей системе $user->Create(); }
Использование событий
Четыре основных метода класса kDBItem
, способные непосредственно обращаться к базе данных - это методы:
-
Create
; -
Load
; -
Update
; -
Delete
.
Каждый из них в определённых ситуациях вызывает события, которые можно использовать для связи объекта класса kDBItem
с остальными частями системы. Все эти четыре метода могут в ходе своего выполнения вызывать события OnBeforeItem****
и OnAfterItem****
, где ****
- имя метода. Событие OnBeforeItem****
вызывается до обращения к базе данных. Событие OnAfterItem****
вызывается только после успешного обращения к базе данных.
Методы Create
и Update
могут вызывать ещё и событие OnAfterItemValidate
. Это происходит в случае, если производилась проверка данных объекта и эта проверка прошла успешно. Событие OnAfterItemValidate
вызывается до того как произойдёт обращение к базе данных. Ниже приведён пример того, как можно использовать событие OnAfterItemDelete
для выполнения дополнительных действий после успешного удаления записи.
function OnAfterItemDelete(&$event) { $object =& $event->getObject(); /* @var $object kDBItem */ // несмотря на то что запись в базе данных уже удалена, в памяти хранятся все её данные и // в зависимости от значения полей удалённой записи можно выполнять разные действия $topic_id = $object->GetDBField('TopicId'); if (!$topic_id) { // deleting non-existing post return ; } $post_helper =& $this->Application->recallObject('PostHelper'); /* @var $post_helper PostHelper */ // update posts count in topic $post_helper->updatePostCount($topic_id, -1); }
Основные события, использующие этот класс
Основные события, которые используют класс kDBItem
находятся в классе kDBEventHandler
.
Основные События | Аналоги, используемые при работе с временными таблицами | Используемые методы kDBItem |
---|---|---|
OnNew | OnPreCreate | setID(0)
|
OnCreate | OnPreSaveCreated | SetFieldsFromHash , Create , IsTempTable , setTempID , setID
|
OnUpdate | OnPreSave | Load , SetFieldsFromHash , Update , Load
|
Эти события как правило инициируются непосредственно с web-страницы, то есть, их имена передаются в запросе к серверу.
Событие OnNew
происходит при открытии формы ввода данных для создания новой записи.
-
OnCreate
- при отсылке данных на сервер для создания новой записи. -
OnUpdate
- при отсылке данных на сервер для модификации существующей записи.
function OnUpdate(&$event) { // Получаем ссылку на объект класса kDBItem. $object =& $event->getObject( Array('skip_autoload' => true) ); // Получаем данные из запроса. $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); if ($items_info) { foreach ($items_info as $id => $field_values) { // Загружаем данные из базы по идентификатору записи $object->Load($id); // Вставляем данные из запроса в объект. $object->SetFieldsFromHash($field_values); $this->customProcessing($event, 'before'); // Вызываем метод класса kDBItem. if ( $object->Update($id) ) { $this->customProcessing($event, 'after'); $event->status=erSUCCESS; } else { $event->status=erFAIL; $event->redirect=false; break; } } } $event->setRedirectParam('opener', 'u'); }