7 февр. 2016 г., 16:54

Не срабатывает invokeEvent

Всем привет.
Понадобилось на одном из сайтов сделать периодическое обновление валют с сайта CBR. Создал процессор в shopkeeper3, в интерфейс запилил кнопку. По кнопке курсы обновляются. Дополнительно чтобы легко было работать с фильтрацией и сортировкой по ценам написал плагин, который обновляет в товарах цену в скрытом ТВ по курсу выбранному в товаре с пересчётам из цены введённой тем кто заполняет сайт. Чтобы сразу обновлять цены при обновлении курсов, создал новой системное событие OnSHKAfterSaveSettings, вызвал его в процессоре обновления валют, и подцепил на него плагин. Всё это прекрасно работает по кнопке(коды процессора и плагина выложу, если кому интересно). Проблемы начинаются, когда нужно как то обновлять это дело автоматом. С кроном связываться не захотелось, не удобно это, да и давно подумывал написать какой-то задачник, чтобы прямо из бэкэнда можно было ставить задачи по типу крона. Написал небольшой компонент с использованием для запуска задач stream_context_create c лимитом 0 и обычный file_get_contents к коннектору запускающему процессор записанный в задаче. Выглядит это так:
Функция в классе компонента запускающая задачу:
public function runTask(modTask $task,$params=array()) { if(!$task)return false; $pid = bin2hex(openssl_random_pseudo_bytes(16)); $task->set('pid',$pid); $task->set('state','process'); $task->set('last_run',time()); $task->save(); $params['pid']=$pid; $params['tid']=$task->id; switch($task->type) { case 'processor': { $params['action']='web/runprocessor'; $http_ctx = stream_context_create(array('http' => array('timeout' => 0 ))); @file_get_contents('http://'.$_SERVER['SERVER_NAME'].$this->config['connector']."?".http_build_query($params), 0, $http_ctx); return true; } case 'snippet': { if(empty($params['snippet']))return false; $snippet = $params['snippet']; $this->modx->runSnippet($snippet,$params); return true; } case 'event': { if(empty($params['event']))return false; $event = $params['event']; $this->modx->invokeEvent($event,$params); return true; } default:return false; } }
Коннектор компонента:
<?php ignore_user_abort(1); set_time_limit(120); require_once dirname(dirname(dirname(dirname(__FILE__)))).'/config.core.php'; require_once MODX_CORE_PATH.'config/'.MODX_CONFIG_KEY.'.inc.php'; define("MODX_REQP",false); $_REQUEST['ctx']='mgr'; require_once MODX_CONNECTORS_PATH.'index.php'; $_SERVER['HTTP_MODAUTH'] = $modx->site_id; $_REQUEST['HTTP_MODAUTH'] = $_SERVER['HTTP_MODAUTH']; $corePath = $modx->getOption('core_path').'components/scheduler/'; $modx->runProcessor($_REQUEST["action"],$_REQUEST,array( 'processors_path' => $corePath . 'processors/' ));
Процессор запускающий процессор задачи:
<?php class RunProcessorProcessor extends modProcessor { public function process() { $scriptProperties = $this->getProperties(); $Scheduler = $this->modx->getService('scheduler','Scheduler',$this->modx->getOption('core_path') . 'components/scheduler/model/'); $task = $this->modx->getObject('modTask',(int)$scriptProperties['tid']); if(!$task)return $this->abort('Задача не найдена'); if($task->type!='processor')return $this->abort('Неверный тип задачи'); if($task->pid!=$scriptProperties['pid'])return $this->abort('Неверный pid'); $params = json_decode($task->params,true); if(empty($params))return $this->abort('Не задан процессор'); $this->modx->runProcessor ( $params['processor'], array_merge($params,$scriptProperties), array('processors_path' => $params['path']) ); return array('success'=>true,'message'=>'','object'=>array()); } public function abort($message) { $this->setToLog($message); return array('success'=>false,'message'=>$message); } } return 'RunProcessorProcessor';
В результате нужный процессор(с обновлением валют) запускается, но вот событие OnSHKAfterSaveSettings не вызывается, точнее даже происходит какая-то ошибка(в логах нет), поскольку запись в лог после вызова $this->modx->invokeEvent('OnSHKAfterSaveSettings ') не проходит, а до вызова появляется.
Нашёл похожую проблему на одном из сайтов там ответом был вызов $modx->getSettings(), но мне он не помог. Почему ещё может не отрабатывать invokeEvent?

Добавить комментарий