PMCORE-552
This commit is contained in:
committed by
Julio Cesar Laura Avendaño
parent
a1f447d8af
commit
ebfc73ca11
12
database/factories/AppTimeoutActionFactory.php
Normal file
12
database/factories/AppTimeoutActionFactory.php
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Faker\Generator as Faker;
|
||||||
|
|
||||||
|
$factory->define(\ProcessMaker\Model\AppTimeoutAction::class, function (Faker $faker) {
|
||||||
|
$index = $faker->unique()->numberBetween(20);
|
||||||
|
return [
|
||||||
|
'APP_UID' => G::generateUniqueID(),
|
||||||
|
'DEL_INDEX' => $index,
|
||||||
|
'EXECUTION_DATE' => $faker->dateTime()
|
||||||
|
];
|
||||||
|
});
|
||||||
@@ -29,10 +29,11 @@ $factory->define(\ProcessMaker\Model\Task::class, function(Faker $faker) {
|
|||||||
'TAS_OWNER_APP' => 'FALSE',
|
'TAS_OWNER_APP' => 'FALSE',
|
||||||
'TAS_CAN_SEND_MESSAGE' => 'FALSE',
|
'TAS_CAN_SEND_MESSAGE' => 'FALSE',
|
||||||
'TAS_SEND_LAST_EMAIL' => 'FALSE',
|
'TAS_SEND_LAST_EMAIL' => 'FALSE',
|
||||||
|
'TAS_SELFSERVICE_TIMEOUT' => 0,
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create a delegation with the foreign keys
|
// Create a task with the foreign keys
|
||||||
$factory->state(\ProcessMaker\Model\Task::class, 'foreign_keys', function (Faker $faker) {
|
$factory->state(\ProcessMaker\Model\Task::class, 'foreign_keys', function (Faker $faker) {
|
||||||
$process = factory(\ProcessMaker\Model\Process::class)->create();
|
$process = factory(\ProcessMaker\Model\Process::class)->create();
|
||||||
return [
|
return [
|
||||||
@@ -57,5 +58,29 @@ $factory->state(\ProcessMaker\Model\Task::class, 'foreign_keys', function (Faker
|
|||||||
'TAS_OWNER_APP' => 'FALSE',
|
'TAS_OWNER_APP' => 'FALSE',
|
||||||
'TAS_CAN_SEND_MESSAGE' => 'FALSE',
|
'TAS_CAN_SEND_MESSAGE' => 'FALSE',
|
||||||
'TAS_SEND_LAST_EMAIL' => 'FALSE',
|
'TAS_SEND_LAST_EMAIL' => 'FALSE',
|
||||||
|
'TAS_SELFSERVICE_TIMEOUT' => 0,
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create a task related with the self-service timeout execution
|
||||||
|
$factory->state(\ProcessMaker\Model\Task::class, 'sef_service_timeout', function (Faker $faker) {
|
||||||
|
$timeUnit = $faker->randomElement(['MINUTES', 'HOURS', 'DAYS']);
|
||||||
|
$execution = $faker->randomElement(['EVERY_TIME', 'ONCE']);
|
||||||
|
return [
|
||||||
|
'TAS_UID' => G::generateUniqueID(),
|
||||||
|
'TAS_ID' => $faker->unique()->numberBetween(1, 200000),
|
||||||
|
'TAS_TITLE' => $faker->sentence(2),
|
||||||
|
'TAS_TYPE' => 'NORMAL',
|
||||||
|
'TAS_TYPE_DAY' => 1,
|
||||||
|
'TAS_DURATION' => 1,
|
||||||
|
'TAS_ASSIGN_TYPE' => 'SELF_SERVICE',
|
||||||
|
'TAS_ASSIGN_VARIABLE' => '@@SYS_NEXT_USER_TO_BE_ASSIGNED',
|
||||||
|
'TAS_SELFSERVICE_TIMEOUT' => 1,
|
||||||
|
'TAS_SELFSERVICE_TIME' => $faker->unique()->numberBetween(1, 24),
|
||||||
|
'TAS_SELFSERVICE_TIME_UNIT' => $timeUnit,
|
||||||
|
'TAS_SELFSERVICE_TRIGGER_UID' => function() {
|
||||||
|
return $trigger = factory(\ProcessMaker\Model\Triggers::class)->create()->TRI_UID;
|
||||||
|
},
|
||||||
|
'TAS_SELFSERVICE_EXECUTION' => $execution,
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ $factory->define(Triggers::class, function (Faker $faker) {
|
|||||||
return factory(\ProcessMaker\Model\Process::class)->create()->PRO_UID;
|
return factory(\ProcessMaker\Model\Process::class)->create()->PRO_UID;
|
||||||
},
|
},
|
||||||
'TRI_TYPE' => 'SCRIPT',
|
'TRI_TYPE' => 'SCRIPT',
|
||||||
'TRI_WEBBOT' => $faker->text,
|
'TRI_WEBBOT' => '$var = 1;',
|
||||||
'TRI_PARAM' => '',
|
'TRI_PARAM' => '',
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\Support\Facades\Request;
|
use Illuminate\Support\Facades\Request;
|
||||||
use ProcessMaker\Core\System;
|
use ProcessMaker\Core\System;
|
||||||
|
use ProcessMaker\Log\AuditLog;
|
||||||
use ProcessMaker\Plugins\PluginRegistry;
|
use ProcessMaker\Plugins\PluginRegistry;
|
||||||
use ProcessMaker\Services\OAuth2\Server;
|
use ProcessMaker\Services\OAuth2\Server;
|
||||||
use ProcessMaker\Validation\ValidationUploadedFiles;
|
use ProcessMaker\Validation\ValidationUploadedFiles;
|
||||||
|
|||||||
@@ -4,10 +4,15 @@ namespace ProcessMaker\BusinessModel;
|
|||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use G;
|
use G;
|
||||||
|
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
use ProcessMaker\BusinessModel\Cases;
|
use ProcessMaker\BusinessModel\Cases;
|
||||||
use ProcessMaker\Model\Application;
|
use ProcessMaker\Model\Application;
|
||||||
use ProcessMaker\Model\Delegation;
|
use ProcessMaker\Model\Delegation;
|
||||||
use ProcessMaker\Model\Documents;
|
use ProcessMaker\Model\Documents;
|
||||||
|
use ProcessMaker\Model\ListUnassigned;
|
||||||
|
use ProcessMaker\Model\Task;
|
||||||
|
use ProcessMaker\Model\Triggers;
|
||||||
use ProcessMaker\Model\User;
|
use ProcessMaker\Model\User;
|
||||||
use RBAC;
|
use RBAC;
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
@@ -19,7 +24,6 @@ use Tests\TestCase;
|
|||||||
*/
|
*/
|
||||||
class CasesTest extends TestCase
|
class CasesTest extends TestCase
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up method.
|
* Set up method.
|
||||||
*/
|
*/
|
||||||
@@ -233,4 +237,82 @@ class CasesTest extends TestCase
|
|||||||
// Call the uploadFiles method
|
// Call the uploadFiles method
|
||||||
$case->uploadFiles($user->USR_UID, $application->APP_UID, $varName, -1, null, $delegation->DEL_INDEX);
|
$case->uploadFiles($user->USR_UID, $application->APP_UID, $varName, -1, null, $delegation->DEL_INDEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test the execution of trigger from cases related to the self services timeout
|
||||||
|
*
|
||||||
|
* @covers \ProcessMaker\BusinessModel\Cases::executeSelfServiceTimeout()
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function it_execute_trigger_from_cases_with_self_service_timeout_every_time()
|
||||||
|
{
|
||||||
|
ListUnassigned::truncate();
|
||||||
|
// Define the Execute Trigger = EVERY_TIME
|
||||||
|
$application = factory(Application::class)->states('foreign_keys')->create();
|
||||||
|
// Create a trigger
|
||||||
|
$trigger = factory(Triggers::class)->create([
|
||||||
|
'PRO_UID' => $application->PRO_UID,
|
||||||
|
'TRI_WEBBOT' => 'echo(1);'
|
||||||
|
]);
|
||||||
|
// Create a task with the configuration trigger execution
|
||||||
|
$task = factory(Task::class)->states('sef_service_timeout')->create([
|
||||||
|
'PRO_UID' => $application->PRO_UID,
|
||||||
|
'TAS_SELFSERVICE_EXECUTION' => 'EVERY_TIME',
|
||||||
|
'TAS_SELFSERVICE_TRIGGER_UID' => $trigger->TRI_UID
|
||||||
|
]);
|
||||||
|
// Create a unassigned cases
|
||||||
|
factory(ListUnassigned::class)->create([
|
||||||
|
'TAS_UID' => $task->TAS_UID,
|
||||||
|
'TAS_ID' => $task->TAS_ID,
|
||||||
|
'APP_NUMBER' => $application->APP_NUMBER,
|
||||||
|
'APP_UID' => $application->APP_UID,
|
||||||
|
'PRO_UID' => $application->PRO_UID
|
||||||
|
]);
|
||||||
|
// Define the session
|
||||||
|
$_SESSION["PROCESS"] = $application->PRO_UID;
|
||||||
|
|
||||||
|
// todo: the function Cases::loadCase is using propel we need to change this
|
||||||
|
DB::commit();
|
||||||
|
$casesExecuted = Cases::executeSelfServiceTimeout();
|
||||||
|
$this->assertTrue(is_array($casesExecuted));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test the execution of trigger from cases related to the self services timeout
|
||||||
|
*
|
||||||
|
* @covers \ProcessMaker\BusinessModel\Cases::executeSelfServiceTimeout()
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function it_execute_trigger_from_cases_with_self_service_timeout_once()
|
||||||
|
{
|
||||||
|
ListUnassigned::truncate();
|
||||||
|
// Define the Execute Trigger = ONCE
|
||||||
|
$application = factory(Application::class)->states('foreign_keys')->create();
|
||||||
|
// Create a trigger
|
||||||
|
$trigger = factory(Triggers::class)->create([
|
||||||
|
'PRO_UID' => $application->PRO_UID,
|
||||||
|
'TRI_WEBBOT' => 'echo(1);'
|
||||||
|
]);
|
||||||
|
// Create a task with the configuration trigger execution
|
||||||
|
$task = factory(Task::class)->states('sef_service_timeout')->create([
|
||||||
|
'PRO_UID' => $application->PRO_UID,
|
||||||
|
'TAS_SELFSERVICE_EXECUTION' => 'ONCE',
|
||||||
|
'TAS_SELFSERVICE_TRIGGER_UID' => $trigger->TRI_UID
|
||||||
|
]);
|
||||||
|
// Create a unassigned cases
|
||||||
|
factory(ListUnassigned::class)->create([
|
||||||
|
'TAS_UID' => $task->TAS_UID,
|
||||||
|
'TAS_ID' => $task->TAS_ID,
|
||||||
|
'APP_NUMBER' => $application->APP_NUMBER,
|
||||||
|
'APP_UID' => $application->APP_UID,
|
||||||
|
'PRO_UID' => $application->PRO_UID
|
||||||
|
]);
|
||||||
|
// Define the session
|
||||||
|
$_SESSION["PROCESS"] = $application->PRO_UID;
|
||||||
|
|
||||||
|
// todo: the function Cases::loadCase is using propel we need to change this
|
||||||
|
DB::commit();
|
||||||
|
$casesExecuted = Cases::executeSelfServiceTimeout();
|
||||||
|
$this->assertTrue(is_array($casesExecuted));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,120 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\unit\workflow\engine\src\ProcessMaker\Model;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||||
|
use ProcessMaker\Model\AppTimeoutAction;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class DelegationTest
|
||||||
|
*
|
||||||
|
* @coversDefaultClass \ProcessMaker\Model\AppTimeoutAction
|
||||||
|
*/
|
||||||
|
class AppTimeoutActionTest extends TestCase
|
||||||
|
{
|
||||||
|
use DatabaseTransactions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test set and get the caseUid property
|
||||||
|
*
|
||||||
|
* @covers \ProcessMaker\Model\AppTimeoutAction::setCaseUid()
|
||||||
|
* @covers \ProcessMaker\Model\AppTimeoutAction::getCaseUid()
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function it_set_get_case_uid()
|
||||||
|
{
|
||||||
|
factory(AppTimeoutAction::class)->create();
|
||||||
|
$timeout = factory(AppTimeoutAction::class)->create();
|
||||||
|
$timeout->setCaseUid($timeout->APP_UID);
|
||||||
|
$this->assertEquals($timeout->getCaseUid(), $timeout->APP_UID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test set and get the index property
|
||||||
|
*
|
||||||
|
* @covers \ProcessMaker\Model\AppTimeoutAction::setIndex()
|
||||||
|
* @covers \ProcessMaker\Model\AppTimeoutAction::getIndex()
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function it_set_get_index()
|
||||||
|
{
|
||||||
|
factory(AppTimeoutAction::class)->create();
|
||||||
|
$timeout = factory(AppTimeoutAction::class)->create();
|
||||||
|
$timeout->setIndex($timeout->DEL_INDEX);
|
||||||
|
$this->assertEquals($timeout->getIndex(), $timeout->DEL_INDEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test a query to only include a specific case
|
||||||
|
*
|
||||||
|
* @covers \ProcessMaker\Model\AppTimeoutAction::scopeCase()
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function it_filter_a_specific_case()
|
||||||
|
{
|
||||||
|
factory(AppTimeoutAction::class)->create();
|
||||||
|
$timeout = factory(AppTimeoutAction::class)->create();
|
||||||
|
$this->assertCount(1, $timeout->case($timeout->APP_UID)->get());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test scope a query to only include a specific case
|
||||||
|
*
|
||||||
|
* @covers \ProcessMaker\Model\AppTimeoutAction::scopeIndex()
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function it_filter_a_specific_index()
|
||||||
|
{
|
||||||
|
factory(AppTimeoutAction::class)->create();
|
||||||
|
$timeout = factory(AppTimeoutAction::class)->create();
|
||||||
|
$this->assertCount(1, $timeout->case($timeout->APP_UID)->index($timeout->DEL_INDEX)->get());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This checks it returns information about the self service timeout in a sequential thread
|
||||||
|
*
|
||||||
|
* @covers \ProcessMaker\Model\AppTimeoutAction::cases()
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function it_return_the_case_executed_once_one_thread()
|
||||||
|
{
|
||||||
|
$records = factory(AppTimeoutAction::class, 5)->create();
|
||||||
|
foreach ($records as $row) {
|
||||||
|
$appUid = $row->APP_UID;
|
||||||
|
$delIndex = $row->DEL_INDEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
$appTimeout = new AppTimeoutAction();
|
||||||
|
$appTimeout->setCaseUid($appUid);
|
||||||
|
$appTimeout->setIndex($delIndex);
|
||||||
|
$caseExecuted = $appTimeout->cases();
|
||||||
|
$this->assertNotEmpty($caseExecuted);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This checks it returns information about the self service timeout in a parallel thread
|
||||||
|
*
|
||||||
|
* @covers \ProcessMaker\Model\AppTimeoutAction::cases()
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function it_return_the_case_executed_once_more_than_one_thread()
|
||||||
|
{
|
||||||
|
$records = factory(AppTimeoutAction::class, 5)->create();
|
||||||
|
foreach ($records as $row) {
|
||||||
|
$appUid = $row->APP_UID;
|
||||||
|
$delIndex = $row->DEL_INDEX;
|
||||||
|
}
|
||||||
|
// Create other thread in the same case
|
||||||
|
factory(AppTimeoutAction::class)->create([
|
||||||
|
'APP_UID' => $appUid,
|
||||||
|
'DEL_INDEX' => $delIndex + 1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$appTimeout = new AppTimeoutAction();
|
||||||
|
$appTimeout->setCaseUid($appUid);
|
||||||
|
$appTimeout->setIndex($delIndex);
|
||||||
|
$caseExecuted = $appTimeout->cases();
|
||||||
|
$this->assertNotEmpty($caseExecuted);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,16 @@ use Tests\TestCase;
|
|||||||
*/
|
*/
|
||||||
class ListUnassignedTest extends TestCase
|
class ListUnassignedTest extends TestCase
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up function.
|
||||||
|
*/
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
ListUnassigned::truncate();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method set up.
|
* Method set up.
|
||||||
*/
|
*/
|
||||||
@@ -300,5 +310,25 @@ class ListUnassignedTest extends TestCase
|
|||||||
$result = ListUnassigned::loadList($user->USR_UID, $filters);
|
$result = ListUnassigned::loadList($user->USR_UID, $filters);
|
||||||
$this->assertCount(2, $result);
|
$this->assertCount(2, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This checks the self-service timeout cases
|
||||||
|
*
|
||||||
|
* @covers \ProcessMaker\Model\ListUnassigned::selfServiceTimeout()
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function it_should_return_cases_configured_self_service_timeout()
|
||||||
|
{
|
||||||
|
// Create some cases configured the self service timeout
|
||||||
|
for ($x = 1; $x <= 5; $x++) {
|
||||||
|
$task = factory(Task::class)->states('sef_service_timeout')->create();
|
||||||
|
factory(ListUnassigned::class)->create([
|
||||||
|
'TAS_UID' => $task->TAS_UID,
|
||||||
|
'TAS_ID' => $task->TAS_ID
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
$results = ListUnassigned::selfServiceTimeout();
|
||||||
|
$this->assertCount(5, $results);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,14 +2,40 @@
|
|||||||
|
|
||||||
namespace Tests\unit\workflow\engine\src\ProcessMaker\Model;
|
namespace Tests\unit\workflow\engine\src\ProcessMaker\Model;
|
||||||
|
|
||||||
|
use G;
|
||||||
|
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||||
use ProcessMaker\Model\Process;
|
use ProcessMaker\Model\Process;
|
||||||
use ProcessMaker\Model\Triggers;
|
use ProcessMaker\Model\Triggers;
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class DelegationTest
|
||||||
|
*
|
||||||
|
* @coversDefaultClass \ProcessMaker\Model\Triggers
|
||||||
|
*/
|
||||||
class TriggersTest extends TestCase
|
class TriggersTest extends TestCase
|
||||||
{
|
{
|
||||||
|
use DatabaseTransactions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test set and get the trigger property
|
||||||
|
*
|
||||||
|
* @covers \ProcessMaker\Model\Triggers::setTrigger()
|
||||||
|
* @covers \ProcessMaker\Model\Triggers::getTrigger()
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function it_set_get_trigger()
|
||||||
|
{
|
||||||
|
factory(Triggers::class)->create();
|
||||||
|
$trigger = factory(Triggers::class)->create();
|
||||||
|
$trigger->setTrigger($trigger->TRI_UID);
|
||||||
|
$this->assertEquals($trigger->getTrigger(), $trigger->TRI_UID);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It tests the process scope in the trigger model
|
* It tests the process scope in the trigger model
|
||||||
|
*
|
||||||
|
* @covers \ProcessMaker\Model\Triggers::scopeProcess()
|
||||||
* @test
|
* @test
|
||||||
*/
|
*/
|
||||||
public function it_should_test_process_scope_in_trigger_model()
|
public function it_should_test_process_scope_in_trigger_model()
|
||||||
@@ -74,4 +100,48 @@ class TriggersTest extends TestCase
|
|||||||
$this->assertEquals($process[2]['PRO_UID'], $result[0]['PRO_UID']);
|
$this->assertEquals($process[2]['PRO_UID'], $result[0]['PRO_UID']);
|
||||||
$this->assertEquals($process[2]['PRO_UID'], $result[1]['PRO_UID']);
|
$this->assertEquals($process[2]['PRO_UID'], $result[1]['PRO_UID']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test scope a query to only include a specific case
|
||||||
|
*
|
||||||
|
* @covers \ProcessMaker\Model\Triggers::scopeTrigger()
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function it_filter_specific_tasks()
|
||||||
|
{
|
||||||
|
factory(Triggers::class)->create();
|
||||||
|
$trigger = factory(Triggers::class)->create();
|
||||||
|
$this->assertCount(1, $trigger->trigger($trigger->TRI_UID)->get());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This checks it returns information about the trigger
|
||||||
|
*
|
||||||
|
* @covers \ProcessMaker\Model\Triggers::triggers()
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function it_return_specific_trigger_information()
|
||||||
|
{
|
||||||
|
$triggers = factory(Triggers::class, 5)->create();
|
||||||
|
$trigger = new Triggers();
|
||||||
|
$trigger->setTrigger($triggers[0]->TRI_UID);
|
||||||
|
$triggersList = $trigger->triggers();
|
||||||
|
$this->assertCount(1, $triggersList);
|
||||||
|
$this->assertEquals($triggers[0]->TRI_TITLE , $triggersList[0]['TRI_TITLE']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This checks it returns empty when the trigger does not exist
|
||||||
|
*
|
||||||
|
* @covers \ProcessMaker\Model\Triggers::triggers()
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function it_return_empty_when_the_trigger_not_exist()
|
||||||
|
{
|
||||||
|
factory(Triggers::class)->create();
|
||||||
|
$trigger = new Triggers();
|
||||||
|
$trigger->setTrigger(G::generateUniqueID());
|
||||||
|
$triggersList = $trigger->triggers();
|
||||||
|
$this->assertEmpty($triggersList);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\unit\workflow\engine\src\ProcessMaker\Util\Helpers;
|
||||||
|
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class CalculateDateTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* It tests the addition of days
|
||||||
|
*
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function it_test_adding_days()
|
||||||
|
{
|
||||||
|
$iniDate = '2019-10-04 12:07:40';
|
||||||
|
$newDate = calculateDate($iniDate, 'DAYS', 1);
|
||||||
|
$this->assertEquals('2019-10-05 12:07:40', $newDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* It tests the addition of hours
|
||||||
|
*
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function it_test_adding_hours()
|
||||||
|
{
|
||||||
|
$iniDate = '2019-10-04 12:07:40';
|
||||||
|
$newDate = calculateDate($iniDate, 'HOURS', 1);
|
||||||
|
$this->assertEquals('2019-10-04 13:07:40', $newDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* It tests the addition of minutes
|
||||||
|
*
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function it_test_adding_minutes()
|
||||||
|
{
|
||||||
|
$iniDate = '2019-10-04 12:07:40';
|
||||||
|
$newDate = calculateDate($iniDate, 'MINUTES', 10);
|
||||||
|
$this->assertEquals('2019-10-04 12:17:40', $newDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ namespace Tests\unit\workflow\src\ProcessMaker\Util\Helpers;
|
|||||||
|
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
class ChangeAbbreviationOfDirectives extends TestCase
|
class ChangeAbbreviationOfDirectivesTest extends TestCase
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Provider to define different types of configurations in the php.ini and the result expected
|
* Provider to define different types of configurations in the php.ini and the result expected
|
||||||
@@ -17,6 +17,7 @@ use Illuminate\Foundation\Http\Kernel;
|
|||||||
/*----------------------------------********---------------------------------*/
|
/*----------------------------------********---------------------------------*/
|
||||||
use ProcessMaker\BusinessModel\ActionsByEmail\ResponseReader;
|
use ProcessMaker\BusinessModel\ActionsByEmail\ResponseReader;
|
||||||
/*----------------------------------********---------------------------------*/
|
/*----------------------------------********---------------------------------*/
|
||||||
|
use ProcessMaker\BusinessModel\Cases;
|
||||||
|
|
||||||
require_once __DIR__ . '/../../../gulliver/system/class.g.php';
|
require_once __DIR__ . '/../../../gulliver/system/class.g.php';
|
||||||
require_once __DIR__ . '/../../../bootstrap/autoload.php';
|
require_once __DIR__ . '/../../../bootstrap/autoload.php';
|
||||||
@@ -562,6 +563,11 @@ function executeUpdateAppTitle()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if some task unassigned has enable the setting timeout and execute the trigger related
|
||||||
|
*
|
||||||
|
* @link https://wiki.processmaker.com/3.2/Tasks#Self-Service
|
||||||
|
*/
|
||||||
function executeCaseSelfService()
|
function executeCaseSelfService()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@@ -570,163 +576,16 @@ function executeCaseSelfService()
|
|||||||
if ($argvx != "" && strpos($argvx, "unassigned-case") === false) {
|
if ($argvx != "" && strpos($argvx, "unassigned-case") === false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$criteria = new Criteria("workflow");
|
|
||||||
|
|
||||||
//SELECT
|
|
||||||
$criteria->addSelectColumn(AppCacheViewPeer::APP_UID);
|
|
||||||
$criteria->addSelectColumn(AppCacheViewPeer::DEL_INDEX);
|
|
||||||
$criteria->addSelectColumn(AppCacheViewPeer::DEL_DELEGATE_DATE);
|
|
||||||
$criteria->addSelectColumn(AppCacheViewPeer::APP_NUMBER);
|
|
||||||
$criteria->addSelectColumn(AppCacheViewPeer::PRO_UID);
|
|
||||||
$criteria->addSelectColumn(TaskPeer::TAS_UID);
|
|
||||||
$criteria->addSelectColumn(TaskPeer::TAS_SELFSERVICE_TIME);
|
|
||||||
$criteria->addSelectColumn(TaskPeer::TAS_SELFSERVICE_TIME_UNIT);
|
|
||||||
$criteria->addSelectColumn(TaskPeer::TAS_SELFSERVICE_TRIGGER_UID);
|
|
||||||
/*----------------------------------********---------------------------------*/
|
|
||||||
$criteria->addSelectColumn(TaskPeer::TAS_SELFSERVICE_EXECUTION);
|
|
||||||
/*----------------------------------********---------------------------------*/
|
|
||||||
|
|
||||||
//FROM
|
|
||||||
$condition = array();
|
|
||||||
$condition[] = array(AppCacheViewPeer::TAS_UID, TaskPeer::TAS_UID);
|
|
||||||
$condition[] = array(TaskPeer::TAS_SELFSERVICE_TIMEOUT, 1);
|
|
||||||
$criteria->addJoinMC($condition, Criteria::LEFT_JOIN);
|
|
||||||
|
|
||||||
//WHERE
|
|
||||||
$criteria->add(AppCacheViewPeer::USR_UID, "");
|
|
||||||
$criteria->add(AppCacheViewPeer::DEL_THREAD_STATUS, "OPEN");
|
|
||||||
|
|
||||||
//QUERY
|
|
||||||
$rsCriteria = AppCacheViewPeer::doSelectRS($criteria);
|
|
||||||
$rsCriteria->setFetchmode(ResultSet::FETCHMODE_ASSOC);
|
|
||||||
|
|
||||||
setExecutionMessage("Unassigned case");
|
setExecutionMessage("Unassigned case");
|
||||||
saveLog("unassignedCase", "action", "Unassigned case", "c");
|
saveLog("unassignedCase", "action", "Unassigned case", "c");
|
||||||
|
$casesExecuted = Cases::executeSelfServiceTimeout();
|
||||||
$calendar = new Calendar();
|
foreach ($casesExecuted as $caseNumber) {
|
||||||
|
saveLog("unassignedCase", "action", "OK Executed trigger to the case $caseNumber");
|
||||||
while ($rsCriteria->next()) {
|
|
||||||
$row = $rsCriteria->getRow();
|
|
||||||
$flag = false;
|
|
||||||
|
|
||||||
$appcacheAppUid = $row["APP_UID"];
|
|
||||||
$appcacheDelIndex = $row["DEL_INDEX"];
|
|
||||||
$appcacheDelDelegateDate = $row["DEL_DELEGATE_DATE"];
|
|
||||||
$appcacheAppNumber = $row["APP_NUMBER"];
|
|
||||||
$appcacheProUid = $row["PRO_UID"];
|
|
||||||
$taskUid = $row["TAS_UID"];
|
|
||||||
$taskSelfServiceTime = intval($row["TAS_SELFSERVICE_TIME"]);
|
|
||||||
$taskSelfServiceTimeUnit = $row["TAS_SELFSERVICE_TIME_UNIT"];
|
|
||||||
$taskSelfServiceTriggerUid = $row["TAS_SELFSERVICE_TRIGGER_UID"];
|
|
||||||
/*----------------------------------********---------------------------------*/
|
|
||||||
$taskSelfServiceJustOneExecution = $row["TAS_SELFSERVICE_EXECUTION"];
|
|
||||||
|
|
||||||
if ($taskSelfServiceJustOneExecution == 'ONCE') {
|
|
||||||
$criteriaSelfService = new Criteria("workflow");
|
|
||||||
|
|
||||||
$criteriaSelfService->add(AppTimeoutActionExecutedPeer::APP_UID, $appcacheAppUid);
|
|
||||||
$criteriaSelfService->add(AppTimeoutActionExecutedPeer::DEL_INDEX, $appcacheDelIndex);
|
|
||||||
|
|
||||||
$querySelfService = AppTimeoutActionExecutedPeer::doSelectRS($criteriaSelfService);
|
|
||||||
$querySelfService->setFetchmode(ResultSet::FETCHMODE_ASSOC);
|
|
||||||
|
|
||||||
if ($querySelfService->next()) {
|
|
||||||
$row = $querySelfService->getRow();
|
|
||||||
$flag = true; //already executed
|
|
||||||
}
|
}
|
||||||
}
|
setExecutionResultMessage(count($casesExecuted) . " Cases");
|
||||||
/*----------------------------------********---------------------------------*/
|
|
||||||
|
|
||||||
if ($calendar->pmCalendarUid == '') {
|
|
||||||
$calendar->getCalendar(null, $appcacheProUid, $taskUid);
|
|
||||||
$calendar->getCalendarData();
|
|
||||||
}
|
|
||||||
|
|
||||||
$dueDate = $calendar->calculateDate(
|
|
||||||
$appcacheDelDelegateDate,
|
|
||||||
$taskSelfServiceTime,
|
|
||||||
$taskSelfServiceTimeUnit //HOURS|DAYS|MINUTES
|
|
||||||
//1
|
|
||||||
);
|
|
||||||
|
|
||||||
if (time() > $dueDate["DUE_DATE_SECONDS"] && $flag == false) {
|
|
||||||
$sessProcess = null;
|
|
||||||
$sessProcessSw = 0;
|
|
||||||
|
|
||||||
//Load data
|
|
||||||
$case = new Cases();
|
|
||||||
$appFields = $case->loadCase($appcacheAppUid);
|
|
||||||
|
|
||||||
$appFields["APP_DATA"]["APPLICATION"] = $appcacheAppUid;
|
|
||||||
|
|
||||||
if (isset($_SESSION["PROCESS"])) {
|
|
||||||
$sessProcess = $_SESSION["PROCESS"];
|
|
||||||
$sessProcessSw = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
$_SESSION["PROCESS"] = $appFields["PRO_UID"];
|
|
||||||
|
|
||||||
//Execute trigger
|
|
||||||
$criteriaTgr = new Criteria();
|
|
||||||
$criteriaTgr->add(TriggersPeer::TRI_UID, $taskSelfServiceTriggerUid);
|
|
||||||
|
|
||||||
$rsCriteriaTgr = TriggersPeer::doSelectRS($criteriaTgr);
|
|
||||||
$rsCriteriaTgr->setFetchmode(ResultSet::FETCHMODE_ASSOC);
|
|
||||||
|
|
||||||
if ($rsCriteriaTgr->next()) {
|
|
||||||
$row = $rsCriteriaTgr->getRow();
|
|
||||||
|
|
||||||
if (is_array($row) && $row["TRI_TYPE"] == "SCRIPT") {
|
|
||||||
$arrayCron = unserialize(trim(@file_get_contents(PATH_DATA . "cron")));
|
|
||||||
$arrayCron["processcTimeProcess"] = 60; //Minutes
|
|
||||||
$arrayCron["processcTimeStart"] = time();
|
|
||||||
@file_put_contents(PATH_DATA . "cron", serialize($arrayCron));
|
|
||||||
|
|
||||||
//Trigger
|
|
||||||
global $oPMScript;
|
|
||||||
|
|
||||||
$oPMScript = new PMScript();
|
|
||||||
$oPMScript->setDataTrigger($row);
|
|
||||||
$oPMScript->setFields($appFields["APP_DATA"]);
|
|
||||||
$oPMScript->setScript($row["TRI_WEBBOT"]);
|
|
||||||
$oPMScript->setExecutedOn(PMScript::SELF_SERVICE_TIMEOUT);
|
|
||||||
$oPMScript->execute();
|
|
||||||
|
|
||||||
/*----------------------------------********---------------------------------*/
|
|
||||||
//saving the case`s data if the 'Execution' is set in ONCE.
|
|
||||||
if ($taskSelfServiceJustOneExecution == "ONCE") {
|
|
||||||
$oAppTimeoutActionExecuted = new AppTimeoutActionExecuted();
|
|
||||||
$dataSelf = array();
|
|
||||||
$dataSelf["APP_UID"] = $appcacheAppUid;
|
|
||||||
$dataSelf["DEL_INDEX"] = $appcacheDelIndex;
|
|
||||||
$dataSelf["EXECUTION_DATE"] = time();
|
|
||||||
$oAppTimeoutActionExecuted->create($dataSelf);
|
|
||||||
}
|
|
||||||
/*----------------------------------********---------------------------------*/
|
|
||||||
$appFields["APP_DATA"] = array_merge($appFields["APP_DATA"], $oPMScript->aFields);
|
|
||||||
|
|
||||||
unset($appFields['APP_STATUS']);
|
|
||||||
unset($appFields['APP_PROC_STATUS']);
|
|
||||||
unset($appFields['APP_PROC_CODE']);
|
|
||||||
unset($appFields['APP_PIN']);
|
|
||||||
$case->updateCase($appFields["APP_UID"], $appFields);
|
|
||||||
|
|
||||||
saveLog("unassignedCase", "action", "OK Executed trigger to the case $appcacheAppNumber");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unset($_SESSION["PROCESS"]);
|
|
||||||
|
|
||||||
if ($sessProcessSw == 1) {
|
|
||||||
$_SESSION["PROCESS"] = $sessProcess;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setExecutionResultMessage("DONE");
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
setExecutionResultMessage("WITH ERRORS", "error");
|
setExecutionResultMessage("WITH ERRORS", "error");
|
||||||
|
saveLog("unassignedCase", "action", "Unassigned case", "c");
|
||||||
eprintln(" '-" . $e->getMessage(), "red");
|
eprintln(" '-" . $e->getMessage(), "red");
|
||||||
saveLog("unassignedCase", "error", "Error in unassigned case: " . $e->getMessage());
|
saveLog("unassignedCase", "error", "Error in unassigned case: " . $e->getMessage());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -302,6 +302,9 @@ class PMScript
|
|||||||
case 'SCRIPT_TASK':
|
case 'SCRIPT_TASK':
|
||||||
$executedOn = self::SCRIPT_TASK;
|
$executedOn = self::SCRIPT_TASK;
|
||||||
break;
|
break;
|
||||||
|
case 'SELF_SERVICE_TIMEOUT':
|
||||||
|
$executedOn = self::SELF_SERVICE_TIMEOUT;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
$executedOn = self::UNDEFINED_ORIGIN;
|
$executedOn = self::UNDEFINED_ORIGIN;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ class AppTimeoutActionExecutedMapBuilder
|
|||||||
|
|
||||||
$tMap->addPrimaryKey('APP_UID', 'AppUid', 'string', CreoleTypes::VARCHAR, true, 32);
|
$tMap->addPrimaryKey('APP_UID', 'AppUid', 'string', CreoleTypes::VARCHAR, true, 32);
|
||||||
|
|
||||||
$tMap->addColumn('DEL_INDEX', 'DelIndex', 'int', CreoleTypes::INTEGER, true, null);
|
$tMap->addPrimaryKey('DEL_INDEX', 'DelIndex', 'int', CreoleTypes::INTEGER, true, null);
|
||||||
|
|
||||||
$tMap->addColumn('EXECUTION_DATE', 'ExecutionDate', 'int', CreoleTypes::TIMESTAMP, false, null);
|
$tMap->addColumn('EXECUTION_DATE', 'ExecutionDate', 'int', CreoleTypes::TIMESTAMP, false, null);
|
||||||
|
|
||||||
|
|||||||
@@ -565,28 +565,40 @@ abstract class BaseAppTimeoutActionExecuted extends BaseObject implements Persis
|
|||||||
$criteria = new Criteria(AppTimeoutActionExecutedPeer::DATABASE_NAME);
|
$criteria = new Criteria(AppTimeoutActionExecutedPeer::DATABASE_NAME);
|
||||||
|
|
||||||
$criteria->add(AppTimeoutActionExecutedPeer::APP_UID, $this->app_uid);
|
$criteria->add(AppTimeoutActionExecutedPeer::APP_UID, $this->app_uid);
|
||||||
|
$criteria->add(AppTimeoutActionExecutedPeer::DEL_INDEX, $this->del_index);
|
||||||
|
|
||||||
return $criteria;
|
return $criteria;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the primary key for this object (row).
|
* Returns the composite primary key for this object.
|
||||||
* @return string
|
* The array elements will be in same order as specified in XML.
|
||||||
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getPrimaryKey()
|
public function getPrimaryKey()
|
||||||
{
|
{
|
||||||
return $this->getAppUid();
|
$pks = array();
|
||||||
|
|
||||||
|
$pks[0] = $this->getAppUid();
|
||||||
|
|
||||||
|
$pks[1] = $this->getDelIndex();
|
||||||
|
|
||||||
|
return $pks;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic method to set the primary key (app_uid column).
|
* Set the [composite] primary key.
|
||||||
*
|
*
|
||||||
* @param string $key Primary key.
|
* @param array $keys The elements of the composite key (order must match the order in XML file).
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function setPrimaryKey($key)
|
public function setPrimaryKey($keys)
|
||||||
{
|
{
|
||||||
$this->setAppUid($key);
|
|
||||||
|
$this->setAppUid($keys[0]);
|
||||||
|
|
||||||
|
$this->setDelIndex($keys[1]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -602,8 +614,6 @@ abstract class BaseAppTimeoutActionExecuted extends BaseObject implements Persis
|
|||||||
public function copyInto($copyObj, $deepCopy = false)
|
public function copyInto($copyObj, $deepCopy = false)
|
||||||
{
|
{
|
||||||
|
|
||||||
$copyObj->setDelIndex($this->del_index);
|
|
||||||
|
|
||||||
$copyObj->setExecutionDate($this->execution_date);
|
$copyObj->setExecutionDate($this->execution_date);
|
||||||
|
|
||||||
|
|
||||||
@@ -611,6 +621,8 @@ abstract class BaseAppTimeoutActionExecuted extends BaseObject implements Persis
|
|||||||
|
|
||||||
$copyObj->setAppUid(''); // this is a pkey column, so set to default value
|
$copyObj->setAppUid(''); // this is a pkey column, so set to default value
|
||||||
|
|
||||||
|
$copyObj->setDelIndex('0'); // this is a pkey column, so set to default value
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -389,6 +389,9 @@ abstract class BaseAppTimeoutActionExecutedPeer
|
|||||||
$comparison = $criteria->getComparison(AppTimeoutActionExecutedPeer::APP_UID);
|
$comparison = $criteria->getComparison(AppTimeoutActionExecutedPeer::APP_UID);
|
||||||
$selectCriteria->add(AppTimeoutActionExecutedPeer::APP_UID, $criteria->remove(AppTimeoutActionExecutedPeer::APP_UID), $comparison);
|
$selectCriteria->add(AppTimeoutActionExecutedPeer::APP_UID, $criteria->remove(AppTimeoutActionExecutedPeer::APP_UID), $comparison);
|
||||||
|
|
||||||
|
$comparison = $criteria->getComparison(AppTimeoutActionExecutedPeer::DEL_INDEX);
|
||||||
|
$selectCriteria->add(AppTimeoutActionExecutedPeer::DEL_INDEX, $criteria->remove(AppTimeoutActionExecutedPeer::DEL_INDEX), $comparison);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$criteria = $values->buildCriteria(); // gets full criteria
|
$criteria = $values->buildCriteria(); // gets full criteria
|
||||||
$selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s)
|
$selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s)
|
||||||
@@ -450,7 +453,22 @@ abstract class BaseAppTimeoutActionExecutedPeer
|
|||||||
} else {
|
} else {
|
||||||
// it must be the primary key
|
// it must be the primary key
|
||||||
$criteria = new Criteria(self::DATABASE_NAME);
|
$criteria = new Criteria(self::DATABASE_NAME);
|
||||||
$criteria->add(AppTimeoutActionExecutedPeer::APP_UID, (array) $values, Criteria::IN);
|
// primary key is composite; we therefore, expect
|
||||||
|
// the primary key passed to be an array of pkey
|
||||||
|
// values
|
||||||
|
if (count($values) == count($values, COUNT_RECURSIVE)) {
|
||||||
|
// array is not multi-dimensional
|
||||||
|
$values = array($values);
|
||||||
|
}
|
||||||
|
$vals = array();
|
||||||
|
foreach ($values as $value) {
|
||||||
|
|
||||||
|
$vals[0][] = $value[0];
|
||||||
|
$vals[1][] = $value[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
$criteria->add(AppTimeoutActionExecutedPeer::APP_UID, $vals[0], Criteria::IN);
|
||||||
|
$criteria->add(AppTimeoutActionExecutedPeer::DEL_INDEX, $vals[1], Criteria::IN);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the correct dbName
|
// Set the correct dbName
|
||||||
@@ -510,51 +528,23 @@ abstract class BaseAppTimeoutActionExecutedPeer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a single object by pkey.
|
* Retrieve object using using composite pkey values.
|
||||||
*
|
* @param string $app_uid
|
||||||
* @param mixed $pk the primary key.
|
* @param int $del_index
|
||||||
* @param Connection $con the connection to use
|
* @param Connection $con
|
||||||
* @return AppTimeoutActionExecuted
|
* @return AppTimeoutActionExecuted
|
||||||
*/
|
*/
|
||||||
public static function retrieveByPK($pk, $con = null)
|
public static function retrieveByPK($app_uid, $del_index, $con = null)
|
||||||
{
|
{
|
||||||
if ($con === null) {
|
if ($con === null) {
|
||||||
$con = Propel::getConnection(self::DATABASE_NAME);
|
$con = Propel::getConnection(self::DATABASE_NAME);
|
||||||
}
|
}
|
||||||
|
$criteria = new Criteria();
|
||||||
$criteria = new Criteria(AppTimeoutActionExecutedPeer::DATABASE_NAME);
|
$criteria->add(AppTimeoutActionExecutedPeer::APP_UID, $app_uid);
|
||||||
|
$criteria->add(AppTimeoutActionExecutedPeer::DEL_INDEX, $del_index);
|
||||||
$criteria->add(AppTimeoutActionExecutedPeer::APP_UID, $pk);
|
|
||||||
|
|
||||||
|
|
||||||
$v = AppTimeoutActionExecutedPeer::doSelect($criteria, $con);
|
$v = AppTimeoutActionExecutedPeer::doSelect($criteria, $con);
|
||||||
|
|
||||||
return !empty($v) > 0 ? $v[0] : null;
|
return !empty($v) ? $v[0] : null;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve multiple objects by pkey.
|
|
||||||
*
|
|
||||||
* @param array $pks List of primary keys
|
|
||||||
* @param Connection $con the connection to use
|
|
||||||
* @throws PropelException Any exceptions caught during processing will be
|
|
||||||
* rethrown wrapped into a PropelException.
|
|
||||||
*/
|
|
||||||
public static function retrieveByPKs($pks, $con = null)
|
|
||||||
{
|
|
||||||
if ($con === null) {
|
|
||||||
$con = Propel::getConnection(self::DATABASE_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
$objs = null;
|
|
||||||
if (empty($pks)) {
|
|
||||||
$objs = array();
|
|
||||||
} else {
|
|
||||||
$criteria = new Criteria();
|
|
||||||
$criteria->add(AppTimeoutActionExecutedPeer::APP_UID, $pks, Criteria::IN);
|
|
||||||
$objs = AppTimeoutActionExecutedPeer::doSelect($criteria, $con);
|
|
||||||
}
|
|
||||||
return $objs;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4303,7 +4303,7 @@
|
|||||||
|
|
||||||
<table name="APP_TIMEOUT_ACTION_EXECUTED">
|
<table name="APP_TIMEOUT_ACTION_EXECUTED">
|
||||||
<column name="APP_UID" type="VARCHAR" size="32" required="true" default="" primaryKey="true"/>
|
<column name="APP_UID" type="VARCHAR" size="32" required="true" default="" primaryKey="true"/>
|
||||||
<column name="DEL_INDEX" type="INTEGER" required="true" default="0"/>
|
<column name="DEL_INDEX" type="INTEGER" required="true" default="0" primaryKey="true"/>
|
||||||
<column name="EXECUTION_DATE" type="TIMESTAMP" required="false"/>
|
<column name="EXECUTION_DATE" type="TIMESTAMP" required="false"/>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|||||||
@@ -2314,7 +2314,7 @@ CREATE TABLE `APP_TIMEOUT_ACTION_EXECUTED`
|
|||||||
`APP_UID` VARCHAR(32) default '' NOT NULL,
|
`APP_UID` VARCHAR(32) default '' NOT NULL,
|
||||||
`DEL_INDEX` INTEGER default 0 NOT NULL,
|
`DEL_INDEX` INTEGER default 0 NOT NULL,
|
||||||
`EXECUTION_DATE` DATETIME,
|
`EXECUTION_DATE` DATETIME,
|
||||||
PRIMARY KEY (`APP_UID`)
|
PRIMARY KEY (`APP_UID`,`DEL_INDEX`)
|
||||||
)ENGINE=InnoDB ;
|
)ENGINE=InnoDB ;
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
#-- ADDONS_STORE
|
#-- ADDONS_STORE
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use ProcessMaker\AuditLog\AuditLog;
|
use ProcessMaker\Log\AuditLog;
|
||||||
|
|
||||||
global $RBAC;
|
global $RBAC;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use ProcessMaker\AuditLog\AuditLog;
|
use ProcessMaker\Log\AuditLog;
|
||||||
|
|
||||||
$auditLog = new AuditLog();
|
$auditLog = new AuditLog();
|
||||||
$auditLog->setUserLogged($_SESSION["USER_LOGGED"]);
|
$auditLog->setUserLogged($_SESSION["USER_LOGGED"]);
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ use Applications;
|
|||||||
use AppNotes;
|
use AppNotes;
|
||||||
use AppNotesPeer;
|
use AppNotesPeer;
|
||||||
use AppSolr;
|
use AppSolr;
|
||||||
|
use AppTimeoutActionExecuted;
|
||||||
use BasePeer;
|
use BasePeer;
|
||||||
use Bootstrap;
|
use Bootstrap;
|
||||||
use BpmnEngineServicesSearchIndex;
|
use BpmnEngineServicesSearchIndex;
|
||||||
@@ -25,6 +26,7 @@ use CasesPeer;
|
|||||||
use Configurations;
|
use Configurations;
|
||||||
use CreoleTypes;
|
use CreoleTypes;
|
||||||
use Criteria;
|
use Criteria;
|
||||||
|
use DateTime;
|
||||||
use DBAdapter;
|
use DBAdapter;
|
||||||
use EntitySolrRequestData;
|
use EntitySolrRequestData;
|
||||||
use Exception;
|
use Exception;
|
||||||
@@ -44,8 +46,11 @@ use ProcessMaker\Exception\UploadException;
|
|||||||
use ProcessMaker\Exception\CaseNoteUploadFile;
|
use ProcessMaker\Exception\CaseNoteUploadFile;
|
||||||
use ProcessMaker\Model\Application as ModelApplication;
|
use ProcessMaker\Model\Application as ModelApplication;
|
||||||
use ProcessMaker\Model\AppNotes as Notes;
|
use ProcessMaker\Model\AppNotes as Notes;
|
||||||
|
use ProcessMaker\Model\AppTimeoutAction;
|
||||||
use ProcessMaker\Model\Delegation;
|
use ProcessMaker\Model\Delegation;
|
||||||
use ProcessMaker\Model\Documents;
|
use ProcessMaker\Model\Documents;
|
||||||
|
use ProcessMaker\Model\ListUnassigned;
|
||||||
|
use ProcessMaker\Model\Triggers;
|
||||||
use ProcessMaker\Plugins\PluginRegistry;
|
use ProcessMaker\Plugins\PluginRegistry;
|
||||||
use ProcessMaker\Services\OAuth2\Server;
|
use ProcessMaker\Services\OAuth2\Server;
|
||||||
use ProcessMaker\Util\DateTime as UtilDateTime;
|
use ProcessMaker\Util\DateTime as UtilDateTime;
|
||||||
@@ -4107,4 +4112,127 @@ class Cases
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the cases related to the self services timeout that needs to execute the trigger related
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static function executeSelfServiceTimeout()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$casesSelfService = ListUnassigned::selfServiceTimeout();
|
||||||
|
$casesExecuted = [];
|
||||||
|
foreach ($casesSelfService as $row) {
|
||||||
|
$appUid = $row["APP_UID"];
|
||||||
|
$appNumber = $row["APP_NUMBER"];
|
||||||
|
$delIndex = $row["DEL_INDEX"];
|
||||||
|
$delegateDate = $row["DEL_DELEGATE_DATE"];
|
||||||
|
$proUid = $row["PRO_UID"];
|
||||||
|
$taskUid = $row["TAS_UID"];
|
||||||
|
$taskSelfServiceTime = intval($row["TAS_SELFSERVICE_TIME"]);
|
||||||
|
$taskSelfServiceTimeUnit = $row["TAS_SELFSERVICE_TIME_UNIT"];
|
||||||
|
$triggerUid = $row["TAS_SELFSERVICE_TRIGGER_UID"];
|
||||||
|
|
||||||
|
/*----------------------------------********---------------------------------*/
|
||||||
|
$typeOfExecution = $row["TAS_SELFSERVICE_EXECUTION"];
|
||||||
|
$flagExecuteOnce = true;
|
||||||
|
// This option will be executed just once, can check if was executed before
|
||||||
|
if ($typeOfExecution == 'ONCE') {
|
||||||
|
$appTimeout = new AppTimeoutAction();
|
||||||
|
$appTimeout->setCaseUid($appUid);
|
||||||
|
$appTimeout->setIndex($delIndex);
|
||||||
|
$caseExecuted = $appTimeout->cases();
|
||||||
|
$flagExecuteOnce = !empty($caseExecuted) ? false : true;
|
||||||
|
}
|
||||||
|
/*----------------------------------********---------------------------------*/
|
||||||
|
|
||||||
|
// Add the time in the corresponding unit to the delegation date
|
||||||
|
$delegateDate = calculateDate($delegateDate, $taskSelfServiceTimeUnit, $taskSelfServiceTime);
|
||||||
|
|
||||||
|
// Define the current time
|
||||||
|
$datetime = new DateTime('now');
|
||||||
|
$currentDate = $datetime->format('Y-m-d H:i:s');
|
||||||
|
|
||||||
|
// Check if the triggers to be executed
|
||||||
|
if ($currentDate >= $delegateDate && $flagExecuteOnce) {
|
||||||
|
// Review if the session process is defined
|
||||||
|
$sessProcess = null;
|
||||||
|
$sessProcessSw = false;
|
||||||
|
if (isset($_SESSION["PROCESS"])) {
|
||||||
|
$sessProcess = $_SESSION["PROCESS"];
|
||||||
|
$sessProcessSw = true;
|
||||||
|
}
|
||||||
|
// Load case data
|
||||||
|
$case = new ClassesCases();
|
||||||
|
$appFields = $case->loadCase($appUid);
|
||||||
|
$appFields["APP_DATA"]["APPLICATION"] = $appUid;
|
||||||
|
// Set the process defined in the case related
|
||||||
|
$_SESSION["PROCESS"] = $appFields["PRO_UID"];
|
||||||
|
|
||||||
|
// Get the trigger related and execute
|
||||||
|
$triggersList = [];
|
||||||
|
if (!empty($triggerUid)) {
|
||||||
|
$trigger = new Triggers();
|
||||||
|
$trigger->setTrigger($triggerUid);
|
||||||
|
$triggersList = $trigger->triggers();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the trigger exist, let's to execute
|
||||||
|
if (!empty($triggersList)) {
|
||||||
|
// Execute the trigger defined in the self service timeout
|
||||||
|
$fieldsCase['APP_DATA'] = $case->executeTriggerFromList(
|
||||||
|
$triggersList,
|
||||||
|
$appFields['APP_DATA'],
|
||||||
|
'SELF_SERVICE_TIMEOUT',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
// Update the case
|
||||||
|
$case->updateCase($appUid, $fieldsCase);
|
||||||
|
|
||||||
|
/*----------------------------------********---------------------------------*/
|
||||||
|
if ($typeOfExecution == 'ONCE') {
|
||||||
|
// Saving the case`s data if the 'Execution' is set in ONCE.
|
||||||
|
$appTimeoutActionExecuted = new AppTimeoutActionExecuted();
|
||||||
|
$dataSelf = [];
|
||||||
|
$dataSelf["APP_UID"] = $appUid;
|
||||||
|
$dataSelf["DEL_INDEX"] = $delIndex;
|
||||||
|
$dataSelf["EXECUTION_DATE"] = time();
|
||||||
|
$appTimeoutActionExecuted->create($dataSelf);
|
||||||
|
}
|
||||||
|
/*----------------------------------********---------------------------------*/
|
||||||
|
|
||||||
|
array_push($casesExecuted, $appNumber); // Register the cases executed
|
||||||
|
|
||||||
|
// Logging this action
|
||||||
|
$context = [
|
||||||
|
'appUid' => $appUid,
|
||||||
|
'appNumber' => $appNumber,
|
||||||
|
'triUid' => $triggerUid,
|
||||||
|
'proUid' => $proUid,
|
||||||
|
'tasUid' => $taskUid,
|
||||||
|
'selfServiceTime' => $taskSelfServiceTime,
|
||||||
|
'selfServiceTimeUnit' => $taskSelfServiceTimeUnit,
|
||||||
|
];
|
||||||
|
Log::channel(':TriggerExecution')->info('Timeout trigger execution', Bootstrap::context($context));
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($_SESSION["PROCESS"]);
|
||||||
|
|
||||||
|
if ($sessProcessSw) {
|
||||||
|
$_SESSION["PROCESS"] = $sessProcess;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $casesExecuted;
|
||||||
|
} catch (Exception $e) {
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace ProcessMaker\AuditLog;
|
namespace ProcessMaker\Log;
|
||||||
|
|
||||||
use Bootstrap;
|
use Bootstrap;
|
||||||
use Configurations;
|
use Configurations;
|
||||||
103
workflow/engine/src/ProcessMaker/Model/AppTimeoutAction.php
Normal file
103
workflow/engine/src/ProcessMaker/Model/AppTimeoutAction.php
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace ProcessMaker\Model;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class AppTimeoutAction extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'APP_TIMEOUT_ACTION_EXECUTED';
|
||||||
|
// We do not have create/update timestamps for this table
|
||||||
|
public $timestamps = false;
|
||||||
|
// Filter by a specific case using case number
|
||||||
|
private $caseUid = '';
|
||||||
|
// Filter by a specific index
|
||||||
|
private $index = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Case Uid
|
||||||
|
*
|
||||||
|
* @param string $caseUid
|
||||||
|
*/
|
||||||
|
public function setCaseUid($caseUid)
|
||||||
|
{
|
||||||
|
$this->caseUid = $caseUid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Case Uid
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getCaseUid()
|
||||||
|
{
|
||||||
|
return $this->caseUid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set index
|
||||||
|
*
|
||||||
|
* @param int $index
|
||||||
|
*/
|
||||||
|
public function setIndex($index)
|
||||||
|
{
|
||||||
|
$this->index = $index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get index
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getIndex()
|
||||||
|
{
|
||||||
|
return $this->index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scope a query to get specific case uid
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||||
|
* @param string $appUid
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Builder
|
||||||
|
*/
|
||||||
|
public function scopeCase($query, $appUid)
|
||||||
|
{
|
||||||
|
return $query->where('APP_UID', $appUid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scope a query to get index
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||||
|
* @param int $index
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Builder
|
||||||
|
*/
|
||||||
|
public function scopeIndex($query, $index)
|
||||||
|
{
|
||||||
|
return $query->where('DEL_INDEX', $index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the records related to the case and index if it was defined
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function cases()
|
||||||
|
{
|
||||||
|
$query = AppTimeoutAction::query()->select();
|
||||||
|
// Specific case uid
|
||||||
|
if (!empty($this->getCaseUid())) {
|
||||||
|
$query->case($this->getCaseUid());
|
||||||
|
}
|
||||||
|
// Specific index
|
||||||
|
if (!empty($this->getIndex())) {
|
||||||
|
$query->index($this->getIndex());
|
||||||
|
}
|
||||||
|
$results = $query->get()->toArray();
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -48,6 +48,7 @@ class ListUnassigned extends Model
|
|||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||||
* @param array $tasks
|
* @param array $tasks
|
||||||
|
*
|
||||||
* @return \Illuminate\Database\Eloquent\Builder
|
* @return \Illuminate\Database\Eloquent\Builder
|
||||||
*/
|
*/
|
||||||
public function scopeTasksIn($query, array $tasks)
|
public function scopeTasksIn($query, array $tasks)
|
||||||
@@ -100,7 +101,7 @@ class ListUnassigned extends Model
|
|||||||
* @param string $userUid
|
* @param string $userUid
|
||||||
* @param array $filters
|
* @param array $filters
|
||||||
*
|
*
|
||||||
* @return array
|
* @return int
|
||||||
*/
|
*/
|
||||||
public static function doCount($userUid, $filters = [])
|
public static function doCount($userUid, $filters = [])
|
||||||
{
|
{
|
||||||
@@ -125,4 +126,21 @@ class ListUnassigned extends Model
|
|||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the unassigned cases related to the self service timeout
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function selfServiceTimeout()
|
||||||
|
{
|
||||||
|
$query = ListUnassigned::query()->select();
|
||||||
|
$query->join('TASK', function ($join) {
|
||||||
|
$join->on('LIST_UNASSIGNED.TAS_ID', '=', 'TASK.TAS_ID')
|
||||||
|
->where('TASK.TAS_SELFSERVICE_TIMEOUT', '=', 1);
|
||||||
|
});
|
||||||
|
$results = $query->get()->toArray();
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,34 @@ class Triggers extends Model
|
|||||||
protected $table = 'TRIGGERS';
|
protected $table = 'TRIGGERS';
|
||||||
// No timestamps
|
// No timestamps
|
||||||
public $timestamps = false;
|
public $timestamps = false;
|
||||||
//primary key
|
// Primary key
|
||||||
protected $primaryKey = 'TRI_UID';
|
protected $primaryKey = 'TRI_UID';
|
||||||
//No incrementing
|
// No incrementing
|
||||||
public $incrementing = false;
|
public $incrementing = false;
|
||||||
|
|
||||||
|
// Filter by a specific uid
|
||||||
|
private $triUid = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set trigger uid
|
||||||
|
*
|
||||||
|
* @param string $triUid
|
||||||
|
*/
|
||||||
|
public function setTrigger($triUid)
|
||||||
|
{
|
||||||
|
$this->triUid = $triUid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get trigger uid
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getTrigger()
|
||||||
|
{
|
||||||
|
return $this->triUid;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scope a query to filter an specific process
|
* Scope a query to filter an specific process
|
||||||
*
|
*
|
||||||
@@ -22,8 +45,37 @@ class Triggers extends Model
|
|||||||
* @param string $columns
|
* @param string $columns
|
||||||
* @return \Illuminate\Database\Eloquent\Builder
|
* @return \Illuminate\Database\Eloquent\Builder
|
||||||
*/
|
*/
|
||||||
public function scopeProcess($query, string $proUID)
|
public function scopeProcess($query, string $proUid)
|
||||||
{
|
{
|
||||||
return $query->where('PRO_UID', $proUID);
|
return $query->where('PRO_UID', $proUid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scope a query to filter an specific trigger
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||||
|
* @param string $triUid
|
||||||
|
* @return \Illuminate\Database\Eloquent\Builder
|
||||||
|
*/
|
||||||
|
public function scopeTrigger($query, string $triUid)
|
||||||
|
{
|
||||||
|
return $query->where('TRI_UID', $triUid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the records
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function triggers()
|
||||||
|
{
|
||||||
|
$query = Triggers::query()->select();
|
||||||
|
// Specific trigger
|
||||||
|
if (!empty($this->getTrigger())) {
|
||||||
|
$query->trigger($this->getTrigger());
|
||||||
|
}
|
||||||
|
$results = $query->get()->toArray();
|
||||||
|
|
||||||
|
return $results;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -640,3 +640,33 @@ function saveAppDocument($file, $appUid, $appDocUid, $version = 1, $upload = tru
|
|||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a specific date minutes, hours or days
|
||||||
|
*
|
||||||
|
* @param string $iniDate
|
||||||
|
* @param string $timeUnit
|
||||||
|
* @param int $time
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*
|
||||||
|
* @link https://www.php.net/manual/en/datetime.modify.php
|
||||||
|
*/
|
||||||
|
function calculateDate($iniDate, $timeUnit, $time)
|
||||||
|
{
|
||||||
|
|
||||||
|
$datetime = new DateTime($iniDate);
|
||||||
|
switch ($timeUnit) {
|
||||||
|
case 'DAYS':
|
||||||
|
$datetime->modify('+' . $time . ' day');
|
||||||
|
break;
|
||||||
|
case 'HOURS':
|
||||||
|
$datetime->modify('+' . $time . ' hour');
|
||||||
|
break;
|
||||||
|
case 'MINUTES':
|
||||||
|
$datetime->modify('+' . $time . ' minutes');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $datetime->format('Y-m-d H:i:s');
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user