Привет и заранее спасибо за любую помощь!
Итак, проблема в том, что:
Я запускаю 2 разных процессора в плагине — я создаю пользователя (security / user / create) и создаю дополнительный информационный объект (мой пользовательский класс).
Проблема в том, что второй процессор всегда возвращает ответ первого. Если я удалю первый вызов процессора — это нормально. Проблема была та же, когда я пытался сделать то же самое во втором процессоре. Так код:
$response = $modx->runProcessor('security/user/create',$_REQUEST);
$resp=$modx->runProcessor('mgr/userdata/create',$_REQUEST,array("processors_path"=>$custom_path));
$modx->log(MODx::LOG_LEVEL_ERROR,print_r($resp->response,true));
Возвращает:
[2014-11-21 01:01:44] (ОШИБКА @ /index.php) Массив ( [успех] => [сообщение] => [всего] => 1 [errors] => Массив ( [0] => Массив ( [id] => имя пользователя [msg] => Это имя пользователя уже используется! ) ) [object] => Array ( ) )
Что это за колдовство и как заставить его работать?
Процессоры в MODX используют общие $modx->error
объект. В журнале мы имеем ошибку при создании пользователя. Второй процессор ловит его и не может быть успешно выполнен.
И все потому, что $ modx-> error является общей для всех процессоров в одном потоке. Самый простой способ — это использовать $modx->error->reset
после первого вызова процессора.
Но что, если мы пойдем глубже?
Вы хотите создать пользователя и связанные с ним данные? Хорошо. Но что, если создание пользователя будет успешным, а создание пользовательских данных не удастся? В итоге у нас есть противоречивые данные. Это настоящая головная боль.
Для меня лучший способ в создании собственного процессора, который расширяет security/user/create processor
, Есть особый beforeSave
метод. Таким образом, вы можете понять, когда создание пользователя прошло успешно, а затем создать свои собственные данные. Это действительно круто.
Пример (это процессор из одного из моих проектов, и речь идет не о создании пользователя. Но смысл тот же):
class modWebOrdersOrdersBulkComplectationCompleteProcessor extends modWebOrdersOrdersUpdateProcessor{public function beforeSave(){
$canSave = parent::beforeSave();
if($canSave !== true){
return $canSave;
}
// if we are here user creating has no errors.
// method for my additional logic. If i have errors there user won't be created
$ok = $this->transactionCreate();
if($ok !== true){
return $ok;
}return true;
}
protected function transactionCreate(){
// i'm usually works with related objects and use especially aggregates/composites relations. So if user has related data profile it will be saved when `save` method will be called for $this->object.
$_Transaction = $this->modx->newObject('BillingProductTransaction', array(
'createdby' => $this->modx->user->id,
'cause'=> 2
));
$this->object->Transaction = $_Transaction;
// but anyway you can run your subprocessor there. But there are some cons
// 1. $this->modx->error is common. if you make multiple runProcessor call there you can get some weird problems with logic. (error->reset() is hack not feature)
// 2. when your project architecture grows logic based on relations becomes more maintainable.
return true;
}
Вы уверены, что он доходит до второго процессора? Попытка регистрации обоих:
$response = $modx->runProcessor('security/user/create',$_REQUEST);
$modx->log(MODx::LOG_LEVEL_ERROR,print_r($response->response,true));
$resp=$modx->runProcessor('mgr/userdata/create',$_REQUEST,array("processors_path"=>$custom_path));
$modx->log(MODx::LOG_LEVEL_ERROR,print_r($resp->response,true));