unarmedf 07 февраля 2016 1 0
Всем привет.

Понадобилось на одном из сайтов сделать периодическое обновление валют с сайта 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?
0 комментариев
Авторизуйтесь или зарегистрируйтесь (можно через соцсети ), чтобы оставлять комментарии.