Files
luos/workflow/engine/src/ProcessMaker/BusinessModel/ReportTable.php
Paula Quispe e25d58dd8c PMCORE-1194
2022-01-24 16:48:45 -04:00

888 lines
36 KiB
PHP

<?php
namespace ProcessMaker\BusinessModel;
use AdditionalTables;
use AdditionalTablesPeer;
use Configurations;
use G;
use Exception;
class ReportTable
{
/**
* Get report table default columns
*
* @param string $type
*
* @return object
*/
private function getDefaultColumns($type = 'NORMAL')
{
$defaultColumns = [];
$application = new \stdClass(); //APPLICATION KEY
$application->uid = '';
$application->field_dyn = '';
$application->field_uid = '';
$application->field_name = 'APP_UID';
$application->field_label = 'APP_UID';
$application->field_type = 'VARCHAR';
$application->field_size = 32;
$application->field_dyn = '';
$application->field_key = 1;
$application->field_index = 1;
$application->field_null = 0;
$application->field_filter = false;
$application->field_autoincrement = false;
array_push($defaultColumns, $application);
$application = new \stdClass(); //APP_NUMBER
$application->uid = '';
$application->field_dyn = '';
$application->field_uid = '';
$application->field_name = 'APP_NUMBER';
$application->field_label = 'APP_NUMBER';
$application->field_type = 'INTEGER';
$application->field_size = 11;
$application->field_dyn = '';
$application->field_key = 0;
$application->field_null = 0;
$application->field_filter = false;
$application->field_autoincrement = false;
array_push($defaultColumns, $application);
$application = new \stdClass(); //APP_STATUS
$application->uid = '';
$application->field_dyn = '';
$application->field_uid = '';
$application->field_name = 'APP_STATUS';
$application->field_label = 'APP_STATUS';
$application->field_type = 'VARCHAR';
$application->field_size = 10;
$application->field_dyn = '';
$application->field_key = 0;
$application->field_null = 0;
$application->field_filter = false;
$application->field_autoincrement = false;
array_push($defaultColumns, $application);
//If it is a grid report table
if ($type == 'GRID') {
//GRID INDEX
$gridIndex = new \stdClass();
$gridIndex->uid = '';
$gridIndex->field_dyn = '';
$gridIndex->field_uid = '';
$gridIndex->field_name = 'ROW';
$gridIndex->field_label = 'ROW';
$gridIndex->field_type = 'INTEGER';
$gridIndex->field_size = '11';
$gridIndex->field_dyn = '';
$gridIndex->field_key = 1;
$gridIndex->field_null = 0;
$gridIndex->field_filter = false;
$gridIndex->field_autoincrement = false;
array_push($defaultColumns, $gridIndex);
}
return $defaultColumns;
}
/**
* Populate the data
*
* @param array $arrayTableData
* @param array $tableNameMap
*
* @return string
*/
private function populateData(array $arrayTableData, array $tableNameMap)
{
try {
$errors = '';
foreach ($arrayTableData as $key => $value) {
$tableName = $key;
$contentData = $value;
if (isset($tableNameMap[$tableName])) {
$tableName = $tableNameMap[$tableName];
$additionalTable = new AdditionalTables();
$arrayAdditionalTableData = $additionalTable->loadByName($tableName);
if ($arrayAdditionalTableData) {
$flagIsPmTable = $arrayAdditionalTableData['PRO_UID'] == '';
if ($flagIsPmTable && !empty($contentData)) {
$additionalTable->load($arrayAdditionalTableData['ADD_TAB_UID'], true);
$primaryKeys = $additionalTable->getPrimaryKeys();
//Obtain a list of columns
$primaryKeyColumn = [];
foreach ($contentData as $key => $row) {
$primaryKeyColumn[$key] = $row[$primaryKeys[0]['FLD_NAME']];
}
array_multisort($primaryKeyColumn, SORT_ASC, $contentData);
foreach ($contentData as $row) {
$arrayResult = $this->createRecord(['id' => $arrayAdditionalTableData['ADD_TAB_UID'], 'rows' => base64_encode(serialize($row)),], 'base64');
if (!$arrayResult['success']) {
$errors .= $arrayResult['message'];
}
}
}
}
}
}
//Return
return $errors;
} catch (Exception $e) {
throw $e;
}
}
/**
* Create record
*
* @param array $arrayData
* @param string $codification
*
* @return array
*/
public function createRecord(array $arrayData, $codification = 'json')
{
try {
$additionalTable = new AdditionalTables();
$arrayAdditionalTableData = $additionalTable->load($arrayData['id'], true);
$additionalTableClassName = $arrayAdditionalTableData['ADD_TAB_CLASS_NAME'];
$additionalTableClassPeerName = $additionalTableClassName . 'Peer';
$row = ($codification == 'base64') ? unserialize(base64_decode($arrayData['rows'])) : G::json_decode($arrayData['rows']);
$row = (array) ($row);
$row = array_merge(array_change_key_case($row, CASE_LOWER), array_change_key_case($row, CASE_UPPER));
$flagSave = false;
if (!file_exists(PATH_WORKSPACE . 'classes' . PATH_SEP . $additionalTableClassName . '.php')) {
throw new Exception(G::LoadTranslation('ID_PMTABLE_CLASS_DOESNT_EXIST', [$additionalTableClassName]));
}
require_once(PATH_WORKSPACE . 'classes' . PATH_SEP . $additionalTableClassName . '.php');
if (!empty($row)) {
eval('$con = \\Propel::getConnection(' . $additionalTableClassPeerName . '::DATABASE_NAME);');
eval('$obj = new \\' . $additionalTableClassName . '();');
$obj->fromArray($row, \BasePeer::TYPE_FIELDNAME);
if ($obj->validate()) {
$obj->save();
$primaryKeysValues = [];
foreach ($additionalTable->getPrimaryKeys() as $primaryKey) {
$method = 'get' . AdditionalTables::getPHPName($primaryKey['FLD_NAME']);
$primaryKeysValues[] = $obj->$method();
}
$index = G::encrypt(implode(',', $primaryKeysValues), 'pmtable');
G::auditLog('AddDataPmtable', 'Table Name: ' . $arrayAdditionalTableData['ADD_TAB_NAME'] . ' Table ID: (' . $arrayAdditionalTableData['ADD_TAB_UID'] . ')');
$flagSave = true;
} else {
$msg = '';
foreach ($obj->getValidationFailures() as $objValidationFailure) {
$msg .= $objValidationFailure->getMessage() . "\n";
}
throw new Exception(G::LoadTranslation('ID_ERROR_TRYING_INSERT') . '"' . $arrayAdditionalTableData['ADD_TAB_NAME'] . "\"\n" . $msg);
}
} else {
$flagSave = false;
}
//Return
return [
'success' => $flagSave,
'message' => ($flagSave) ? G::LoadTranslation('ID_RECORD_SAVED_SUCCESFULLY') : '',
'rows' => ($flagSave) ? $obj->toArray(\BasePeer::TYPE_FIELDNAME) : [],
'index' => ($flagSave) ? $index : '',
];
} catch (Exception $e) {
throw $e;
}
}
/**
* Review the table schema and throw all errors
*
* @param array $arrayTableSchema
* @param string $processUid
* @param bool $flagFromAdmin
* @param bool $flagOverwrite
* @param string $postProUid
*
* @return array
*/
public function checkPmtFileThrowErrors(array $arrayTableSchema, $processUid, $flagFromAdmin, $flagOverwrite, $postProUid)
{
try {
$arrayError = [];
//Ask for all Process
$processMap = new \ProcessMap();
$arrayProcessUid = [];
foreach (G::json_decode($processMap->getAllProcesses()) as $value) {
if ($value->value != '') {
$arrayProcessUid[] = $value->value;
}
}
$i = 0;
foreach ($arrayTableSchema as $value) {
$contentSchema = $value;
//The table exists?
$additionalTable = new AdditionalTables();
$arrayAdditionalTableData = $additionalTable->loadByName($contentSchema['ADD_TAB_NAME']);
$tableProUid = (isset($contentSchema['PRO_UID'])) ? $contentSchema['PRO_UID'] : $postProUid;
$flagIsPmTable = ($contentSchema['PRO_UID'] == '') ? true : false;
if ($flagFromAdmin) {
if ($flagIsPmTable) {
if ($arrayAdditionalTableData && !$flagOverwrite) {
$arrayError[$i]['NAME_TABLE'] = $contentSchema['ADD_TAB_NAME'];
$arrayError[$i]['ERROR_TYPE'] = 1; //ERROR_PM_TABLES_OVERWRITE
$arrayError[$i]['ERROR_MESS'] = G::LoadTranslation('ID_OVERWRITE_PMTABLE', [$contentSchema['ADD_TAB_NAME']]);
$arrayError[$i]['IS_PMTABLE'] = $flagIsPmTable;
$arrayError[$i]['PRO_UID'] = $tableProUid;
}
} else {
if (!in_array($tableProUid, $arrayProcessUid)) {
$arrayError[$i]['NAME_TABLE'] = $contentSchema['ADD_TAB_NAME'];
$arrayError[$i]['ERROR_TYPE'] = 2; //ERROR_PROCESS_NOT_EXIST
$arrayError[$i]['ERROR_MESS'] = G::LoadTranslation('ID_PROCESS_NOT_EXIST', [$contentSchema['ADD_TAB_NAME']]);
$arrayError[$i]['IS_PMTABLE'] = $flagIsPmTable;
$arrayError[$i]['PRO_UID'] = $tableProUid;
} else {
if ($arrayAdditionalTableData && !$flagOverwrite) {
$arrayError[$i]['NAME_TABLE'] = $contentSchema['ADD_TAB_NAME'];
$arrayError[$i]['ERROR_TYPE'] = 3; //ERROR_RP_TABLES_OVERWRITE
$arrayError[$i]['ERROR_MESS'] = G::LoadTranslation('ID_OVERWRITE_RPTABLE', [$contentSchema['ADD_TAB_NAME']]);
$arrayError[$i]['IS_PMTABLE'] = $flagIsPmTable;
$arrayError[$i]['PRO_UID'] = $tableProUid;
}
}
}
} else {
if ($flagIsPmTable) {
$arrayError[$i]['NAME_TABLE'] = $contentSchema['ADD_TAB_NAME'];
$arrayError[$i]['ERROR_TYPE'] = 4; //ERROR_NO_REPORT_TABLE
$arrayError[$i]['ERROR_MESS'] = G::LoadTranslation('ID_NO_REPORT_TABLE', [$contentSchema['ADD_TAB_NAME']]);
$arrayError[$i]['IS_PMTABLE'] = $flagIsPmTable;
$arrayError[$i]['PRO_UID'] = $tableProUid;
} else {
if ($tableProUid !== $processUid) {
$arrayError[$i]['NAME_TABLE'] = $contentSchema['ADD_TAB_NAME'];
$arrayError[$i]['ERROR_TYPE'] = 5; //ERROR_OVERWRITE_RELATED_PROCESS
$arrayError[$i]['ERROR_MESS'] = G::LoadTranslation('ID_OVERWRITE_RELATED_PROCESS', [$contentSchema['ADD_TAB_NAME']]);
$arrayError[$i]['IS_PMTABLE'] = $flagIsPmTable;
$arrayError[$i]['PRO_UID'] = $tableProUid;
} else {
if ($arrayAdditionalTableData && !$flagOverwrite) {
$arrayError[$i]['NAME_TABLE'] = $contentSchema['ADD_TAB_NAME'];
$arrayError[$i]['ERROR_TYPE'] = 3; //ERROR_RP_TABLES_OVERWRITE
$arrayError[$i]['ERROR_MESS'] = G::LoadTranslation('ID_OVERWRITE_RPTABLE', [$contentSchema['ADD_TAB_NAME']]);
$arrayError[$i]['IS_PMTABLE'] = $flagIsPmTable;
$arrayError[$i]['PRO_UID'] = $tableProUid;
}
}
}
}
$i++;
}
//Return
return $arrayError;
} catch (Exception $e) {
throw $e;
}
}
/**
* Save structure of table
*
* @param array $arrayData
* @param bool $flagAlterTable
*
* @see pmTablesProxy->save()
* @see ProcessMaker\BusinessModel\ReportTable->createStructureOfTables()
* @see Table->validateTableBeforeUpdate()
* @link https://wiki.processmaker.com/3.1/Report_Tables
*
* @return object
*/
public function saveStructureOfTable($arrayData, $flagAlterTable = true)
{
$result = new \stdClass();
try {
$additionalTableUid = $arrayData['REP_TAB_UID'];
$flagNew = 0;
$additionalTables = AdditionalTablesPeer::retrieveByPK($arrayData['REP_TAB_UID']);
if (!is_null($additionalTables)) {
$arrayData['REP_TAB_NAME'] = 'PMT_' . trim($arrayData['REP_TAB_NAME']);
if ($additionalTables->getAddTabName() != $arrayData['REP_TAB_NAME']) {
$arrayData['REP_TAB_UID'] = '';
$flagNew = 1;
}
}
ob_start();
$arrayData['PRO_UID'] = trim($arrayData['PRO_UID']);
$arrayData['columns'] = G::json_decode(stripslashes($arrayData['columns'])); //Decofing data columns
if ($flagNew == 1) {
$arrayNewColumn = [];
$counter = 0;
foreach ($arrayData['columns'] as $value) {
$column = $value;
if (!preg_match('/^(?:APP_UID|APP_NUMBER|APP_STATUS|ROW)$/', $column->field_name)) {
$column->uid = '';
$column->_index = $counter;
$arrayNewColumn[] = $column;
$counter++;
}
}
$arrayData['columns'] = $arrayNewColumn;
}
$additionalTable = new AdditionalTables();
$repTabClassName = $additionalTable->getPHPName($arrayData['REP_TAB_NAME']);
$flagIsReportTable = ($arrayData['PRO_UID'] != '') ? true : false;
$columns = $arrayData['columns'];
//Reserved Words Table
$reservedWords = [
'ALTER', 'CLOSE', 'COMMIT', 'CREATE', 'DECLARE', 'DELETE', 'DROP', 'FETCH', 'FUNCTION', 'GRANT', 'INDEX',
'INSERT', 'OPEN', 'REVOKE', 'ROLLBACK', 'SELECT', 'SYNONYM', 'TABLE', 'UPDATE', 'VIEW', 'APP_UID', 'ROW', 'PMTABLE'
];
//Reserved Words Field
$reservedWordsPhp = [
'case', 'catch', 'cfunction', 'class', 'clone', 'const', 'continue', 'declare', 'default', 'do', 'else', 'elseif',
'enddeclare', 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile', 'extends', 'final', 'for', 'foreach',
'function', 'global', 'goto', 'if', 'implements', 'interface', 'instanceof', 'private', 'namespace', 'new',
'old_function', 'or', 'throw', 'protected', 'public', 'static', 'switch', 'xor', 'try', 'use', 'var', 'while'
];
$reservedWordsSql = G::reservedWordsSql();
//Verify if exists
if ($arrayData['REP_TAB_UID'] == '' || (isset($arrayData['forceUid']) && $arrayData['forceUid'])) {
//New report table
if ($flagIsReportTable && $flagAlterTable) {
//Setting default columns
$defaultColumns = $this->getDefaultColumns($arrayData['REP_TAB_TYPE']);
$columns = array_merge($defaultColumns, $columns);
}
//Validations
if (is_array($additionalTable->loadByName($arrayData['REP_TAB_NAME']))) {
throw new Exception(G::LoadTranslation('ID_PMTABLE_ALREADY_EXISTS', [$arrayData['REP_TAB_NAME']]));
}
if (in_array(strtoupper($arrayData['REP_TAB_NAME']), $reservedWords) ||
in_array(strtoupper($arrayData['REP_TAB_NAME']), $reservedWordsSql)
) {
throw new Exception(G::LoadTranslation('ID_PMTABLE_INVALID_NAME', [$arrayData['REP_TAB_NAME']]));
}
}
$this->validateFieldName($columns);
//Backward compatility
foreach ($columns as $i => $column) {
if (in_array(strtoupper($columns[$i]->field_name), $reservedWordsSql) ||
in_array(strtolower($columns[$i]->field_name), $reservedWordsPhp)
) {
throw new Exception(G::LoadTranslation('ID_PMTABLE_INVALID_FIELD_NAME', [$columns[$i]->field_name]));
}
switch ($column->field_type) {
case 'INT':
$columns[$i]->field_type = 'INTEGER';
break;
case 'TEXT':
$columns[$i]->field_type = 'LONGVARCHAR';
break;
case 'DATETIME':
//Propel: DATETIME equivalent is TIMESTAMP
$columns[$i]->field_type = 'TIMESTAMP';
break;
}
//Validations
if ($columns[$i]->field_autoincrement) {
$typeCol = $columns[$i]->field_type;
if (!($typeCol === 'INTEGER' || $typeCol === 'TINYINT' || $typeCol === 'SMALLINT' || $typeCol === 'BIGINT')) {
$columns[$i]->field_autoincrement = false;
}
}
}
$pmTable = new \PmTable($arrayData['REP_TAB_NAME']);
$pmTable->setDataSource($arrayData['REP_TAB_CONNECTION']);
$pmTable->setColumns($columns);
$pmTable->setAlterTable($flagAlterTable);
if (isset($arrayData['REP_TAB_NAME_OLD_NAME'])) {
$pmTable->setOldTableName($arrayData['REP_TAB_NAME_OLD_NAME']);
}
if (isset($arrayData['keepData']) && $arrayData['keepData'] == 1) {
//PM Table
$pmTable->setKeepData(true);
}
$pmTable->build();
$buildResult = ob_get_contents();
if (ob_get_contents()) {
ob_end_clean();
}
//Updating additional table struture information
$addTabData = [
'ADD_TAB_UID' => $arrayData['REP_TAB_UID'],
'ADD_TAB_NAME' => $arrayData['REP_TAB_NAME'],
'ADD_TAB_CLASS_NAME' => $repTabClassName,
'ADD_TAB_DESCRIPTION' => $arrayData['REP_TAB_DSC'],
'ADD_TAB_PLG_UID' => '',
'DBS_UID' => ($arrayData['REP_TAB_CONNECTION']) ? $arrayData['REP_TAB_CONNECTION'] : 'workflow',
'PRO_UID' => $arrayData['PRO_UID'],
'ADD_TAB_TYPE' => $arrayData['REP_TAB_TYPE'],
'ADD_TAB_GRID' => $arrayData['REP_TAB_GRID'],
'ADD_TAB_OFFLINE' => !empty($arrayData['REP_TAB_OFFLINE']) ?? 0,
'ADD_TAB_UPDATE_DATE' => date('Y-m-d H:i:s'),
];
if ($arrayData['REP_TAB_UID'] == '' || (isset($arrayData['forceUid']) && $arrayData['forceUid'])) {
//New report table
//create record
$addTabUid = $additionalTable->create($addTabData);
} else {
//Editing report table
//updating record
$addTabUid = $arrayData['REP_TAB_UID'];
$additionalTable->update($addTabData);
//Removing old data fields references
$oCriteria = new \Criteria('workflow');
$oCriteria->add(\FieldsPeer::ADD_TAB_UID, $arrayData['REP_TAB_UID']);
\FieldsPeer::doDelete($oCriteria);
}
//Updating pmtable fields
$field = new \Fields();
foreach ($columns as $i => $column) {
$field->create([
'FLD_UID' => $column->uid,
'FLD_INDEX' => $i,
'ADD_TAB_UID' => $addTabUid,
'FLD_NAME' => $column->field_name,
'FLD_DESCRIPTION' => $column->field_label,
'FLD_TYPE' => $column->field_type,
'FLD_SIZE' => ($column->field_size == '') ? null : $column->field_size,
'FLD_NULL' => ($column->field_null) ? 1 : 0,
'FLD_AUTO_INCREMENT' => ($column->field_autoincrement) ? 1 : 0,
'FLD_KEY' => ($column->field_key) ? 1 : 0,
'FLD_TABLE_INDEX' => (isset($column->field_index) && $column->field_index) ? 1 : 0,
'FLD_FOREIGN_KEY' => 0,
'FLD_FOREIGN_KEY_TABLE' => '',
'FLD_DYN_NAME' => $column->field_dyn,
'FLD_DYN_UID' => $column->field_uid,
'FLD_FILTER' => (isset($column->field_filter) && $column->field_filter) ? 1 : 0
]);
}
if ($flagIsReportTable && $flagAlterTable) {
//The table was create successfully but we're catching problems while populating table
try {
$additionalTable->populateReportTable($arrayData['REP_TAB_NAME'], $pmTable->getDataSource(), $arrayData['REP_TAB_TYPE'], $arrayData['PRO_UID'], $arrayData['REP_TAB_GRID'], $addTabUid);
} catch (Exception $e) {
$result->message = $result->msg = $e->getMessage();
}
}
//Audit Log
$nFields = count($columns) - 1;
$fieldsName = '';
foreach ($columns as $i => $column) {
if ($i != $nFields) {
$fieldsName = $fieldsName . $columns[$i]->field_name . ' [' . implode(', ', get_object_vars($column)) . '], ';
} else {
$fieldsName = $fieldsName . $columns[$i]->field_name . ' [' . implode(', ', get_object_vars($column)) . '].';
}
}
G::auditLog((isset($arrayData['REP_TAB_UID']) && $arrayData['REP_TAB_UID'] == '') ? 'CreatePmtable' : 'UpdatePmtable', 'Fields: ' . $fieldsName);
$result->success = true;
$result->message = $result->msg = $buildResult;
require_once(PATH_CORE . 'controllers/pmTablesProxy.php');
if ($flagNew == 1) {
$pmTablesProxy = new \pmTablesProxy();
$obj = new \stdClass();
$obj->rows = G::json_encode([['id' => $additionalTableUid, 'type' => '']]);
//Delete Report Table
$resultDeleteReportTable = $pmTablesProxy->delete($obj);
}
$this->updateConfigurationCaseList($additionalTableUid, $columns);
} catch (Exception $e) {
$buildResult = ob_get_contents();
if (ob_get_contents()) {
ob_end_clean();
}
$result->success = false;
//If it is a propel exception message
if (preg_match('/(.*)\s\[(.*):\s(.*)\]\s\[(.*):\s(.*)\]/', $e->getMessage(), $match)) {
$result->message = $result->msg = $match[3];
$result->type = ucfirst($pmTable->getDbConfig()->adapter);
} else {
$result->message = $result->msg = $e->getMessage();
$result->type = G::LoadTranslation('ID_EXCEPTION');
}
$result->trace = $e->getTraceAsString();
}
//Return
return $result;
}
/**
* Update the Custom Case List fields configuration.
*
* @param array $columns
*
* @see ProcessMaker\BusinessModel\ReportTable->saveStructureOfTable()
* @link https://wiki.processmaker.com/3.1/Report_Tables
* @link https://wiki.processmaker.com/3.2/Cases_List_Builder#Installation_and_Configuration
*/
public function updateConfigurationCaseList($addTabUid, $columns)
{
$actions = [
"todo", "draft", "sent", "unassigned", "paused", "completed", "cancelled"
];
$conf = new Configurations();
foreach ($actions as $action) {
$confCasesList = $conf->loadObject("casesList", $action, "", "", "");
$sw = is_array($confCasesList) && !empty($confCasesList) && !empty($confCasesList['PMTable']) && $confCasesList['PMTable'] === $addTabUid;
if ($sw) {
$this->addFieldsToCustomCaseList($confCasesList['first']['data'], $confCasesList['second']['data'], $columns);
$this->removeFieldsFromCustomCaseList($confCasesList['first']['data'], $columns);
$this->removeFieldsFromCustomCaseList($confCasesList['second']['data'], $columns);
$conf->saveObject($confCasesList, "casesList", $action);
}
}
}
/**
* Add fields to Custom Case List.
* @param array $data1
* @param array $data2
* @param array $columns
*
* @see ProcessMaker\BusinessModel\ReportTable->saveStructureOfTable()
* @link https://wiki.processmaker.com/3.1/Report_Tables
* @link https://wiki.processmaker.com/3.2/Cases_List_Builder#Installation_and_Configuration
*/
public function addFieldsToCustomCaseList(&$data1, $data2, $columns)
{
$all = [];
$type = 'PM Table';
$this->loadFieldTypeValues($data1, $all, $type);
$this->loadFieldTypeValues($data2, $all, $type);
foreach ($all as $value) {
foreach ($columns as $index => $column) {
if ($value['name'] === $column->field_name) {
unset($columns[$index]);
break;
}
}
}
$defaults = ["APP_UID", "APP_NUMBER", "APP_STATUS"];
foreach ($defaults as $value) {
foreach ($columns as $index => $column) {
if ($value === $column->field_name) {
unset($columns[$index]);
break;
}
}
}
foreach ($columns as $value) {
$data1[] = [
"name" => $column->field_name,
"fieldType" => $type
];
}
}
/**
* Load field type values.
*
* @param array $fields
* @param array $all
* @param string $type
*/
private function loadFieldTypeValues($fields, array &$all, $type)
{
foreach ($fields as $value) {
if ($value['fieldType'] === $type) {
$all[] = $value;
}
}
}
/**
* Remove fields from Custom Cases List.
*
* @param array $data
* @param array $columns
*
* @see ProcessMaker\BusinessModel\ReportTable->saveStructureOfTable()
* @link https://wiki.processmaker.com/3.1/Report_Tables
* @link https://wiki.processmaker.com/3.2/Cases_List_Builder#Installation_and_Configuration
*/
public function removeFieldsFromCustomCaseList(&$data, $columns)
{
$n = count($data);
for ($key = 0; $key < $n; $key++) {
if ($data[$key]['fieldType'] === 'PM Table') {
$remove = true;
foreach ($columns as $column) {
if ($data[$key]['name'] === $column->field_name) {
$remove = false;
break;
}
}
if ($remove === true) {
unset($data[$key]);
$data = array_values($data);
$key = 0;
$n = count($data);
}
}
}
}
/**
* Create the structure of tables
*
* @param array $arrayTableSchema,
* @param array $arrayTableData,
* @param string $processUid
* @param bool $flagFromAdmin
* @param bool $flagOverwrite
* @param array $arrayTablesToExclude
* @param array $arrayTablesToCreate
*
* @return string
*/
public function createStructureOfTables(array $arrayTableSchema, array $arrayTableData, $processUid, $flagFromAdmin, $flagOverwrite = true, array $arrayTablesToExclude = [], array $arrayTablesToCreate = [])
{
try {
$errors = '';
$tableNameMap = [];
$processQueue = [];
$processQueueTables = [];
foreach ($arrayTableSchema as $value) {
$contentSchema = $value;
if (!in_array($contentSchema['ADD_TAB_NAME'], $arrayTablesToExclude)) {
$additionalTable = new AdditionalTables();
$arrayAdditionalTableData = $additionalTable->loadByName($contentSchema['ADD_TAB_NAME']);
$tableNameMap[$contentSchema['ADD_TAB_NAME']] = $contentSchema['ADD_TAB_NAME'];
$tableData = new \stdClass();
if (isset($contentSchema['PRO_UID'])) {
$tableData->PRO_UID = $contentSchema['PRO_UID'];
} else {
$tableData->PRO_UID = $_POST['form']['PRO_UID'];
}
$flagIsPmTable = $contentSchema['PRO_UID'] === '';
if (!$flagFromAdmin && !$flagIsPmTable) {
$tableData->PRO_UID = $processUid;
}
$flagOverwrite2 = $flagOverwrite;
if (in_array($contentSchema['ADD_TAB_NAME'], $arrayTablesToCreate)) {
$flagOverwrite2 = false;
}
//Overwrite
if ($flagOverwrite2) {
if ($arrayAdditionalTableData) {
$additionalTable->deleteAll($arrayAdditionalTableData['ADD_TAB_UID']);
}
} else {
if ($arrayAdditionalTableData) {
//Some table exists with the same name
//renaming...
$tNameOld = $contentSchema['ADD_TAB_NAME'];
$newTableName = $contentSchema['ADD_TAB_NAME'] . '_' . date('YmdHis');
$contentSchema['ADD_TAB_UID'] = G::generateUniqueID();
$contentSchema['ADD_TAB_NAME'] = $newTableName;
$contentSchema['ADD_TAB_CLASS_NAME'] = AdditionalTables::getPHPName($newTableName);
//Mapping the table name for posterior uses
$tableNameMap[$tNameOld] = $contentSchema['ADD_TAB_NAME'];
}
}
//Validating invalid bds_uid in old tables definition -> mapped to workflow
if (!$contentSchema['DBS_UID'] || $contentSchema['DBS_UID'] == '0' || !$contentSchema['DBS_UID']) {
$contentSchema['DBS_UID'] = 'workflow';
}
$columns = [];
foreach ($contentSchema['FIELDS'] as $field) {
$columns[] = [
'uid' => '',
'field_uid' => '',
'field_name' => $field['FLD_NAME'],
'field_dyn' => (isset($field['FLD_DYN_NAME'])) ? $field['FLD_DYN_NAME'] : '',
'field_label' => (isset($field['FLD_DESCRIPTION'])) ? $field['FLD_DESCRIPTION'] : '',
'field_type' => $field['FLD_TYPE'],
'field_size' => $field['FLD_SIZE'],
'field_key' => (isset($field['FLD_KEY'])) ? $field['FLD_KEY'] : 0,
'field_null' => (isset($field['FLD_NULL'])) ? $field['FLD_NULL'] : 1,
'field_autoincrement' => (isset($field['FLD_AUTO_INCREMENT'])) ?
$field['FLD_AUTO_INCREMENT'] : 0
];
}
$tableData->REP_TAB_UID = $contentSchema['ADD_TAB_UID'];
$tableData->REP_TAB_NAME = $contentSchema['ADD_TAB_NAME'];
$tableData->REP_TAB_DSC = $contentSchema['ADD_TAB_DESCRIPTION'];
$tableData->REP_TAB_CONNECTION = $contentSchema['DBS_UID'];
$tableData->REP_TAB_TYPE = (isset($contentSchema['ADD_TAB_TYPE'])) ? $contentSchema['ADD_TAB_TYPE'] : '';
$tableData->REP_TAB_GRID = (isset($contentSchema['ADD_TAB_GRID'])) ? $contentSchema['ADD_TAB_GRID'] : '';
$tableData->REP_TAB_OFFLINE = (isset($contentSchema['ADD_TAB_OFFLINE'])) ? $contentSchema['ADD_TAB_OFFLINE'] : '0';
$tableData->REP_TAB_UPDATE_DATE = date('Y-m-d H:i:s');
$tableData->columns = G::json_encode($columns);
$tableData->forceUid = true;
//Save the table
$alterTable = false;
$result = $this->saveStructureOfTable((array) ($tableData), $alterTable);
if ($result->success) {
G::auditLog('ImportTable', $contentSchema['ADD_TAB_NAME'] . ' (' . $contentSchema['ADD_TAB_UID'] . ')');
$processQueueTables[$contentSchema['DBS_UID']][] = $contentSchema['ADD_TAB_NAME'];
} else {
$errors .= G::LoadTranslation('ID_ERROR_CREATE_TABLE') . $tableData->REP_TAB_NAME . '-> ' . $result->message . '\n\n';
}
}
}
foreach ($processQueueTables as $dbsUid => $tables) {
$pmTable = new \PmTable();
ob_start();
$pmTable->buildModelFor($dbsUid, $tables);
$buildResult = ob_get_contents();
if (ob_get_contents()) {
ob_end_clean();
}
$errors .= $pmTable->upgradeDatabaseFor($pmTable->getDataSource(), $tables);
}
if (!empty($tableNameMap)) {
$errors = $this->populateData($arrayTableData, $tableNameMap);
}
//Return
return $errors;
} catch (Exception $e) {
throw $e;
}
}
/**
* Throw an exception if the column is not valid for the creation of the field
* in the classes managed by propel.
*
* @param array $columns
* @throws Exception
*/
private function validateFieldName($columns)
{
$validFields = [];
$invalidFields = [];
foreach ($columns as $column) {
try {
$fieldName = $column->field_name;
Validator::isValidVariableName($fieldName);
$fieldName = strtolower(AdditionalTables::getPHPName($fieldName));
if (in_array($fieldName, $validFields)) {
$invalidFields[] = $fieldName;
} else {
$validFields[] = $fieldName;
}
} catch (Exception $e) {
$invalidFields[] = $fieldName;
}
}
if (!empty($invalidFields)) {
throw new Exception(G::LoadTranslation('ID_PMTABLE_INVALID_FIELD_NAME_VARIABLE', $invalidFields));
}
}
}