Странное поведение процессора

Очень странная ситуация с процессором modUserUpdateProcessor — в расширяющем процессоре он подключается стандартным образом, привожу начало процессора:

<?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, которого, естественно, не обнаруживал.

Косяк с моей стороны, но не слишком очевидным он оказался.

 

МОРАЛЬ:

Названия классов нужно использовать максимально стандартизированные, иначе легко появляются ошибки.
Воеводский Михаил
07 августа 2015, 11:43
modx.pro
2 170
0

Комментарии: 10

Воеводский Михаил
07 августа 2015, 17:02
0
Эксперименты продолжаются.
Сделал отдельный процессор
<?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.

Что я делаю не так, почему именно обновление пользователя так криво работает?
    Fi1osof
    07 августа 2015, 18:09
    1
    +2
    99.99% все дело в методе modUserUpdateProcessor::getInstance(). Он формирует маску имени класса процессора, и если класса такого нет, то вернет инстанс именно текущего (базового) процессора. Пропишите этот метод в своем классе, типа
    public static function getInstance(modX &$modx,$className,$properties = array()) {
            $className = __CLASS__;
            $processor = new $className($modx,$properties);
            return $processor;
        }
      Воеводский Михаил
      07 августа 2015, 18:21
      0
      Именно так и оказалось.
      До такой глубины вряд ли хватило бы времени и терпения дойти.

      Николай, спасибо!
        Fi1osof
        07 августа 2015, 19:31
        0
        Всегда пожалуйста!
          Fi1osof
          07 августа 2015, 19:34
          +1
          Просмотрев код функции modUserUpdateProcessor::getInstance(), стала понятна причина: новый процессор назывался chwUserUpdateProcessor, однако, стандартный код искал класс с названием chWorkerUpdateProcessor, которого, естественно, не обнаруживал.
          Если вы переименуете свой процессор в chWorkerUpdateProcessor, то свой метод getInstance уже прописывать не надо. Итак заработает (при условии, что класс уже был подгружен). К примеру, у меня в shopModx в самих классах сразу прописана подгрузка апдейт-процессоров. Минус тут конечно в том, что выполняется два лишних запроса к файлам (хотя относительно общего механизма — это капля в море). Но зато при выполнении апдейт-процессоров кастомный класс уже есть и на моих кастомных документах выполняются их процессоры.
            Воеводский Михаил
            07 августа 2015, 21:16
            0
            Когда я дописывал заключительную часть вопроса, понял уже, что достаточно переименовать собственный процессор, после чего настанет вселенское счастье.

            Подгрузка процессоров изменения — очень интересный прием. Возможно, возьму на вооружение. Спасибо за подсказку.
              Fi1osof
              07 августа 2015, 21:44
              0
              Пожалуйста.
        Андрей Степаненко
        31 января 2019, 19:20
        +1
        Еще бывает что если путь к процессору указан через разные наклоны слэш то запустить то запуститься.
        Но в функции $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
          Воеводский Михаил
          01 февраля 2019, 10:22
          0
          Очень интересное наблюдение, спасибо. Кому-то вполне может спасти много часов.
          Хотя я всегда против веб-разработки на винде :)
            Андрей Степаненко
            01 февраля 2019, 10:27
            0
            Я и сам против, просто пришлось использовать phpunit тесты, а на винде через phpStorm достаточно удобно это делать, нежеле на сервере упражняться с настройками.
            Тоже часа два голову ломал что ему не нравится в это классе пока не залезе в runProcessor
          Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
          10