added cron job manager for service jobs and scheduler jobs
This commit is contained in:
@@ -101,7 +101,10 @@ class Application
|
||||
{
|
||||
$auth = $this->getAuth();
|
||||
$auth->useNoAuth();
|
||||
// TODO cron manager
|
||||
|
||||
$cronManager = new \Espo\Core\CronManager($this->container);
|
||||
|
||||
$cronManager->run();
|
||||
}
|
||||
|
||||
protected function routeHooks()
|
||||
|
||||
@@ -175,6 +175,15 @@ class Container
|
||||
$this->get('entityManager')
|
||||
);
|
||||
}
|
||||
|
||||
private function loadClassMerger()
|
||||
{
|
||||
return new \Espo\Core\Utils\File\ClassMerger(
|
||||
$this->get('fileManager'),
|
||||
$this->get('config'),
|
||||
$this->get('metadata')
|
||||
);
|
||||
}
|
||||
|
||||
public function setUser($user)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace Espo\Core\Cron;
|
||||
|
||||
use Espo\Core\Exceptions\NotFound,
|
||||
Espo\Core\Utils\Util;
|
||||
|
||||
class ScheduledJob
|
||||
{
|
||||
private $container;
|
||||
|
||||
protected $data = null;
|
||||
|
||||
protected $cacheFile = 'data/cache/application/jobs.php';
|
||||
|
||||
protected $allowedMethod = 'run';
|
||||
|
||||
/**
|
||||
* @var array - path to cron job files
|
||||
*/
|
||||
private $paths = array(
|
||||
'corePath' => 'application/Espo/Jobs',
|
||||
'modulePath' => 'application/Espo/Modules/{*}/Jobs',
|
||||
'customPath' => 'application/Espo/Custom/Jobs',
|
||||
);
|
||||
|
||||
|
||||
public function __construct(\Espo\Core\Container $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
protected function getContainer()
|
||||
{
|
||||
return $this->container;
|
||||
}
|
||||
|
||||
protected function getEntityManager()
|
||||
{
|
||||
return $this->container->get('entityManager');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public function run(array $job)
|
||||
{
|
||||
$jobName = $job['method'];
|
||||
|
||||
$className = $this->getClassName($jobName);
|
||||
if ($className === false) {
|
||||
throw new NotFound();
|
||||
}
|
||||
|
||||
$jobClass = new $className($this->container);
|
||||
$method = $this->allowedMethod;
|
||||
|
||||
$jobClass->$method();
|
||||
}
|
||||
|
||||
|
||||
protected function getClassName($name)
|
||||
{
|
||||
$name = Util::normilizeClassName($name);
|
||||
|
||||
if (!isset($this->data)) {
|
||||
$this->init();
|
||||
}
|
||||
|
||||
$name = ucfirst($name);
|
||||
if (isset($this->data[$name])) {
|
||||
return $this->data[$name];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load scheduler classes. It loads from ...Jobs, ex. \Espo\Jobs
|
||||
* @return null
|
||||
*/
|
||||
protected function init()
|
||||
{
|
||||
$classMerger = $this->getContainer()->get('classMerger');
|
||||
$classMerger->setAllowedMethods( array($this->allowedMethod) );
|
||||
$this->data = $classMerger->getData($this->cacheFile, $this->paths);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Espo\Core\Cron;
|
||||
|
||||
use Espo\Core\Utils\Json,
|
||||
Espo\Core\Exceptions\NotFound;
|
||||
|
||||
class Service
|
||||
{
|
||||
private $serviceFactory;
|
||||
|
||||
public function __construct(\Espo\Core\ServiceFactory $serviceFactory)
|
||||
{
|
||||
$this->serviceFactory = $serviceFactory;
|
||||
}
|
||||
|
||||
protected function getServiceFactory()
|
||||
{
|
||||
return $this->serviceFactory;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function run($job)
|
||||
{
|
||||
$serviceName = $job['service_name'];
|
||||
|
||||
if (!$this->getServiceFactory()->checkExists($serviceName)) {
|
||||
throw new NotFound();
|
||||
}
|
||||
|
||||
$service = $this->getServiceFactory()->create($serviceName);
|
||||
$serviceMethod = $job['method'];
|
||||
|
||||
if (!method_exists($service, $serviceMethod)) {
|
||||
throw new NotFound();
|
||||
}
|
||||
|
||||
$data = $job['data'];
|
||||
if (Json::isJSON($data)) {
|
||||
$data = Json::decode($data, true);
|
||||
}
|
||||
|
||||
$service->$serviceMethod($data);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
<?php
|
||||
|
||||
namespace Espo\Core;
|
||||
|
||||
class CronManager
|
||||
{
|
||||
private $container;
|
||||
private $config;
|
||||
private $fileManager;
|
||||
|
||||
private $scheduledJobCron;
|
||||
private $serviceCron;
|
||||
|
||||
private $jobFactory;
|
||||
private $scheduledJobFactory;
|
||||
|
||||
protected $lastRunTime = 'data/cache/application/cronLastRunTime.php';
|
||||
|
||||
|
||||
public function __construct(\Espo\Core\Container $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
|
||||
$this->config = $this->container->get('config');
|
||||
$this->fileManager = $this->container->get('fileManager');
|
||||
|
||||
$this->scheduledJobCron = new \Espo\Core\Cron\ScheduledJob( $this->container );
|
||||
$this->serviceCron = new \Espo\Core\Cron\Service( $this->container->get('serviceFactory') );
|
||||
|
||||
$this->jobFactory = $this->container->get('serviceFactory')->create('job');
|
||||
$this->scheduledJobFactory = $this->container->get('serviceFactory')->create('scheduledJob');
|
||||
}
|
||||
|
||||
protected function getContainer()
|
||||
{
|
||||
return $this->container;
|
||||
}
|
||||
|
||||
protected function getConfig()
|
||||
{
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
protected function getFileManager()
|
||||
{
|
||||
return $this->fileManager;
|
||||
}
|
||||
|
||||
protected function getJobFactory()
|
||||
{
|
||||
return $this->jobFactory;
|
||||
}
|
||||
|
||||
protected function getScheduledJobFactory()
|
||||
{
|
||||
return $this->scheduledJobFactory;
|
||||
}
|
||||
|
||||
protected function getScheduledJobCron()
|
||||
{
|
||||
return $this->scheduledJobCron;
|
||||
}
|
||||
|
||||
protected function getServiceCron()
|
||||
{
|
||||
return $this->serviceCron;
|
||||
}
|
||||
|
||||
|
||||
protected function getLastRunTime()
|
||||
{
|
||||
$lastRunTime = $this->getFileManager()->getContent($this->lastRunTime);
|
||||
if (!is_int($lastRunTime)) {
|
||||
$lastRunTime = time() - (intval($this->getConfig()->get('cron.minExecutionTime')) + 60);
|
||||
}
|
||||
|
||||
return $lastRunTime;
|
||||
}
|
||||
|
||||
protected function setLastRunTime($time)
|
||||
{
|
||||
return $this->getFileManager()->setContentPHP($time, $this->lastRunTime);
|
||||
}
|
||||
|
||||
protected function checkLastRunTime()
|
||||
{
|
||||
$currentTime = time();
|
||||
$lastRunTime = $this->getLastRunTime();
|
||||
$minTime = $this->getConfig()->get('cron.minExecutionTime');
|
||||
|
||||
if ($currentTime > ($lastRunTime + $minTime) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public function run()
|
||||
{
|
||||
if (!$this->checkLastRunTime()) {
|
||||
$GLOBALS['log']->add('INFO', 'Cron Manager: Stop cron running, too frequency execution');
|
||||
return; //stop cron running, too frequency execution
|
||||
}
|
||||
|
||||
$this->setLastRunTime(time());
|
||||
|
||||
//Check scheduled jobs and create related jobs
|
||||
$this->createJobsFromScheduledJobs();
|
||||
|
||||
|
||||
$pendingJobs = $this->getJobFactory()->getPendingJobs();
|
||||
|
||||
foreach ($pendingJobs as $job) {
|
||||
|
||||
$this->getJobFactory()->updateEntity($job['id'], array(
|
||||
'status' => 'Running',
|
||||
));
|
||||
|
||||
$isSuccess = true;
|
||||
|
||||
try {
|
||||
if (!empty($job['scheduled_job_id'])) {
|
||||
$this->getScheduledJobCron()->run($job);
|
||||
} else {
|
||||
$this->getServiceCron()->run($job);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$isSuccess = false;
|
||||
$GLOBALS['log']->add('INFO', 'Failed job running, job ['.$job['id'].']. Error Details: '.$e->getMessage());
|
||||
}
|
||||
|
||||
$status = $isSuccess ? 'Success' : 'Failed';
|
||||
|
||||
$this->getJobFactory()->updateEntity($job['id'], array(
|
||||
'status' => $status,
|
||||
));
|
||||
|
||||
//set status in the schedulerJobLog
|
||||
if (!empty($job['scheduled_job_id'])) {
|
||||
$this->getScheduledJobFactory()->addLogRecord($job['scheduled_job_id'], $status);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check scheduled jobs and create related jobs
|
||||
* @return array List of created Jobs
|
||||
*/
|
||||
protected function createJobsFromScheduledJobs()
|
||||
{
|
||||
$activeScheduledJobs = $this->getScheduledJobFactory()->getActiveJobs();
|
||||
|
||||
$createdJobs = array();
|
||||
foreach ($activeScheduledJobs as $scheduledJob) {
|
||||
|
||||
$scheduling = $scheduledJob['scheduling'];
|
||||
|
||||
$cronExpression = \Cron\CronExpression::factory($scheduling);
|
||||
|
||||
try {
|
||||
//$nextDate = $cronExpression->getNextRunDate()->format('Y-m-d H:i:s');
|
||||
$prevDate = $cronExpression->getPreviousRunDate()->format('Y-m-d H:i:s');
|
||||
} catch (\Exception $e) {
|
||||
$GLOBALS['log']->add('Exception', 'ScheduledJob ['.$scheduledJob['id'].']: CronExpression - Impossible CRON expression ['.$scheduling.']');
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($cronExpression->isDue()) {
|
||||
$prevDate = date('Y-m-d H:i:00');
|
||||
}
|
||||
|
||||
$existsJob = $this->getJobFactory()->getJobByScheduledJob($scheduledJob['id'], $prevDate);
|
||||
|
||||
if (!isset($existsJob) || empty($existsJob)) {
|
||||
//create a job
|
||||
$data = array(
|
||||
'name' => $scheduledJob['name'],
|
||||
'status' => 'Pending',
|
||||
'scheduledJobId' => $scheduledJob['id'],
|
||||
'executeTime' => $prevDate,
|
||||
'method' => $scheduledJob['job'],
|
||||
);
|
||||
$createdJobs[] = $this->getJobFactory()->createEntity($data);
|
||||
}
|
||||
}
|
||||
|
||||
return $createdJobs;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -16,7 +16,7 @@ class EntryPointManager
|
||||
|
||||
protected $cacheFile = 'data/cache/application/entryPoints.php';
|
||||
|
||||
protected $allowMethods = array(
|
||||
protected $allowedMethods = array(
|
||||
'run',
|
||||
);
|
||||
|
||||
@@ -85,50 +85,11 @@ class EntryPointManager
|
||||
|
||||
protected function init()
|
||||
{
|
||||
$config = $this->getContainer()->get('config');
|
||||
|
||||
if (file_exists($this->cacheFile) && $config->get('useCache')) {
|
||||
$this->data = $this->getFileManager()->getContent($this->cacheFile);
|
||||
} else {
|
||||
$this->data = $this->getClassNameHash(array($this->paths['corePath'], $this->paths['customPath']) );
|
||||
foreach ($this->getContainer()->get('metadata')->getModuleList() as $moduleName) {
|
||||
$path = str_replace('{*}', $moduleName, $this->paths['modulePath']);
|
||||
|
||||
$this->data = array_merge($this->data, $this->getClassNameHash(array($path)));
|
||||
}
|
||||
if ($config->get('useCache')) {
|
||||
$result = $this->getFileManager()->setContentPHP($this->data, $this->cacheFile);
|
||||
if ($result == false) {
|
||||
throw new \Espo\Core\Exceptions\Error();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO delegate to another class
|
||||
protected function getClassNameHash(array $dirs)
|
||||
{
|
||||
$data = array();
|
||||
foreach ($dirs as $dir) {
|
||||
if (file_exists($dir)) {
|
||||
$fileList = $this->getFileManager()->getFileList($dir, false, '\.php$', 'file');
|
||||
foreach ($fileList as $file) {
|
||||
$filePath = Util::concatPath($dir, $file);
|
||||
$className = Util::getClassName($filePath);
|
||||
$fileName = $this->getFileManager()->getFileName($filePath);
|
||||
$fileName = ucfirst($fileName);
|
||||
|
||||
foreach ($this->allowMethods as $methodName) {
|
||||
if (method_exists($className, $methodName)) {
|
||||
$data[$fileName] = $className;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
$classMerger = $this->getContainer()->get('classMerger');
|
||||
$classMerger->setAllowedMethods($this->allowedMethods);
|
||||
$this->data = $classMerger->getData($this->cacheFile, $this->paths);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Espo\Core\Jobs;
|
||||
|
||||
use \Espo\Core\Container;
|
||||
|
||||
|
||||
abstract class Base
|
||||
{
|
||||
private $container;
|
||||
|
||||
protected function getContainer()
|
||||
{
|
||||
return $this->container;
|
||||
}
|
||||
|
||||
protected function getEntityManager()
|
||||
{
|
||||
return $this->getContainer()->get('entityManager');
|
||||
}
|
||||
|
||||
protected function getServiceFactory()
|
||||
{
|
||||
return $this->getContainer()->get('serviceFactory');
|
||||
}
|
||||
|
||||
protected function getConfig()
|
||||
{
|
||||
return $this->getContainer()->get('config');
|
||||
}
|
||||
|
||||
protected function getMetadata()
|
||||
{
|
||||
return $this->getContainer()->get('metadata');
|
||||
}
|
||||
|
||||
public function __construct(Container $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
abstract public function run();
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace Espo\Core\Utils\File;
|
||||
|
||||
use \Espo\Core\Utils\Util;
|
||||
|
||||
class ClassMerger
|
||||
{
|
||||
private $fileManager;
|
||||
|
||||
private $config;
|
||||
|
||||
private $metadata;
|
||||
|
||||
protected $cacheFile = null;
|
||||
|
||||
protected $allowedMethods = array(
|
||||
'run',
|
||||
);
|
||||
|
||||
public function __construct(\Espo\Core\Utils\File\Manager $fileManager, \Espo\Core\Utils\Config $config, \Espo\Core\Utils\Metadata $metadata)
|
||||
{
|
||||
$this->fileManager = $fileManager;
|
||||
$this->config = $config;
|
||||
$this->metadata = $metadata;
|
||||
}
|
||||
|
||||
protected function getFileManager()
|
||||
{
|
||||
return $this->fileManager;
|
||||
}
|
||||
|
||||
protected function getConfig()
|
||||
{
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
protected function getMetadata()
|
||||
{
|
||||
return $this->metadata;
|
||||
}
|
||||
|
||||
public function setAllowedMethods(array $methods)
|
||||
{
|
||||
$this->allowedMethods = $methods;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return path data of classes
|
||||
* @param string $cacheFile full path for a cache file, ex. data/cache/application/entryPoints.php
|
||||
* @param array $paths in format array(
|
||||
* 'corePath' => '',
|
||||
* 'modulePath' => '',
|
||||
* 'customPath' => '',
|
||||
* );
|
||||
* @return array
|
||||
*/
|
||||
public function getData($cacheFile, array $paths)
|
||||
{
|
||||
$data = null;
|
||||
|
||||
if (file_exists($cacheFile) && $this->getConfig()->get('useCache')) {
|
||||
$data = $this->getFileManager()->getContent($cacheFile);
|
||||
} else {
|
||||
$data = $this->getClassNameHash(array($paths['corePath'], $paths['customPath']) );
|
||||
foreach ($this->getMetadata()->getModuleList() as $moduleName) {
|
||||
$path = str_replace('{*}', $moduleName, $paths['modulePath']);
|
||||
|
||||
$data = array_merge($data, $this->getClassNameHash(array($path)));
|
||||
}
|
||||
if ($this->getConfig()->get('useCache')) {
|
||||
$result = $this->getFileManager()->setContentPHP($data, $cacheFile);
|
||||
if ($result == false) {
|
||||
throw new \Espo\Core\Exceptions\Error();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
protected function getClassNameHash(array $dirs)
|
||||
{
|
||||
$data = array();
|
||||
foreach ($dirs as $dir) {
|
||||
if (file_exists($dir)) {
|
||||
$fileList = $this->getFileManager()->getFileList($dir, false, '\.php$', 'file');
|
||||
foreach ($fileList as $file) {
|
||||
$filePath = Util::concatPath($dir, $file);
|
||||
$className = Util::getClassName($filePath);
|
||||
$fileName = $this->getFileManager()->getFileName($filePath);
|
||||
$fileName = ucfirst($fileName);
|
||||
|
||||
foreach ($this->allowedMethods as $methodName) {
|
||||
if (method_exists($className, $methodName)) {
|
||||
$data[$fileName] = $className;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,12 @@ return array (
|
||||
'dateFormat' => 'MM/DD/YYYY',
|
||||
'timeFormat' => 'HH:mm',
|
||||
|
||||
'cron' => array(
|
||||
'maxJobNumber' => 15, /*Max number of jobs per one execution*/
|
||||
'jobPeriod' => 7800, /*Period for jobs, ex. if cron executed at 15:35, it will execute all pending jobs for times from 14:05 to 15:35*/
|
||||
'minExecutionTime' => 50, /*to avoid too frequency execution*/
|
||||
),
|
||||
|
||||
'systemUser' => array(
|
||||
'id' => 'system',
|
||||
'userName' => 'system',
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Espo\Entities;
|
||||
|
||||
class Job extends \Espo\Core\ORM\Entity
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Espo\Jobs;
|
||||
|
||||
use \Espo\Core\Exceptions;
|
||||
|
||||
|
||||
class CheckInboundEmails extends \Espo\Core\Jobs\Base
|
||||
{
|
||||
|
||||
public function run()
|
||||
{
|
||||
//some code
|
||||
//for problems use Exceptions. In this case job status will be "Failed", otherwise "Success"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"fields": {
|
||||
"name": {
|
||||
"type": "varchar",
|
||||
"required": true
|
||||
},
|
||||
"status": {
|
||||
"type": "enum",
|
||||
"options": ["Pending", "Running", "Success", "Failed"],
|
||||
"default": "Pending"
|
||||
},
|
||||
"executeTime": {
|
||||
"type": "datetime",
|
||||
"required": true
|
||||
},
|
||||
"serviceName": {
|
||||
"type": "varchar",
|
||||
"required": true,
|
||||
"len":100
|
||||
},
|
||||
"method": {
|
||||
"type": "varchar",
|
||||
"required": true,
|
||||
"len":100
|
||||
},
|
||||
"data": {
|
||||
"type": "text"
|
||||
},
|
||||
"scheduledJob": {
|
||||
"type": "link"
|
||||
},
|
||||
"createdAt": {
|
||||
"type": "datetime",
|
||||
"readOnly": true
|
||||
},
|
||||
"modifiedAt": {
|
||||
"type": "datetime",
|
||||
"readOnly": true
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
"scheduledJob": {
|
||||
"type": "belongsTo",
|
||||
"entity": "ScheduledJob"
|
||||
}
|
||||
},
|
||||
"collection": {
|
||||
"sortBy": "createdAt",
|
||||
"asc": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"entity": true,
|
||||
"layouts": false,
|
||||
"tab": false,
|
||||
"acl": false,
|
||||
"customizable":false
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace Espo\Services;
|
||||
|
||||
use \PDO;
|
||||
|
||||
class Job extends Record
|
||||
{
|
||||
|
||||
public function getPendingJobs()
|
||||
{
|
||||
$jobConfigs = (array) $this->getConfig()->get('cron');
|
||||
|
||||
$currentTime = time();
|
||||
$periodTime = $currentTime - intval($jobConfigs['jobPeriod']);
|
||||
$limit = empty($jobConfigs['maxJobNumber']) ? '' : 'LIMIT '.$jobConfigs['maxJobNumber'];
|
||||
|
||||
$query = "SELECT * FROM job WHERE
|
||||
`status` = 'Pending'
|
||||
AND execute_time BETWEEN '".date('Y-m-d H:i:s', $periodTime)."' AND '".date('Y-m-d H:i:s', $currentTime)."'
|
||||
ORDER BY execute_time DESC ".$limit;
|
||||
|
||||
$pdo = $this->getEntityManager()->getPDO();
|
||||
$sth = $pdo->prepare($query);
|
||||
$sth->execute();
|
||||
|
||||
$rows = $sth->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$list = array();
|
||||
foreach ($rows as $row) {
|
||||
$list[] = $row;
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
public function getJobByScheduledJob($scheduledJobId, $date)
|
||||
{
|
||||
$query = "SELECT * FROM job WHERE
|
||||
scheduled_job_id = '".$scheduledJobId."'
|
||||
AND execute_time = '".$date."'
|
||||
LIMIT 1";
|
||||
|
||||
$pdo = $this->getEntityManager()->getPDO();
|
||||
$sth = $pdo->prepare($query);
|
||||
$sth->execute();
|
||||
|
||||
$scheduledJob = $sth->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
return $scheduledJob;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//todo remove, used for tests
|
||||
public function testMethod($data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//todo remove, used for tests
|
||||
public function testFailed($data)
|
||||
{
|
||||
throw new \Espo\Core\Exceptions\Error();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace Espo\Services;
|
||||
|
||||
use \PDO;
|
||||
|
||||
class ScheduledJob extends \Espo\Services\Record
|
||||
{
|
||||
|
||||
public function getActiveJobs()
|
||||
{
|
||||
$query = "SELECT * FROM scheduled_job WHERE
|
||||
`status` = 'Active'
|
||||
AND deleted = 0";
|
||||
|
||||
$pdo = $this->getEntityManager()->getPDO();
|
||||
$sth = $pdo->prepare($query);
|
||||
$sth->execute();
|
||||
|
||||
$rows = $sth->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$list = array();
|
||||
foreach ($rows as $row) {
|
||||
$list[] = $row;
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add record to ScheduledJobLogRecord about executed job
|
||||
* @param string $scheduledJobId
|
||||
* @param string $status
|
||||
*
|
||||
* @return string Id of created ScheduledJobLogRecord
|
||||
*/
|
||||
public function addLogRecord($scheduledJobId, $status)
|
||||
{
|
||||
$lastRun = date('Y-m-d H:i:s');
|
||||
|
||||
$entityManager = $this->getEntityManager();
|
||||
|
||||
$scheduledJob = $entityManager->getEntity('ScheduledJob', $scheduledJobId);
|
||||
$scheduledJob->set('lastRun', $lastRun);
|
||||
$entityManager->saveEntity($scheduledJob);
|
||||
|
||||
$scheduledJobLog = $entityManager->getEntity('ScheduledJobLogRecord');
|
||||
$scheduledJobLog->set(array(
|
||||
'scheduledJobId' => $scheduledJobId,
|
||||
'name' => $scheduledJob->get('name'),
|
||||
'status' => $status,
|
||||
'executionTime' => $lastRun,
|
||||
));
|
||||
$scheduledJobLogId = $entityManager->saveEntity($scheduledJobLog);
|
||||
//$entityManager->getRepository('ScheduledJobLogRecord')->relate($scheduledJobLog, 'scheduledJob', $scheduledJob);
|
||||
|
||||
return $scheduledJobLogId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ class Auth extends \Slim\Middleware
|
||||
if (!empty($routes[0])) {
|
||||
$routeConditions = $routes[0]->getConditions();
|
||||
if (isset($routeConditions['auth']) && $routeConditions['auth'] === false) {
|
||||
//$this->container->setUser(new \Espo\Entities\User());
|
||||
$this->container->setUser($this->entityManager->getRepository('User'));
|
||||
$this->next->call();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace tests\Espo\Core;
|
||||
|
||||
use tests\ReflectionHelper;
|
||||
|
||||
|
||||
class CronManagerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $object;
|
||||
|
||||
protected $objects;
|
||||
|
||||
protected $filesPath= 'tests/testData/EntryPoints';
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->objects['container'] = $this->getMockBuilder('\Espo\Core\Container')->disableOriginalConstructor()->getMock();
|
||||
|
||||
$this->objects['serviceFactory'] = $this->getMockBuilder('\Espo\Core\ServiceFactory')->disableOriginalConstructor()->getMock();
|
||||
$this->objects['config'] = $this->getMockBuilder('\Espo\Core\Utils\Config')->disableOriginalConstructor()->getMock();
|
||||
$this->objects['fileManager'] = $this->getMockBuilder('\Espo\Core\Utils\File\Manager')->disableOriginalConstructor()->getMock();
|
||||
|
||||
|
||||
$map = array(
|
||||
array('config', $this->objects['config']),
|
||||
array('fileManager', $this->objects['fileManager']),
|
||||
array('serviceFactory', $this->objects['serviceFactory']),
|
||||
);
|
||||
|
||||
$this->objects['container']
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->will($this->returnValueMap($map));
|
||||
|
||||
$this->object = new \Espo\Core\CronManager( $this->objects['container'] );
|
||||
|
||||
$this->reflection = new ReflectionHelper($this->object);
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
$this->object = NULL;
|
||||
}
|
||||
|
||||
|
||||
function testCheckLastRunTimeFileDoesnotExist()
|
||||
{
|
||||
$this->objects['fileManager']
|
||||
->expects($this->once())
|
||||
->method('getContent')
|
||||
->will($this->returnValue(false));
|
||||
|
||||
$this->objects['config']
|
||||
->expects($this->exactly(2))
|
||||
->method('get')
|
||||
->will($this->returnValue(50));
|
||||
|
||||
$this->assertTrue( $this->reflection->invokeMethod('checkLastRunTime', array()) );
|
||||
}
|
||||
|
||||
|
||||
function testCheckLastRunTime()
|
||||
{
|
||||
$this->objects['fileManager']
|
||||
->expects($this->once())
|
||||
->method('getContent')
|
||||
->will($this->returnValue(time()-60));
|
||||
|
||||
$this->objects['config']
|
||||
->expects($this->once())
|
||||
->method('get')
|
||||
->will($this->returnValue(50));
|
||||
|
||||
$this->assertTrue( $this->reflection->invokeMethod('checkLastRunTime', array()) );
|
||||
}
|
||||
|
||||
|
||||
function testCheckLastRunTimeTooFrequency()
|
||||
{
|
||||
$this->objects['fileManager']
|
||||
->expects($this->once())
|
||||
->method('getContent')
|
||||
->will($this->returnValue(time()-49));
|
||||
|
||||
$this->objects['config']
|
||||
->expects($this->once())
|
||||
->method('get')
|
||||
->will($this->returnValue(50));
|
||||
|
||||
$this->assertFalse( $this->reflection->invokeMethod('checkLastRunTime', array()) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -28,11 +28,7 @@ class EntryPointManagerTest extends \PHPUnit_Framework_TestCase
|
||||
$this->reflection->setProperty('paths', array(
|
||||
'corePath' => 'tests/testData/EntryPoints/Espo/EntryPoints',
|
||||
'modulePath' => 'tests/testData/EntryPoints/Espo/Modules/Crm/EntryPoints',
|
||||
));
|
||||
$this->reflection->setProperty('customPaths', array(
|
||||
'corePath' => '',
|
||||
'modulePath' => '',
|
||||
));
|
||||
));
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
@@ -40,24 +36,13 @@ class EntryPointManagerTest extends \PHPUnit_Framework_TestCase
|
||||
$this->object = NULL;
|
||||
}
|
||||
|
||||
|
||||
function testGetData()
|
||||
{
|
||||
$result = array(
|
||||
'Download' => '\tests\testData\EntryPoints\Espo\EntryPoints\Download',
|
||||
'Test' => '\tests\testData\EntryPoints\Espo\EntryPoints\Test',
|
||||
'InModule' => '\tests\testData\EntryPoints\Espo\Modules\Crm\EntryPoints\InModule'
|
||||
);
|
||||
$this->assertEquals( $result, $this->reflection->invokeMethod('getData', array($this->reflection->getProperty('paths'))) );
|
||||
}
|
||||
|
||||
function testGet()
|
||||
{
|
||||
$this->reflection->setProperty('data', array(
|
||||
'Test' => '\tests\testData\EntryPoints\Espo\EntryPoints\Test',
|
||||
));
|
||||
|
||||
$this->assertEquals('\tests\testData\EntryPoints\Espo\EntryPoints\Test', $this->reflection->invokeMethod('get', array('test')) );
|
||||
$this->assertEquals('\tests\testData\EntryPoints\Espo\EntryPoints\Test', $this->reflection->invokeMethod('getClassName', array('test')) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace tests\Espo\Core\Utils\File;
|
||||
|
||||
use tests\ReflectionHelper;
|
||||
|
||||
|
||||
class ClassMergerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $object;
|
||||
|
||||
protected $objects;
|
||||
|
||||
protected $reflection;
|
||||
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->objects['fileManager'] = new \Espo\Core\Utils\File\Manager( (object) array());
|
||||
$this->objects['config'] = $this->getMockBuilder('\Espo\Core\Utils\Config')->disableOriginalConstructor()->getMock();
|
||||
$this->objects['metadata'] = $this->getMockBuilder('\Espo\Core\Utils\Metadata')->disableOriginalConstructor()->getMock();
|
||||
|
||||
$this->object = new \Espo\Core\Utils\File\ClassMerger($this->objects['fileManager'], $this->objects['config'], $this->objects['metadata']);
|
||||
|
||||
$this->reflection = new ReflectionHelper($this->object);
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
$this->object = NULL;
|
||||
}
|
||||
|
||||
|
||||
function testGetClassNameHash()
|
||||
{
|
||||
$paths = array(
|
||||
'tests/testData/EntryPoints/Espo/EntryPoints',
|
||||
'tests/testData/EntryPoints/Espo/Modules/Crm/EntryPoints',
|
||||
);
|
||||
|
||||
$result = array(
|
||||
'Download' => '\tests\testData\EntryPoints\Espo\EntryPoints\Download',
|
||||
'Test' => '\tests\testData\EntryPoints\Espo\EntryPoints\Test',
|
||||
'InModule' => '\tests\testData\EntryPoints\Espo\Modules\Crm\EntryPoints\InModule'
|
||||
);
|
||||
$this->assertEquals( $result, $this->reflection->invokeMethod('getClassNameHash', array($paths)) );
|
||||
}
|
||||
|
||||
|
||||
function testGetDataWithCache()
|
||||
{
|
||||
$this->objects['config']
|
||||
->expects($this->once())
|
||||
->method('get')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
$cacheFile = 'tests/testData/EntryPoints/cache/entryPoints.php';
|
||||
$paths = array(
|
||||
'corePath' => 'tests/testData/EntryPoints/Espo/EntryPoints',
|
||||
'modulePath' => 'tests/testData/EntryPoints/Espo/Modules/{*}/EntryPoints',
|
||||
'customPath' => 'tests/testData/EntryPoints/Espo/Custom/EntryPoints',
|
||||
);
|
||||
|
||||
$result = array (
|
||||
'Download' => '\\tests\\testData\\EntryPoints\\Espo\\EntryPoints\\Download',
|
||||
);
|
||||
|
||||
$this->assertEquals( $result, $this->reflection->invokeMethod('getData', array($cacheFile, $paths)) );
|
||||
}
|
||||
|
||||
function testGetDataWithNoCache()
|
||||
{
|
||||
$this->objects['config']
|
||||
->expects($this->exactly(2))
|
||||
->method('get')
|
||||
->will($this->returnValue(false));
|
||||
|
||||
$this->objects['metadata']
|
||||
->expects($this->once())
|
||||
->method('getModuleList')
|
||||
->will($this->returnValue(
|
||||
array(
|
||||
'Crm',
|
||||
)
|
||||
));
|
||||
|
||||
$cacheFile = 'tests/testData/EntryPoints/cache/entryPoints.php';
|
||||
$paths = array(
|
||||
'corePath' => 'tests/testData/EntryPoints/Espo/EntryPoints',
|
||||
'modulePath' => 'tests/testData/EntryPoints/Espo/Modules/{*}/EntryPoints',
|
||||
'customPath' => 'tests/testData/EntryPoints/Espo/Custom/EntryPoints',
|
||||
);
|
||||
|
||||
$result = array(
|
||||
'Download' => '\tests\testData\EntryPoints\Espo\EntryPoints\Download',
|
||||
'Test' => '\tests\testData\EntryPoints\Espo\EntryPoints\Test',
|
||||
'InModule' => '\tests\testData\EntryPoints\Espo\Modules\Crm\EntryPoints\InModule'
|
||||
);
|
||||
|
||||
$this->assertEquals( $result, $this->reflection->invokeMethod('getData', array($cacheFile, $paths)) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -5,8 +5,7 @@ namespace tests\testData\EntryPoints\Espo\EntryPoints;
|
||||
|
||||
class Download extends \Espo\Core\EntryPoints\Base
|
||||
{
|
||||
protected $authRequired = true;
|
||||
|
||||
|
||||
public function run()
|
||||
{
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
return array (
|
||||
'Download' => '\\tests\\testData\\EntryPoints\\Espo\\EntryPoints\\Download',
|
||||
);
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user