Array ('self' => 'add|edit'), 'OnRun' => Array ('self' => 'add|edit'), ); $this->permMapping = array_merge($this->permMapping, $permissions); } /** * Does custom validation * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemValidate(kEvent $event) { parent::OnBeforeItemValidate($event); $object = $event->getObject(); /* @var $object kDBItem */ $event_string = $object->GetDBField('Event'); if ( !$event_string ) { return; } try { $this->Application->eventImplemented(new kEvent($event_string)); } catch (Exception $e) { $object->SetError('Event', 'invalid_event', '+' . $e->getMessage()); } } /** * [HOOK] Refreshes scheduled task list in database based on cached data from unit configs * * @param kEvent $event */ function OnRefresh($event) { $scheduled_tasks_from_cache = $this->Application->EventManager->getScheduledTasks(true); $object = $event->getObject( Array ('skip_autoload' => true) ); /* @var $object kDBItem */ $processed_ids = Array (); $scheduled_tasks_from_db = $this->Conn->Query($object->GetSelectSQL(), 'Name'); $cron_helper = $this->Application->recallObject('kCronHelper'); /* @var $cron_helper kCronHelper */ foreach ($scheduled_tasks_from_cache as $scheduled_task_name => $scheduled_task_params) { if ( !isset($scheduled_tasks_from_db[$scheduled_task_name]) ) { $fields_hash = Array ( 'Event' => $scheduled_task_params['Event'], 'Name' => $scheduled_task_name, 'Type' => ScheduledTask::TYPE_SYSTEM, 'Status' => isset($scheduled_task_params['Status']) ? $scheduled_task_params['Status'] : STATUS_ACTIVE, 'RunSchedule' => $scheduled_task_params['RunSchedule'], ); $object->Clear(); $object->SetDBFieldsFromHash($fields_hash); $cron_helper->load($object, 'RunSchedule'); $object->Create(); } else { $object->LoadFromHash( $scheduled_tasks_from_db[$scheduled_task_name] ); } $processed_ids[] = $object->GetID(); } // delete all non-processed scheduled tasks (ones, that were deleted from unit configs) $sql = 'SELECT ' . $object->IDField . ' FROM ' . $object->TableName . ' WHERE (Type = ' . ScheduledTask::TYPE_SYSTEM . ') AND (' . $object->IDField . ' NOT IN (' . implode(',', $processed_ids) . '))'; $delete_ids = $this->Conn->GetCol($sql); if ($delete_ids) { $temp_handler = $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler', Array ('parent_event' => $event)); /* @var $temp_handler kTempTablesHandler */ $temp_handler->DeleteItems($event->Prefix, $event->Special, $delete_ids); } $this->Application->removeObject($event->getPrefixSpecial()); } /** * Don't allow to delete other user's messages * * @param kEvent $event * @param string $type * @return void * @access protected */ protected function customProcessing(kEvent $event, $type) { if ( $event->Name == 'OnMassDelete' && $type == 'before' ) { if ( $this->Application->isDebugMode() ) { // allow to delete system scheduled tasks in debug mode return; } $ids = $event->getEventParam('ids'); if ( $ids ) { $config = $event->getUnitConfig(); $id_field = $config->getIDField(); $sql = 'SELECT ' . $id_field . ' FROM ' . $config->getTableName() . ' WHERE ' . $id_field . ' IN (' . implode(',', $ids) . ') AND Type <> ' . ScheduledTask::TYPE_SYSTEM; $event->setEventParam('ids', $this->Conn->GetCol($sql)); } } } /** * Cancels scheduled tasks, that are currently running * * @param kEvent $event */ function OnMassCancel($event) { $ids = $this->StoreSelectedIDs($event); if ($ids) { $object = $event->getObject( Array ('skip_autoload' => true) ); /* @var $object kDBItem */ foreach ($ids as $id) { $object->Load($id); if ($object->GetDBField('LastRunStatus') == ScheduledTask::LAST_RUN_RUNNING) { // only changes status, doesn't affect currency running scheduled tasks $object->SetDBField('LastRunStatus', ScheduledTask::LAST_RUN_FAILED); $object->Update(); } } } $this->clearSelectedIDs($event); } /** * Runs selected scheduled tasks * * @param kEvent $event */ function OnRun($event) { $ids = $this->StoreSelectedIDs($event); if ($ids) { $object = $event->getObject( Array ('skip_autoload' => true) ); /* @var $object kDBItem */ $where_clause = Array ( $object->TableName . '.' . $object->IDField . ' IN (' . implode(',', $ids) . ')', $object->TableName . '.Status = ' . STATUS_ACTIVE, $object->TableName . '.LastRunStatus <> ' . ScheduledTask::LAST_RUN_RUNNING, ); $sql = $object->GetSelectSQL() . ' WHERE (' . implode(') AND (', $where_clause) . ')'; $scheduled_tasks = $this->Conn->Query($sql); foreach ($scheduled_tasks as $scheduled_task_data) { $this->Application->EventManager->runScheduledTask($scheduled_task_data); } } $this->clearSelectedIDs($event); } /** * Loads schedule from database to virtual fields * * @param kEvent $event * @return void * @access protected */ protected function OnAfterItemLoad(kEvent $event) { parent::OnAfterItemLoad($event); $object = $event->getObject(); /* @var $object kDBItem */ $cron_helper = $this->Application->recallObject('kCronHelper'); /* @var $cron_helper kCronHelper */ $cron_helper->load($object, 'RunSchedule'); } /** * Validates schedule * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemCreate(kEvent $event) { parent::OnBeforeItemCreate($event); $this->_itemChanged($event); } /** * Validates schedule * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemUpdate(kEvent $event) { parent::OnBeforeItemUpdate($event); $this->_itemChanged($event); } /** * Validates schedule * * @param kEvent $event * @return void * @access protected */ protected function _itemChanged(kEvent $event) { $object = $event->getObject(); /* @var $object kDBItem */ $cron_helper = $this->Application->recallObject('kCronHelper'); /* @var $cron_helper kCronHelper */ if ( $cron_helper->validateAndSave($object, 'RunSchedule') && !$object->GetDBField('NextRunOn_date') ) { $next_run = $cron_helper->getMatch($object->GetDBField('RunSchedule')); $object->SetDBField('NextRunOn_date', $next_run); $object->SetDBField('NextRunOn_time', $next_run); } } /** * Creates schedule fields * * @param kEvent $event * @return void * @access protected */ protected function OnAfterConfigRead(kEvent $event) { parent::OnAfterConfigRead($event); $cron_helper = $this->Application->recallObject('kCronHelper'); /* @var $cron_helper kCronHelper */ $cron_helper->initUnit($event->Prefix, 'RunSchedule'); } }