Странное поведение процессора
Очень странная ситуация с процессором modUserUpdateProcessor — в расширяющем процессоре он подключается стандартным образом, привожу начало процессора:
Если определение класса заменить на
Вопрос получается простой: как сделать расширяющий для modUserUpdateProcessor, чтобы он работал корректно, и в нем можно было переопределять свойства/функции?
Надеюсь, что все понятно объяснил.
РЕШЕНИЕ:
В своем процессоре, который расширяет стандартный modUserUpdateProcessor, необходимо переопределить метод getInstance():
После этого все становится на свои места и корректно работает.
За решение спасибо Николаю.
ПРИЧИНА:
Просмотрев код функции modUserUpdateProcessor::getInstance(), стала понятна причина: новый процессор назывался chwUserUpdateProcessor, однако, стандартный код искал класс с названием chWorkerUpdateProcessor, которого, естественно, не обнаруживал.
Косяк с моей стороны, но не слишком очевидным он оказался.
МОРАЛЬ:
Названия классов нужно использовать максимально стандартизированные, иначе легко появляются ошибки.
<?php
require_once MODX_CORE_PATH . 'model/modx/processors/security/user/update.class.php';
class chwUserUpdateProcessor extends modUserUpdateProcessor {
public $classKey = 'chWorker';
public $permission = 'chworker_save';
/**
* {@inheritDoc}
* @return boolean|string
*/
public function initialize() {
exit ('PERM::::: '.$this->permission. ' ::::::RESULT::::: '.$this->modx->hasPermission($this->permission));
return parent::initialize();
}
Вызывается этот процессор тоже вполне обычно:$response = $this->modx->runProcessor('web/user/update',$userData, array('processors_path' => $this->config['processorsPath']));
Но! chwUserUpdateProcessor как файл вызывается, а отрабатывает modUserUpdateProcessor. Видно это простейшим образом: вместо обрыва выполнения на операторе exit() происходит проверка прав с отрицательным результатом и возвратом json. Если определение класса заменить на
class chwUserUpdateProcessor extends modObjectUpdateProcessor {
, но оставить подключение файла, все равно отработает modUserUpdateProcessor. И только если убрать подключение файла и оставить class chwUserUpdateProcessor extends modObjectUpdateProcessor {
, тогда все отработает и сохранится (или оборвется на exit(), если не убрать). Вопрос получается простой: как сделать расширяющий для modUserUpdateProcessor, чтобы он работал корректно, и в нем можно было переопределять свойства/функции?
Надеюсь, что все понятно объяснил.
РЕШЕНИЕ:
В своем процессоре, который расширяет стандартный modUserUpdateProcessor, необходимо переопределить метод getInstance():
public static function getInstance(modX &$modx,$className,$properties = array()) {
$className = __CLASS__;
$processor = new $className($modx,$properties);
return $processor;
}
После этого все становится на свои места и корректно работает.
За решение спасибо Николаю.
ПРИЧИНА:
Просмотрев код функции modUserUpdateProcessor::getInstance(), стала понятна причина: новый процессор назывался chwUserUpdateProcessor, однако, стандартный код искал класс с названием chWorkerUpdateProcessor, которого, естественно, не обнаруживал.
Косяк с моей стороны, но не слишком очевидным он оказался.
МОРАЛЬ:
Названия классов нужно использовать максимально стандартизированные, иначе легко появляются ошибки.
Комментарии: 10
Эксперименты продолжаются.
Сделал отдельный процессор
Что я делаю не так, почему именно обновление пользователя так криво работает?
Сделал отдельный процессор
<?php
exit('bla');
require_once MODX_CORE_PATH . 'model/modx/processors/security/user/update.class.php';
class chwUserUpdatetmpProcessor extends modUserUpdateProcessor {
public $classKey = 'chWorker';
public $permission = '';
public function checkPermissions() {
return true;
}
public function run() {
return true;
}
}
return 'chwUserUpdatetmpProcessor';
Работа всего MODX прекращается на строке exit('bla');, как и положено. Но если ее убрать, то получаю сообщение permission_denied, что явно говорит о выполнении процессора modUserUpdateProcessor и игнорировании chwUserUpdatetmpProcessor.Что я делаю не так, почему именно обновление пользователя так криво работает?
99.99% все дело в методе modUserUpdateProcessor::getInstance(). Он формирует маску имени класса процессора, и если класса такого нет, то вернет инстанс именно текущего (базового) процессора. Пропишите этот метод в своем классе, типа
public static function getInstance(modX &$modx,$className,$properties = array()) {
$className = __CLASS__;
$processor = new $className($modx,$properties);
return $processor;
}
Именно так и оказалось.
До такой глубины вряд ли хватило бы времени и терпения дойти.
Николай, спасибо!
До такой глубины вряд ли хватило бы времени и терпения дойти.
Николай, спасибо!
Всегда пожалуйста!
Просмотрев код функции modUserUpdateProcessor::getInstance(), стала понятна причина: новый процессор назывался chwUserUpdateProcessor, однако, стандартный код искал класс с названием chWorkerUpdateProcessor, которого, естественно, не обнаруживал.Если вы переименуете свой процессор в chWorkerUpdateProcessor, то свой метод getInstance уже прописывать не надо. Итак заработает (при условии, что класс уже был подгружен). К примеру, у меня в shopModx в самих классах сразу прописана подгрузка апдейт-процессоров. Минус тут конечно в том, что выполняется два лишних запроса к файлам (хотя относительно общего механизма — это капля в море). Но зато при выполнении апдейт-процессоров кастомный класс уже есть и на моих кастомных документах выполняются их процессоры.
Когда я дописывал заключительную часть вопроса, понял уже, что достаточно переименовать собственный процессор, после чего настанет вселенское счастье.
Подгрузка процессоров изменения — очень интересный прием. Возможно, возьму на вооружение. Спасибо за подсказку.
Подгрузка процессоров изменения — очень интересный прием. Возможно, возьму на вооружение. Спасибо за подсказку.
Пожалуйста.
Еще бывает что если путь к процессору указан через разные наклоны слэш то запустить то запуститься.
Но в функции $this->modx->runProcessor подумает что это разные процессор и попробует еще раз создать экземпляр, что приведет к ошибке:
Но может кому полезно будет
Но в функции $this->modx->runProcessor подумает что это разные процессор и попробует еще раз создать экземпляр, что приведет к ошибке:
Fatal error: Cannot declare class myMsProductUpdateProcessor, because the name is already in use in on line 11
Конечно это все к windows относится) Но может кому полезно будет
Путь 1
...\core\components\mspre\processors\mgr/product/update
Путь 2
...\core\components\mspre\processors\mgr\product/update
Очень интересное наблюдение, спасибо. Кому-то вполне может спасти много часов.
Хотя я всегда против веб-разработки на винде :)
Хотя я всегда против веб-разработки на винде :)
Я и сам против, просто пришлось использовать phpunit тесты, а на винде через phpStorm достаточно удобно это делать, нежеле на сервере упражняться с настройками.
Тоже часа два голову ломал что ему не нравится в это классе пока не залезе в runProcessor
Тоже часа два голову ломал что ему не нравится в это классе пока не залезе в runProcessor
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.