Merge with develop: solving conflicts

This commit is contained in:
Paula Quispe
2019-05-29 13:12:45 -04:00
93 changed files with 6342 additions and 6993 deletions

1
.gitignore vendored
View File

@@ -41,3 +41,4 @@ node_modules
test_shared/
**/cache/
storage/
phpunit.xml

View File

@@ -40,7 +40,7 @@
"monolog/monolog": "1.19.0",
"geshi/geshi": "dev-master",
"libchart/libchart": "1.4.0",
"phpmailer/phpmailer": "5.2.4",
"phpmailer/phpmailer": "5.2.27",
"pear/archive_tar": "1.4.*",
"pear/console_getopt": "1.4.*",
"TYPO3/class-alias-loader": "^1.0",
@@ -48,7 +48,10 @@
"smarty/smarty": "2.6.30",
"pdepend/pdepend": "@stable",
"chumper/zipper": "^1.0",
"php-imap/php-imap": "^3.0"
"php-imap/php-imap": "^3.0",
"nikic/php-parser": "3.1.5",
"laravel/tinker": "^1.0"
},
"require-dev": {
"fzaninotto/faker": "^1.7",

355
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -23,7 +23,9 @@ return [
Illuminate\Queue\QueueServiceProvider::class,
Illuminate\Translation\TranslationServiceProvider::class,
Illuminate\Encryption\EncryptionServiceProvider::class,
ViewServiceProvider::class
Laravel\Tinker\TinkerServiceProvider::class,
ViewServiceProvider::class,
],
'aliases' => [
'Crypt' => Illuminate\Support\Facades\Crypt::class

View File

@@ -0,0 +1,18 @@
<?php
/**
* Model factory for a APP_ASSIGN_SELF_SERVICE_VALUE
*/
use Faker\Generator as Faker;
$factory->define(\ProcessMaker\Model\AppAssignSelfServiceValue::class, function(Faker $faker) {
return [
'ID' => $faker->unique()->numberBetween(1, 2000),
'APP_UID' => G::generateUniqueID(),
'DEL_INDEX' => 2,
'PRO_UID' => G::generateUniqueID(),
'TAS_UID' => G::generateUniqueID(),
'TAS_ID' => $faker->unique()->numberBetween(1, 2000),
'GRP_UID' => G::generateUniqueID(),
];
});

View File

@@ -0,0 +1,15 @@
<?php
/**
* Model factory for a APP_ASSIGN_SELF_SERVICE_VALUE_GROUP
*/
use Faker\Generator as Faker;
$factory->define(\ProcessMaker\Model\AppAssignSelfServiceValueGroup::class, function(Faker $faker) {
return [
'ID' => $faker->unique()->numberBetween(1, 2000),
'GRP_UID' => G::generateUniqueID(),
'ASSIGNEE_ID' => $faker->unique()->numberBetween(1, 2000),
'ASSIGNEE_TYPE' => $faker->unique()->numberBetween(1, 2000),
];
});

View File

@@ -0,0 +1,26 @@
<?php
use Faker\Generator as Faker;
use ProcessMaker\BusinessModel\Cases as BmCases;
$factory->define(\ProcessMaker\Model\Application::class, function(Faker $faker) {
$process = \ProcessMaker\Model\Process::all()->random();
$statuses = ['DRAFT', 'TO_DO'];
$status = $faker->randomElement($statuses);
$statusId = array_search($status, $statuses) + 1;
return [
'APP_UID' => G::generateUniqueID(),
'APP_TITLE' => G::generateUniqueID(),
'APP_NUMBER' => $faker->unique()->numberBetween(1000),
'APP_STATUS' => $status,
'APP_STATUS_ID' => $statusId,
'PRO_UID' => $process->PRO_UID,
'APP_PARALLEL' => 'N',
'APP_INIT_USER' => \ProcessMaker\Model\User::all()->random()->USR_UID,
'APP_CUR_USER' => \ProcessMaker\Model\User::all()->random()->USR_UID,
'APP_PIN' => G::generateUniqueID(),
'APP_CREATE_DATE' => $faker->dateTime(),
'APP_UPDATE_DATE' => $faker->dateTime(),
'APP_INIT_DATE' => $faker->dateTime(),
'APP_DATA' => serialize(['APP_NUMBER' => 12])
];
});

View File

@@ -0,0 +1,76 @@
<?php
use Faker\Generator as Faker;
$factory->define(\ProcessMaker\Model\Delegation::class, function(Faker $faker) {
$app = factory(\ProcessMaker\Model\Application::class)->create();
$process = \ProcessMaker\Model\Process::where('PRO_UID', $app->PRO_UID)->first();
$task = $process->tasks->first();
// Grab a user if random
$users = \ProcessMaker\Model\User::all();
if(!count($users)) {
$user = factory(\ProcessMaker\Model\User::class)->create();
} else{
$user = $users->random();
}
// Return with default values
return [
'APP_UID' => $app->APP_UID,
'DEL_INDEX' => 1,
'APP_NUMBER' => $app->APP_NUMBER,
'DEL_PREVIOUS' => 0,
'PRO_UID' => $app->PRO_UID,
'TAS_UID' => $task->TAS_UID,
'USR_UID' => $user->USR_UID,
'DEL_TYPE' => 'NORMAL',
'DEL_THREAD' => 1,
'DEL_THREAD_STATUS' => 'OPEN',
'DEL_PRIORITY' => 3,
'DEL_DELEGATE_DATE' => $faker->dateTime(),
'DEL_INIT_DATE' => $faker->dateTime(),
'DEL_TASK_DUE_DATE' => $faker->dateTime(),
'DEL_RISK_DATE' => $faker->dateTime(),
'USR_ID' => $user->USR_ID,
'PRO_ID' => $process->PRO_ID,
'TAS_ID' => $task->TAS_ID,
'DEL_DATA' => ''
];
});
// Create a open delegation
$factory->state(\ProcessMaker\Model\Delegation::class, 'open', function (Faker $faker) {
// Create dates with sense
$delegateDate = $faker->dateTime();
$initDate = $faker->dateTimeInInterval($delegateDate, '+30 minutes');
$riskDate = $faker->dateTimeInInterval($initDate, '+1 day');
$taskDueDate = $faker->dateTimeInInterval($riskDate, '+1 day');
return [
'DEL_THREAD_STATUS' => 'OPEN',
'DEL_DELEGATE_DATE' => $delegateDate,
'DEL_INIT_DATE' => $initDate,
'DEL_RISK_DATE' => $riskDate,
'DEL_TASK_DUE_DATE' => $taskDueDate,
'DEL_FINISH_DATE' => null
];
});
// Create a closed delegation
$factory->state(\ProcessMaker\Model\Delegation::class, 'closed', function (Faker $faker) {
// Create dates with sense
$delegateDate = $faker->dateTime();
$initDate = $faker->dateTimeInInterval($delegateDate, '+30 minutes');
$riskDate = $faker->dateTimeInInterval($initDate, '+1 day');
$taskDueDate = $faker->dateTimeInInterval($riskDate, '+1 day');
$finishDate = $faker->dateTimeInInterval($initDate, '+10 days');
return [
'DEL_THREAD_STATUS' => 'CLOSED',
'DEL_DELEGATE_DATE' => $delegateDate,
'DEL_INIT_DATE' => $initDate,
'DEL_RISK_DATE' => $riskDate,
'DEL_TASK_DUE_DATE' => $taskDueDate,
'DEL_FINISH_DATE' => $finishDate
];
});

View File

@@ -0,0 +1,26 @@
<?php
/**
* Model factory for a dynaform.
*/
use Faker\Generator as Faker;
$factory->define(\ProcessMaker\Model\Dynaform::class, function(Faker $faker) {
$date = $faker->dateTime();
return [
'DYN_UID' => G::generateUniqueID(),
'DYN_ID' => '',
'DYN_TITLE' => '',
'DYN_DESCRIPTION' => '',
'PRO_UID' => function() {
$process = factory(\ProcessMaker\Model\Process::class)->create();
return $process->PRO_UID;
},
'DYN_TYPE' => 'xmlform',
'DYN_FILENAME' => '',
'DYN_CONTENT' => '',
'DYN_LABEL' => '',
'DYN_VERSION' => 2,
'DYN_UPDATE_DATE' => $date->format('Y-m-d H:i:s'),
];
});

View File

@@ -0,0 +1,14 @@
<?php
/**
* Model factory for a group user relation
*/
use Faker\Generator as Faker;
$factory->define(\ProcessMaker\Model\GroupUser::class, function(Faker $faker) {
return [
'GRP_UID' => G::generateUniqueID(),
'GRP_ID' => $faker->unique()->numberBetween(1, 2000),
'USR_UID' => G::generateUniqueID()
];
});

View File

@@ -0,0 +1,17 @@
<?php
/**
* Model factory for a groups
*/
use Faker\Generator as Faker;
$factory->define(\ProcessMaker\Model\Groupwf::class, function(Faker $faker) {
return [
'GRP_UID' => G::generateUniqueID(),
'GRP_ID' => $faker->unique()->numberBetween(1, 2000),
'GRP_TITLE' => $faker->sentence(2),
'GRP_STATUS' => 'ACTIVE',
'GRP_LDAP_DN' => '',
'GRP_UX' => 'NORMAL',
];
});

View File

@@ -0,0 +1,40 @@
<?php
/**
* Model factory for a list unassigned
*/
use Faker\Generator as Faker;
$factory->define(\ProcessMaker\Model\ListUnassigned::class, function (Faker $faker) {
$app = factory(\ProcessMaker\Model\Application::class)->create();
$process = \ProcessMaker\Model\Process::where('PRO_UID', $app->PRO_UID)->first();
$task = $process->tasks->first();
// Grab a user if random
$users = \ProcessMaker\Model\User::all();
if(!count($users)) {
$user = factory(\ProcessMaker\Model\User::class)->create();
} else{
$user = $users->random();
}
return [
'APP_UID' => $app->APP_UID,
'DEL_INDEX' => 1,
'TAS_UID' => $task->TAS_UID,
'PRO_UID' => $app->PRO_UID,
'APP_NUMBER' => $app->APP_NUMBER,
'APP_TITLE' => $app->APP_TITLE,
'APP_PRO_TITLE' => $process->PRO_TITLE,
'APP_TAS_TITLE' => $task->TAS_TITLE,
'DEL_PREVIOUS_USR_USERNAME' => $user->USR_USERNAME,
'DEL_PREVIOUS_USR_FIRSTNAME' => $user->USR_FIRSTNAME,
'DEL_PREVIOUS_USR_LASTNAME' => $user->USR_LASTNAME,
'APP_UPDATE_DATE' => $faker->dateTime(),
'DEL_PREVIOUS_USR_UID' => G::generateUniqueID(),
'DEL_DELEGATE_DATE' => $faker->dateTime(),
'DEL_DUE_DATE' => $faker->dateTime(),
'DEL_PRIORITY' => 3,
'PRO_ID' => $process->PRO_ID,
'TAS_ID' => $task->TAS_ID,
];
});

View File

@@ -0,0 +1,14 @@
<?php
/**
* Model factory for a process category
*/
use Faker\Generator as Faker;
$factory->define(\ProcessMaker\Model\ProcessCategory::class, function (Faker $faker) {
return [
'CATEGORY_UID' => G::generateUniqueID(),
'CATEGORY_PARENT' => '',
'CATEGORY_NAME' => $faker->sentence(5),
'CATEGORY_ICON' => '',
];
});

View File

@@ -5,13 +5,57 @@
use Faker\Generator as Faker;
$factory->define(\ProcessMaker\Model\Process::class, function(Faker $faker) {
/**
* @todo Determine if we need more base columns populated
*/
return [
$process = [
'PRO_UID' => G::generateUniqueID(),
'PRO_TITLE' => $faker->sentence(3),
'PRO_DESCRIPTION' => $faker->paragraph(3)
'PRO_DESCRIPTION' => $faker->paragraph(3),
'PRO_CREATE_USER' => '00000000000000000000000000000001',
'PRO_DYNAFORMS' => '',
'PRO_ITEE' => 1,
'PRO_STATUS' => 'ACTIVE'
];
$task1 = factory(\ProcessMaker\Model\Task::class)
->create([
'PRO_UID' => $process['PRO_UID'],
'TAS_START'=>'TRUE'
]);
$task2 = factory(\ProcessMaker\Model\Task::class)
->create([
'PRO_UID' => $process['PRO_UID'],
]);
//routes
factory(\ProcessMaker\Model\Route::class)
->create([
'PRO_UID' => $process['PRO_UID'],
'TAS_UID' => $task2['TAS_UID'],
'ROU_NEXT_TASK' => '-1',
]);
factory(\ProcessMaker\Model\Route::class)
->create([
'PRO_UID' => $process['PRO_UID'],
'TAS_UID' => $task1['TAS_UID'],
'ROU_NEXT_TASK' => $task2['TAS_UID']
]);
//User assignments
factory(\ProcessMaker\Model\TaskUser::class)
->create([
'TAS_UID' => $task1['TAS_UID'],
'USR_UID' => \ProcessMaker\Model\User::all()->random()->USR_UID
]);
factory(\ProcessMaker\Model\TaskUser::class)
->create([
'TAS_UID' => $task2['TAS_UID'],
'USR_UID' => \ProcessMaker\Model\User::all()->random()->USR_UID
]);
return $process;
});

View File

@@ -0,0 +1,22 @@
<?php
/**
* Model factory for a process
*/
use Faker\Generator as Faker;
$factory->define(\ProcessMaker\Model\Route::class, function(Faker $faker) {
return [
'PRO_UID' => function() {
$process = factory(\ProcessMaker\Model\Process::class)->create();
return $process->PRO_UID;
},
'TAS_UID' => function() {
$task = factory(\ProcessMaker\Model\Task::class)->create();
return $task->TAS_UID;
},
'ROU_UID' => G::generateUniqueID(),
'ROU_PARENT' => 0,
'ROU_CASE' => 1,
'ROU_TYPE' => 'SEQUENTIAL'
];
});

View File

@@ -0,0 +1,35 @@
<?php
/**
* Model factory for a process
*/
use Faker\Generator as Faker;
$factory->define(\ProcessMaker\Model\Task::class, function(Faker $faker) {
return [
'PRO_UID' => function() {
$process = factory(\ProcessMaker\Model\Process::class)->create();
return $process->PRO_UID;
},
'TAS_UID' => G::generateUniqueID(),
'TAS_ID' => $faker->unique()->numberBetween(1, 100000),
'TAS_TITLE' => $faker->sentence(2),
'TAS_TYPE' => 'NORMAL',
'TAS_TYPE_DAY' => 1,
'TAS_DURATION' => 1,
'TAS_ASSIGN_TYPE' => 'BALANCED',
'TAS_ASSIGN_VARIABLE' => '@@SYS_NEXT_USER_TO_BE_ASSIGNED',
'TAS_MI_INSTANCE_VARIABLE' => '@@SYS_VAR_TOTAL_INSTANCE',
'TAS_MI_COMPLETE_VARIABLE' => '@@SYS_VAR_TOTAL_INSTANCES_COMPLETE',
'TAS_ASSIGN_LOCATION' => 'FALSE',
'TAS_ASSIGN_LOCATION_ADHOC' => 'FALSE',
'TAS_TRANSFER_FLY' => 'FALSE',
'TAS_LAST_ASSIGNED' => 0,
'TAS_USER' => 0,
'TAS_CAN_UPLOAD' => 'FALSE',
'TAS_CAN_CANCEL' => 'FALSE',
'TAS_OWNER_APP' => 'FALSE',
'TAS_CAN_SEND_MESSAGE' => 'FALSE',
'TAS_SEND_LAST_EMAIL' => 'FALSE',
];
});

View File

@@ -0,0 +1,16 @@
<?php
/**
* Model factory for a process
*/
use Faker\Generator as Faker;
$factory->define(\ProcessMaker\Model\TaskUser::class, function(Faker $faker) {
return [
'TAS_UID' => function() {
$task = factory(\ProcessMaker\Model\Task::class)->create();
return $task->TAS_UID;
},
'TU_TYPE' => 1,
'TU_RELATION' => 1
];
});

View File

@@ -0,0 +1,19 @@
<?php
use Faker\Generator as Faker;
$factory->define(\ProcessMaker\Model\User::class, function(Faker $faker) {
return [
'USR_UID' => G::generateUniqueID(),
'USR_USERNAME' => $faker->unique()->userName,
'USR_PASSWORD' => $faker->password,
'USR_FIRSTNAME' => $faker->firstName,
'USR_LASTNAME' => $faker->lastName,
'USR_EMAIL' => $faker->unique()->email,
'USR_DUE_DATE' => new \Carbon\Carbon(2030,1,1),
'USR_STATUS' => 'ACTIVE',
'USR_ROLE' => $faker->randomElement(['PROCESSMAKER_ADMIN', 'PROCESSMAKER_OPERATOR']),
'USR_UX' => 'NORMAL',
'USR_TIME_ZONE' => 'America/Anguilla',
'USR_DEFAULT_LANG' => 'en',
];
});

View File

@@ -1348,8 +1348,7 @@ class Bootstrap
*
* @return void
*/
// _Internal: Remove recursion in result array
public function _del_p(&$ary)
public static function _del_p(&$ary)
{
foreach ($ary as $k => $v) {
if ($k === '_p') {

View File

@@ -1636,13 +1636,16 @@ class G
/**
* Escapes special characters in a string for use in a SQL statement
* @param string $sqlString The string to be escaped
* @param string $DBEngine Target DBMS
*/
public function sqlEscape($sqlString, $DBEngine = DB_ADAPTER)
* @param string $sqlString The string to be escaped
* @param string $dbEngine Target DBMS
*
* @return string
*/
public static function sqlEscape($sqlString, $dbEngine = DB_ADAPTER)
{
$DBEngine = DB_ADAPTER;
switch ($DBEngine) {
// @todo: Research why always this value is set with the same constant?
$dbEngine = DB_ADAPTER;
switch ($dbEngine) {
case 'mysql':
$con = Propel::getConnection('workflow');
return mysqli_real_escape_string($con->getResource(), stripslashes($sqlString));
@@ -1689,9 +1692,15 @@ class G
* @# Non-quoted parameter
* @! Evaluate string : Replace the parameters in value and then in the sql string
* @fn() Evaluate string with the function "fn"
* @author David Callizaya <calidavidx21@hotmail.com>
*
* @param string $sqlString
* @param array $result
* @param string $dbEngine
* @param bool $applyHtmlEntities
*
* @return string
*/
public static function replaceDataField($sqlString, $result, $DBEngine = 'mysql')
public static function replaceDataField($sqlString, $result, $dbEngine = 'mysql', $applyHtmlEntities = false)
{
if (!is_array($result)) {
$result = array();
@@ -1710,7 +1719,12 @@ class G
$u = $match[0][$r][1] + strlen($match[0][$r][0]);
//Mysql quotes scape
if (($match[1][$r][0] == '@') && (isset($result[$match[2][$r][0]]))) {
$__textoEval .= "\"" . G::sqlEscape($result[$match[2][$r][0]], $DBEngine) . "\"";
$text = ($applyHtmlEntities && !stringIsValidHtml($result[$match[2][$r][0]])) ?
htmlentities(G::unhtmlentities($result[$match[2][$r][0]]), ENT_COMPAT, 'UTF-8') :
$result[$match[2][$r][0]];
// Replenish the tag <br /> because is valid
$text = str_replace('&lt;br /&gt;', '<br />', $text);
$__textoEval .= "\"" . G::sqlEscape($text, $dbEngine) . "\"";
continue;
}
//URL encode
@@ -1730,7 +1744,7 @@ class G
}
//Substring (Sub replaceDataField)
if (($match[1][$r][0] == '!') && (isset($result[$match[2][$r][0]]))) {
$__textoEval .= G::replaceDataField($result[$match[2][$r][0]], $result);
$__textoEval .= G::replaceDataField($result[$match[2][$r][0]], $result, $dbEngine, $applyHtmlEntities);
continue;
}
//Call function
@@ -1748,18 +1762,33 @@ class G
}
//Non-quoted
if (($match[1][$r][0] == '#') && (isset($result[$match[2][$r][0]]))) {
$__textoEval .= G::replaceDataField($result[$match[2][$r][0]], $result);
$text = ($applyHtmlEntities && !stringIsValidHtml($result[$match[2][$r][0]]) && $match[2][$r][0] !== '__ABE__') ?
htmlentities(G::unhtmlentities($result[$match[2][$r][0]]), ENT_COMPAT, 'UTF-8') :
$result[$match[2][$r][0]];
// Replenish the tag <br /> because is valid
$text = str_replace('&lt;br /&gt;', '<br />', $text);
$__textoEval .= G::replaceDataField($text, $result);
continue;
}
//Non-quoted =
if (($match[1][$r][0] == '=') && (isset($result[$match[2][$r][0]]))) {
$__textoEval .= G::replaceDataField($result[$match[2][$r][0]], $result);
$text = ($applyHtmlEntities && !stringIsValidHtml($result[$match[2][$r][0]]) && $match[2][$r][0] !== '__ABE__') ?
htmlentities(G::unhtmlentities($result[$match[2][$r][0]]), ENT_COMPAT, 'UTF-8') :
$result[$match[2][$r][0]];
// Replenish the tag <br /> because is valid
$text = str_replace('&lt;br /&gt;', '<br />', $text);
$__textoEval .= G::replaceDataField($text, $result);
continue;
}
//Objects attributes
if (($match[1][$r][0] == '&') && (isset($result[$match[2][$r][0]]))) {
if (isset($result[$match[2][$r][0]]->{$match[6][$r][0]})) {
$__textoEval .= $result[$match[2][$r][0]]->{$match[6][$r][0]};
$text = ($applyHtmlEntities && !stringIsValidHtml($result[$match[2][$r][0]]->{$match[6][$r][0]})) ?
htmlentities(G::unhtmlentities($result[$match[2][$r][0]]->{$match[6][$r][0]}), ENT_COMPAT, 'UTF-8') :
$result[$match[2][$r][0]]->{$match[6][$r][0]};
// Replenish the tag <br /> because is valid
$text = str_replace('&lt;br /&gt;', '<br />', $text);
$__textoEval .= $text;
}
continue;
}
@@ -1771,27 +1800,35 @@ class G
}
/**
* Replace Grid Values
* The tag @>GRID-NAME to open the grid and @<GRID-NAME to close the grid,
*
* @param type String $sContent
* @param type Array $aFields
* @return type String
*/
public static function replaceDataGridField($sContent, $aFields, $nl2brRecursive = true)
* Replace Grid Values in a string.
* The tag @>GRID-NAME to open the grid and @<GRID-NAME to close the grid,
*
* @param string $content
* @param array $fields
* @param bool $nl2brRecursive
* @param bool $applyHtmlEntities
*
* @return string
*
* @see \Cases->sendMessage()
* @see \WsBase->sendMessage()
* @see \OutputDocument->generate()
* @see \ProcessMaker\BusinessModel\Cases\OutputDocument->generate()
*/
public static function replaceDataGridField($content, $fields, $nl2brRecursive = true, $applyHtmlEntities = false)
{
$nrt = array("\n", "\r", "\t");
$nrthtml = array("(n /)", "(r /)", "(t /)");
$sContent = G::unhtmlentities($sContent);
$strContentAux = str_replace($nrt, $nrthtml, $sContent);
$strContentAux = str_replace($nrt, $nrthtml, $content);
$iOcurrences = preg_match_all('/\@(?:([\>])([a-zA-Z\_]\w*)|([a-zA-Z\_][\w\-\>\:]*)\(((?:[^\\\\\)]*(?:[\\\\][\w\W])?)*)\))((?:\s*\[[\'"]?\w+[\'"]?\])+)?/', $strContentAux, $arrayMatch1, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE);
$occurrences = preg_match_all('/\@(?:([\>])([a-zA-Z\_]\w*)|([a-zA-Z\_][\w\-\>\:]*)\(((?:[^\\\\\)]*(?:[\\\\][\w\W])?)*)\))((?:\s*\[[\'"]?\w+[\'"]?\])+)?/',
$strContentAux, $arrayMatch1, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE);
if ($iOcurrences) {
if ($occurrences) {
$arrayGrid = array();
for ($i = 0; $i <= $iOcurrences - 1; $i++) {
for ($i = 0; $i <= $occurrences - 1; $i++) {
$arrayGrid[] = $arrayMatch1[2][$i][0];
}
@@ -1817,16 +1854,16 @@ class G
while (preg_match($ereg, $strContentAux1, $arrayMatch2)) {
$strData = null;
if (isset($aFields[$grdName]) && is_array($aFields[$grdName])) {
foreach ($aFields[$grdName] as $aRow) {
if (isset($fields[$grdName]) && is_array($fields[$grdName])) {
foreach ($fields[$grdName] as $aRow) {
if ($nl2brRecursive) {
foreach ($aRow as $sKey => $vValue) {
if (!is_array($vValue)) {
$aRow[$sKey] = str_replace($nrt, $nrthtml, nl2br($aRow[$sKey]));
foreach ($aRow as $key => $item) {
if (!is_array($item)) {
$aRow[$key] = str_replace($nrt, $nrthtml, nl2br($aRow[$key]));
}
}
}
$strData = $strData . G::replaceDataField($arrayMatch2[2], $aRow);
$strData = $strData . G::replaceDataField($arrayMatch2[2], $aRow, 'mysql', $applyHtmlEntities);
}
}
@@ -1841,19 +1878,19 @@ class G
$strContentAux = str_replace($nrthtml, $nrt, $strContentAux);
$sContent = $strContentAux;
$content = $strContentAux;
if ($nl2brRecursive) {
foreach ($aFields as $sKey => $vValue) {
if (!is_array($vValue) && !is_object($vValue)) {
$aFields[$sKey] = nl2br($aFields[$sKey]);
foreach ($fields as $key => $item) {
if (!is_array($item) && !is_object($item)) {
$fields[$key] = nl2br($fields[$key]);
}
}
}
$sContent = G::replaceDataField($sContent, $aFields);
$content = G::replaceDataField($content, $fields, 'mysql', $applyHtmlEntities);
return $sContent;
return $content;
}
/**

View File

@@ -15,9 +15,9 @@
<directory>./tests/workflow/engine/src/</directory>
</testsuite>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
</testsuites>
</testsuites>
<filter>
<whitelist addUncoveredFilesFromWhitelist="true" processUncoveredFilesFromWhitelist="false">
@@ -33,31 +33,32 @@
</filter>
<php>
<var name="APP_ENV" value="testing" />
<var name="SYS_SYS" value="test" />
<var name="SYS_LANG" value="en" />
<var name="SYS_SKIN" value="neoclassic" />
<var name="DB_ADAPTER" value="mysql" />
<var name="DB_HOST" value="processmaker3" />
<var name="DB_NAME" value="wf_test" />
<var name="DB_USER" value="root" />
<var name="DB_PASS" value="" />
<var name="PATH_DB" value="./shared/sites/" />
<var name="PATH_DATA" value="./shared/" />
<var name="APP_HOST" value="processmaker3.local" />
<var name="HTTPS" value="off" />
<var name="SERVER_PORT" value="8080" />
<env name="DB_DATABASE" value="test" />
<env name="DB_USERNAME" value="root" />
<env name="DB_PASSWORD" value="" />
<env name="RUN_MSSQL_TESTS" value="true" />
<env name="MSSQL_HOST" value="172.16.3.1" />
<env name="MSSQL_PORT" value="1433" />
<env name="MSSQL_DATABASE" value="testexternal" />
<env name="MSSQL_USERNAME" value="test" />
<env name="MSSQL_PASSWORD" value="test" />
<!--Connection to database-->
<env name="DB_HOST" value="127.0.0.1" />
<env name="DB_DATABASE" value="test" />
<env name="DB_USERNAME" value="root" />
<env name="DB_PASSWORD" value="password" />
<!--Connection to database SQLServer-->
<env name="RUN_MSSQL_TESTS" value="false" />
<env name="MSSQL_HOST" value="172.16.3.1" />
<env name="MSSQL_PORT" value="1433" />
<env name="MSSQL_DATABASE" value="testexternal" />
<env name="MSSQL_USERNAME" value="test" />
<env name="MSSQL_PASSWORD" value="test" />
<!--Php variables-->
<var name="APP_ENV" value="testing" />
<var name="SYS_SYS" value="test" />
<var name="SYS_LANG" value="en" />
<var name="SYS_SKIN" value="neoclassic" />
<var name="DB_ADAPTER" value="mysql" />
<var name="DB_HOST" value="processmaker3" />
<var name="DB_NAME" value="wf_test" />
<var name="DB_USER" value="root" />
<var name="DB_PASS" value="" />
<var name="PATH_DB" value="./shared/sites/" />
<var name="PATH_DATA" value="./shared/" />
<var name="APP_HOST" value="processmaker3.local" />
<var name="HTTPS" value="off" />
<var name="SERVER_PORT" value="8080" />
</php>
</phpunit>

View File

@@ -1,4 +1,5 @@
<?php
/**
* Test harness bootstrap that sets up initial defines and builds up the initial database schema
*/
@@ -13,13 +14,21 @@ use Illuminate\Support\Facades\Schema;
/**
* @todo Migrate to configuration parameters
*/
define('PATH_CORE', 'workflow/engine/');
define('PATH_TRUNK', dirname(__DIR__));
define('PATH_CORE', PATH_TRUNK.'/workflow/engine/');
define('PATH_CONFIG', PATH_CORE . 'config/');
define('PATH_RBAC_CORE', 'rbac/engine/');
define('PATH_DB', 'shared/sites/');
define('PATH_DATA', 'shared/rbac/');
define('PATH_RBAC_CORE',dirname(__DIR__).'/rbac/engine/');
define('PATH_DB', dirname(__DIR__).'/shared/sites/');
define('PATH_DATA', dirname(__DIR__).'/shared/rbac/');
define('PATH_SEP', '/');
define('PATH_METHODS', 'workflow/engine/methods/');
define('PATH_METHODS', dirname(__DIR__).'/workflow/engine/methods/');
define('SYS_LANG', 'en');
define('DB_ADAPTER', 'mysql');
define('SYS_SKIN', 'neoclassic');
define('SYS_SYS', 'workflow');
define('PATH_WORKSPACE',PATH_TRUNK.'/shared/sites/' . SYS_SYS . '/');
define('PMTABLE_KEY','pmtable');
// Setup basic app services
$app = require __DIR__ . '/../bootstrap/app.php';
@@ -27,17 +36,17 @@ $app->make(Kernel::class)->bootstrap();
// Setup our testexternal database
config(['database.connections.testexternal' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'database' => env('DB_TESTEXTERNAL_DB', 'testexternal'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'database' => env('DB_DATABASE', 'testexternal'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', 'password'),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null
]]);
// Now, drop all test tables and repopulate with schema
@@ -52,13 +61,13 @@ DB::connection('testexternal')->table('test')->insert([
]);
// Only do if we are supporting MSSql tests
if(env('RUN_MSSQL_TESTS')) {
if (env('RUN_MSSQL_TESTS')) {
config(['database.connections.mssql' => [
'driver' => 'sqlsrv',
'host' => env('MSSQL_HOST', '127.0.0.1'),
'database' => env('MSSQL_DATABASE', 'testexternal'),
'username' => env('MSSQL_USERNAME', 'root'),
'password' => env('MSSQL_PASSWORD', ''),
'driver' => 'sqlsrv',
'host' => env('MSSQL_HOST', '127.0.0.1'),
'database' => env('MSSQL_DATABASE', 'testexternal'),
'username' => env('MSSQL_USERNAME', 'root'),
'password' => env('MSSQL_PASSWORD', 'password'),
]]);
Schema::connection('mssql')->dropIfExists('test');
@@ -73,26 +82,25 @@ if(env('RUN_MSSQL_TESTS')) {
// THIS IS FOR STANDARD PROCESSMAKER TABLES
// Now, drop all test tables and repopulate with schema
DB::unprepared('SET FOREIGN_KEY_CHECKS = 0');
$colname = 'Tables_in_' . env('DB_DATABASE');
$tables = DB::select('SHOW TABLES');
$drop = [];
foreach($tables as $table) {
foreach ($tables as $table) {
$drop[] = $table->$colname;
}
if(count($drop)) {
if (count($drop)) {
$drop = implode(',', $drop);
DB::statement("DROP TABLE $drop");
DB::unprepared('SET FOREIGN_KEY_CHECKS = 1');
}
// Repopulate with schema and standard inserts
DB::unprepared(file_get_contents(PATH_CORE.'data/mysql/schema.sql'));
DB::unprepared(file_get_contents(PATH_RBAC_CORE.'data/mysql/schema.sql'));
DB::unprepared(file_get_contents(PATH_CORE.'data/mysql/insert.sql'));
DB::unprepared(file_get_contents(PATH_RBAC_CORE.'data/mysql/insert.sql'));
DB::unprepared(file_get_contents(PATH_CORE . 'data/mysql/schema.sql'));
DB::unprepared(file_get_contents(PATH_RBAC_CORE . 'data/mysql/schema.sql'));
DB::unprepared(file_get_contents(PATH_CORE . 'data/mysql/insert.sql'));
DB::unprepared(file_get_contents(PATH_RBAC_CORE . 'data/mysql/insert.sql'));
// Set our APP_SEQUENCE val
DB::table('APP_SEQUENCE')->insert([
@@ -106,7 +114,7 @@ DB::table('OAUTH_CLIENTS')->insert([
'CLIENT_NAME' => 'PM Web Designer',
'CLIENT_DESCRIPTION' => 'ProcessMaker Web Designer App',
'CLIENT_WEBSITE' => 'www.processmaker.com',
'REDIRECT_URI' => config('app.url') . '/sys' . config('system.workspace').'/en/neoclassic/oauth2/grant',
'REDIRECT_URI' => config('app.url') . '/sys' . config('system.workspace') . '/en/neoclassic/oauth2/grant',
'USR_UID' => '00000000000000000000000000000001'
]);
DB::table('OAUTH_ACCESS_TOKENS')->insert([
@@ -133,4 +141,4 @@ Propel::initConfiguration([
'adapter' => 'mysql'
]
]
]);
]);

View File

@@ -0,0 +1,280 @@
<?php
use Tests\TestCase;
class ReplaceDataFieldTest extends TestCase
{
/**
* This checks that strings with HTML reserved characters are replaced with entities
* @test
* @covers G::replaceDataField
*/
public function it_should_replace_entities()
{
// Initializing Faker instance
$faker = Faker\Factory::create();
// Initializing variables to use that will not change
$stringWithVariablesToReplace = 'Hello @@var1 the @#var2 is @=var3 not @&var4->value';
$dbEngine = 'mysql'; // This only affects the way to escape the variables with "@@" prefix
$applyEntities = true; // If a value to replace is a not valid HTML and have HTML reserved characters, entities should be applied
// Initializing variables to test the assertions, entities should be applied in variable with @@
$var4 = new stdClass();
$var4->value = $faker->words(1, true);
$valuesToReplace = [
'var1' => 'Java < PHP & Python',
'var2' => $faker->words(1, true),
'var3' => $faker->words(1, true),
'var4' => $var4
];
// Replace variables in the string
$stringToCheck = G::replaceDataField($stringWithVariablesToReplace, $valuesToReplace, $dbEngine, $applyEntities);
// Assertions
$this->assertRegExp('/&lt;/', $stringToCheck);
$this->assertRegExp('/&amp;/', $stringToCheck);
// Initializing variables to test the assertions, entities should be applied in variable with @#
$var4 = new stdClass();
$var4->value = $faker->words(1, true);
$valuesToReplace = [
'var1' => $faker->words(1, true),
'var2' => 'Java < PHP & Python',
'var3' => $faker->words(1, true),
'var4' => $var4
];
// Replace variables in the string
$stringToCheck = G::replaceDataField($stringWithVariablesToReplace, $valuesToReplace, $dbEngine, $applyEntities);
// Assertions
$this->assertRegExp('/&lt;/', $stringToCheck);
$this->assertRegExp('/&amp;/', $stringToCheck);
// Initializing variables to test the assertions, entities should be applied in variable with @=
$var4 = new stdClass();
$var4->value = $faker->words(1, true);
$valuesToReplace = [
'var1' => $faker->words(1, true),
'var2' => $faker->words(1, true),
'var3' => 'Java < PHP & Python',
'var4' => $var4
];
// Replace variables in the string
$stringToCheck = G::replaceDataField($stringWithVariablesToReplace, $valuesToReplace, $dbEngine, $applyEntities);
// Assertions
$this->assertRegExp('/&lt;/', $stringToCheck);
$this->assertRegExp('/&amp;/', $stringToCheck);
// Initializing variables to test the assertions, entities should be applied in variable with @&
$var4 = new stdClass();
$var4->value = 'Java < PHP & Python';
$valuesToReplace = [
'var1' => $faker->words(1, true),
'var2' => $faker->words(1, true),
'var3' => $faker->words(1, true),
'var4' => $var4
];
// Replace variables in the string
$stringToCheck = G::replaceDataField($stringWithVariablesToReplace, $valuesToReplace, $dbEngine, $applyEntities);
// Assertions
$this->assertRegExp('/&lt;/', $stringToCheck);
$this->assertRegExp('/&amp;/', $stringToCheck);
}
/**
* This checks that strings with HTML reserved characters are NOT replaced with entities
* @test
* @covers G::replaceDataField
*/
public function it_should_no_replace_entities()
{
// Initializing Faker instance
$faker = Faker\Factory::create();
// Initializing variables to use that will not change
$stringWithVariablesToReplace = 'Hello @@var1 the @#var2 is @=var3 not @&var4->value';
$dbEngine = 'mysql'; // This only affects the way to escape the variables with "@@" prefix
$applyEntities = false; // The values should not be replaced with entities
// Initializing variables to test the assertions, entities should be applied in variable with @@
$var4 = new stdClass();
$var4->value = $faker->words(1, true);
$valuesToReplace = [
'var1' => 'Java < PHP & Python',
'var2' => $faker->words(1, true),
'var3' => $faker->words(1, true),
'var4' => $var4
];
// Replace variables in the string
$stringToCheck = G::replaceDataField($stringWithVariablesToReplace, $valuesToReplace, $dbEngine, $applyEntities);
// Assertions
$this->assertRegExp('/</', $stringToCheck);
$this->assertRegExp('/&/', $stringToCheck);
// Initializing variables to test the assertions, entities should be applied in variable with @#
$var4 = new stdClass();
$var4->value = $faker->words(1, true);
$valuesToReplace = [
'var1' => $faker->words(1, true),
'var2' => 'Java < PHP & Python',
'var3' => $faker->words(1, true),
'var4' => $var4
];
// Replace variables in the string
$stringToCheck = G::replaceDataField($stringWithVariablesToReplace, $valuesToReplace, $dbEngine, $applyEntities);
// Assertions
$this->assertRegExp('/</', $stringToCheck);
$this->assertRegExp('/&/', $stringToCheck);
// Initializing variables to test the assertions, entities should be applied in variable with @=
$var4 = new stdClass();
$var4->value = $faker->words(1, true);
$valuesToReplace = [
'var1' => $faker->words(1, true),
'var2' => $faker->words(1, true),
'var3' => 'Java < PHP & Python',
'var4' => $var4
];
// Replace variables in the string
$stringToCheck = G::replaceDataField($stringWithVariablesToReplace, $valuesToReplace, $dbEngine, $applyEntities);
// Assertions
$this->assertRegExp('/</', $stringToCheck);
$this->assertRegExp('/&/', $stringToCheck);
// Initializing variables to test the assertions, entities should be applied in variable with @&
$var4 = new stdClass();
$var4->value = 'Java < PHP & Python';
$valuesToReplace = [
'var1' => $faker->words(1, true),
'var2' => $faker->words(1, true),
'var3' => $faker->words(1, true),
'var4' => $var4
];
// Replace variables in the string
$stringToCheck = G::replaceDataField($stringWithVariablesToReplace, $valuesToReplace, $dbEngine, $applyEntities);
// Assertions
$this->assertRegExp('/</', $stringToCheck);
$this->assertRegExp('/&/', $stringToCheck);
}
/**
* This checks that strings with HTML reserved characters are NOT replaced with entities if is a valid HTML, because
* PS team sometimes build a HTML string to insert in templates (output documents or emails), Ex.- A table to list
* users or results from a query
* @test
* @covers G::replaceDataField
*/
public function it_should_no_replace_entities_if_exists_valid_html()
{
// Initializing Faker instance
$faker = Faker\Factory::create();
// Initializing variables to use
$stringWithVariablesToReplace = 'bla @#var1 bla @=listHtml bla @@var2 bla';
$valuesToReplace = [
'var1' => $faker->words(1, true),
'listHtml' => '<table>
<tr>
<th>t1</th>
<th>t2</th>
<th>t3</th>
<th>t4</th>
<th>t5</th>
<th>t6</th>
</tr>
<tr>
<td>c1</td>
<td>c2</td>
<td>c3</td>
<td>c4</td>
<td>c5</td>
<td>c6</td>
</tr>
</table>',
'var2' => $faker->words(1, true)
];
$dbEngine = 'mysql'; // This only affects the way to escape the variables with "@@" prefix
$applyEntities = true; // Is true because the string will b used in a output document or a email template
// Replace variables in the string
$stringToCheck = G::replaceDataField($stringWithVariablesToReplace, $valuesToReplace, $dbEngine, $applyEntities);
// Assertions
$this->assertRegExp('/<table>/', $stringToCheck);
$this->assertRegExp('/<tr>/', $stringToCheck);
$this->assertRegExp('/<th>/', $stringToCheck);
$this->assertRegExp('/<td>/', $stringToCheck);
}
/**
* This checks that strings with tag <br /> should not be replaced, because is a valid tag
* @test
* @covers G::replaceDataField
*/
public function it_should_no_replace_tag_br()
{
// Initializing variables to use
$stringWithTagBr = nl2br("prospection auprès d'entreprises de CA < 10 M euros
test
<a
>a
&a
\"a
'a
¢a
£a
¥a
€a
©a
®a
test");
$valuesToReplace = [];
$dbEngine = 'mysql'; // This only affects the way to escape the variables with "@@" prefix
$applyEntities = true; // Is true because the string will be used in a output document or a email template
// Replace variables in the string
$stringToCheck = G::replaceDataField($stringWithTagBr, $valuesToReplace, $dbEngine, $applyEntities);
// Assertions
$this->assertRegExp("/<br \/>/", $stringToCheck);
}
/**
* Check that the value for the System variable "__ABE__" should not be replaced never
* @test
* @covers G::replaceDataField
*/
public function it_should_no_replace_entities_for_var_abe()
{
// Initializing variables to use
$string = "bla @#__ABE__ bla @#anotherVar bla";
$valuesToReplace = [// Add a value for reserved system variable "__ABE__" used in Actions By Email feature
'__ABE__' => 'Java < PHP', // The value for System variable "__ABE__" shouldn't be changed never
'anotherVar' => '.NET < Java' // The value for another variables should be validated/replaced normally
];
$dbEngine = 'mysql'; // This only affects the way to escape the variables with "@@" prefix
$applyEntities = true; // Is true because the string will be used in a output document or a email template
// Replace variables in the string
$stringToCheck = G::replaceDataField($string, $valuesToReplace, $dbEngine, $applyEntities);
// Assertions
$this->assertRegExp("/Java < PHP/", $stringToCheck);
$this->assertRegExp("/.NET &lt; Java/", $stringToCheck);
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -83,7 +83,8 @@ class MSSQLConnection extends ConnectionCommon implements Connection
$opt = [
'UID' => $user,
'PWD' => $pw,
'Database' => $dsninfo['database']
'Database' => $dsninfo['database'],
'CharacterSet' => 'UTF-8'
];
// SQLSrv is persistent always
$conn = sqlsrv_connect($dbhost, $opt);

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More