diff --git a/classes/modules/notify/Notify.class.php b/classes/modules/notify/Notify.class.php index 92771d18..7a5c25d4 100644 --- a/classes/modules/notify/Notify.class.php +++ b/classes/modules/notify/Notify.class.php @@ -53,7 +53,7 @@ class LsNotify extends Module { */ public function Init() { if (!class_exists('LsViewer')) { - require_once(Config::Get('path.root.engine')."/modules/sys_viewer/Viewer.class.php"); + require_once(Config::Get('path.root.engine')."/modules/viewer/Viewer.class.php"); } $this->oViewerLocal=new LsViewer(Engine::getInstance()); $this->oViewerLocal->Init(); @@ -581,5 +581,48 @@ class LsNotify extends Module { $this->aTask=array(); } } + + /** + * Получает массив заданий на публикацию из базы + * с указанным количественным ограничением (выборка FIFO) + * + * @param int $iLimit + * @return array + */ + public function GetTasksDelayed($iLimit=10) { + return ($aResult=$this->oMapper->GetTasks($iLimit)) + ? $aResult + : array(); + } + /** + * Отправляет на e-mail + * + * @param NotifyEntity_Task $oTask + */ + public function SendTask($oTask) { + $this->Mail_SetAdress($oTask->getUserMail(),$oTask->getUserLogin()); + $this->Mail_SetSubject($oTask->getNotifySubject()); + $this->Mail_SetBody($oTask->getNotifyText()); + $this->Mail_setHTML(); + $this->Mail_Send(); + } + /** + * Удаляет отложенное Notify-задание из базы + * + * @param NotifyEntity_Task $oTask + * @return bool + */ + public function DeleteTask($oTask) { + return $this->oMapper->DeleteTask($oTask); + } + /** + * Удаляет отложенные Notify-задания по списку идентификаторов + * + * @param array $aArrayId + * @return bool + */ + public function DeleteTaskByArrayId($aArrayId) { + return $this->oMapper->DeleteTaskByArrayId($aArrayId); + } } ?> \ No newline at end of file diff --git a/classes/modules/notify/mapper/Notify.mapper.class.php b/classes/modules/notify/mapper/Notify.mapper.class.php index cbf17b08..c7d07830 100644 --- a/classes/modules/notify/mapper/Notify.mapper.class.php +++ b/classes/modules/notify/mapper/Notify.mapper.class.php @@ -91,7 +91,17 @@ class Mapper_Notify extends Mapper { } public function GetTasks($iLimit) { - return array(); + $sql = "SELECT * + FROM ".Config::Get('db.table.notify_task')." + ORDER BY date_created ASC + LIMIT ?d"; + $aTasks=array(); + if ($aRows=$this->oDb->select($sql,$iLimit)) { + foreach ($aRows as $aTask) { + $aTasks[]=Engine::GetEntity('Notify_Task',$aTask); + } + } + return $aTasks; } } ?> \ No newline at end of file diff --git a/config/config.php b/config/config.php index 9f11c945..9a1982e4 100644 --- a/config/config.php +++ b/config/config.php @@ -184,6 +184,10 @@ $config['block']['blogs']['row'] = 10; // сколько записей выв */ $config['path']['root']['web'] = 'http://'.$_SERVER['HTTP_HOST']; // полный WEB адрес сайта $config['path']['root']['server'] = $_SERVER['DOCUMENT_ROOT']; // полный путь до сайта в файловой системе +/** + * Для CLI режима использовать + * $config['path']['root']['server'] = dirname(dirname(__FILE__)); // полный путь до сайта в файловой системе + */ $config['path']['root']['engine'] = $config['path']['root']['server'].'/engine'; // полный путь до сайта в файловой системе; $config['path']['root']['engine_lib'] = $config['path']['root']['web'].'/engine/lib'; // полный путь до сайта в файловой системе $config['path']['static']['root'] = $config['path']['root']['web']; // чтоб можно было статику засунуть на отдельный сервер @@ -298,6 +302,7 @@ $config['module']['lang']['delete_undefined'] = true; // Если устано // Модуль Notify $config['module']['notify']['delayed'] = false; // Указывает на необходимость использовать режим отложенной рассылки сообщений на email $config['module']['notify']['insert_single'] = false; // Если опция установлена в true, систему будет собирать записи заданий удаленной публикации, для вставки их в базу единым INSERT +$config['module']['notify']['per_process'] = 10; // Количество отложенных заданий, обрабатываемых одним крон-процессом // Какие модули должны быть загружены на старте $config['module']['autoLoad'] = array('Cache','Session','User', 'Lang', 'Message'); diff --git a/engine/classes/Cron.class.php b/engine/classes/Cron.class.php index 2c7aa565..0e2da992 100644 --- a/engine/classes/Cron.class.php +++ b/engine/classes/Cron.class.php @@ -43,13 +43,6 @@ class Cron extends Object { if(!empty($sLockFile)) { $this->oLockFile=fopen($sLockFile,'a'); - /** - * Если процесс заблокирован, выкидываем исключение - */ - if($this->isLock()) { - throw new Exception('Try to exec already run process'); - } - $this->setLock(); } } @@ -74,16 +67,12 @@ class Cron extends Object { * @param ( string|array ) $sFunction * @param array $aArgs */ - public function Exec($sFunction, $aArgs) { + public function Exec() { /** * Если выполнение процесса заблокирован, завершаемся */ if($this->isLock()) { - return; - } - - if(!function_exists($sFunction)||!is_callable($sFunction)) { - throw new Exception('Undefined function given'); + throw new Exception('Try to exec already run process'); } /** * Здесь мы реализуем дополнительную логику: @@ -91,12 +80,14 @@ class Cron extends Object { * буферизация вывода. */ ob_start(); - call_user_func_array($sFunction,$aArgs); + $this->Client(); /** * Получаем весь вывод функции. */ $sContent=ob_get_contents(); ob_end_clean(); + + return $sContent; } /** @@ -105,10 +96,15 @@ class Cron extends Object { public function Shutdown() { $this->unsetLock(); } - public function __destruct() { $this->Shutdown(); - return; + } + /** + * Клиентская функция будет переопределятся в наследниках класса + * для обеспечивания выполнения основного функционала. + */ + public function Client(){ + throw new Exception('Call undefined client function'); } } ?> \ No newline at end of file diff --git a/engine/classes/Engine.class.php b/engine/classes/Engine.class.php index c1b4d435..7eca3926 100644 --- a/engine/classes/Engine.class.php +++ b/engine/classes/Engine.class.php @@ -17,6 +17,7 @@ set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__)); require_once(Config::Get('path.root.engine').'/lib/internal/ProfilerSimple/Profiler.class.php'); + require_once("Object.class.php"); require_once("Block.class.php"); require_once("Hook.class.php"); diff --git a/include/cron/.htaccess b/include/cron/.htaccess new file mode 100644 index 00000000..2859d7f4 --- /dev/null +++ b/include/cron/.htaccess @@ -0,0 +1,2 @@ +Order Deny,Allow +Deny from all \ No newline at end of file diff --git a/include/cron/notify.php b/include/cron/notify.php new file mode 100644 index 00000000..31021e84 --- /dev/null +++ b/include/cron/notify.php @@ -0,0 +1,60 @@ +oEngine->Notify_GetTasksDelayed(Config::Get('module.notify.per_process')); + + if(empty($aNotifyTasks)) { + print PHP_EOL."No tasks are found."; + return; + } + /** + * Последовательно загружаем задания на публикацию + */ + $aArrayId=array(); + foreach ($aNotifyTasks as $oTask) { + $this->oEngine->Notify_SendTask($oTask); + $aArrayId[]=$oTask->getTaskId(); + } + print PHP_EOL."Send notify: ".count($aArrayId); + /** + * Удаляем отработанные задания + */ + $this->oEngine->Notify_DeleteTaskByArrayId($aArrayId); + } +} + +$sLockFilePath=Config::Get('sys.cache.dir').'notify.lock'; +/** + * Создаем объект крон-процесса, + * передавая параметром путь к лок-файлу + */ +$app=new NotifyCron($sLockFilePath); +print $app->Exec(); +?> \ No newline at end of file