From 371e220dbc5f1d37b98dc2ab6809591f0c6f6cda Mon Sep 17 00:00:00 2001 From: Victor Saisa Lopez Date: Thu, 31 Mar 2016 19:12:53 -0400 Subject: [PATCH] MT-34 "Import: Reportables" SOLVED Issue: Import: Reportables Cause: Nuevo requerimiento de funciones Solution: - Se implemento la clase \ProcessMaker\BusinessModel\ReportTable, donde se tienen los metodos para la importacion de Report-Tables y PM-Tables - Se implemente el metodo import en la clase \ProcessMaker\BusinessModel\Migrator\ReportTablesMigrator Note: Se deberan hacer la pruebas correspondientes en el modulo ADMIN>Settings>PMTables, las pruebas son: - Importar un file .pmt con Report-Tables y PM-Tables - Crear nuevos Report-Tables - Crear registros en un PM-Table - Otras pruebas que sean necesarias --- gulliver/thirdparty/propel/Propel.php | 3 +- workflow/engine/classes/class.processes.php | 1 + workflow/engine/controllers/pmTablesProxy.php | 767 +++--------------- .../Migrator/ReportTablesMigrator.php | 51 +- .../BusinessModel/ReportTable.php | 706 ++++++++++++++++ 5 files changed, 858 insertions(+), 670 deletions(-) create mode 100644 workflow/engine/src/ProcessMaker/BusinessModel/ReportTable.php diff --git a/gulliver/thirdparty/propel/Propel.php b/gulliver/thirdparty/propel/Propel.php index 05a909cf3..a0732b12c 100755 --- a/gulliver/thirdparty/propel/Propel.php +++ b/gulliver/thirdparty/propel/Propel.php @@ -620,8 +620,7 @@ class Propel { public static function getDbConnection($name) { /*----------------------------------********---------------------------------*/ - $licensedFeatures = & PMLicensedFeatures::getSingleton(); - if (! $licensedFeatures->verifyfeature('02YeEFKNnVoOWFKMzN4ZmpXT0V3MU9SVklnOXNCcE9zcXJKa0tpemNmQkJ5OTUvOWlLdFhibGp0MHVHUlV0VmNpNw==')) { + if (!PMLicensedFeatures::getSingleton()->verifyfeature('02YeEFKNnVoOWFKMzN4ZmpXT0V3MU9SVklnOXNCcE9zcXJKa0tpemNmQkJ5OTUvOWlLdFhibGp0MHVHUlV0VmNpNw==')) { /*----------------------------------********---------------------------------*/ return null; /*----------------------------------********---------------------------------*/ diff --git a/workflow/engine/classes/class.processes.php b/workflow/engine/classes/class.processes.php index ba9b36ebd..7b2f6fc00 100755 --- a/workflow/engine/classes/class.processes.php +++ b/workflow/engine/classes/class.processes.php @@ -3217,6 +3217,7 @@ class Processes $getalldditionalTables = $additionalTables->getReportTables($sProUid); foreach ($getalldditionalTables as $row) { + $additionalTables = new AdditionalTables(); $additionalTables->setAddTabUid($row['ADD_TAB_UID']); $fieldsAdditionalTables = $additionalTables->getFields(); foreach ($fieldsAdditionalTables as $rowField) { diff --git a/workflow/engine/controllers/pmTablesProxy.php b/workflow/engine/controllers/pmTablesProxy.php index 5126d269e..fc67bae8a 100755 --- a/workflow/engine/controllers/pmTablesProxy.php +++ b/workflow/engine/controllers/pmTablesProxy.php @@ -117,7 +117,7 @@ class pmTablesProxy extends HttpProxyController $proUid = $_POST['PRO_UID']; $dbConn = new DbConnections(); $dbConnections = $dbConn->getConnectionsProUid( $proUid, array('mysql') ); - + $workSpace = new workspaceTools(SYS_SYS); $workspaceDB = $workSpace->getDBInfo(); @@ -125,11 +125,11 @@ class pmTablesProxy extends HttpProxyController $defaultConnections = array (array ('DBS_UID' => 'workflow','DBS_NAME' => 'Workflow')); } else { $defaultConnections = array (array ('DBS_UID' => 'workflow','DBS_NAME' => 'Workflow'), - array ('DBS_UID' => 'rp','DBS_NAME' => 'REPORT')); + array ('DBS_UID' => 'rp','DBS_NAME' => 'REPORT')); } - + $dbConnections = array_merge( $defaultConnections, $dbConnections ); - + return $dbConnections; } @@ -210,185 +210,13 @@ class pmTablesProxy extends HttpProxyController */ public function save ($httpData, $alterTable = true) { - //require_once 'classes/model/AdditionalTables.php'; - //require_once 'classes/model/Fields.php'; - $result = new StdClass(); - try { - ob_start(); - $data = (array) $httpData; - $data['PRO_UID'] = trim( $data['PRO_UID'] ); - $data['columns'] = G::json_decode( stripslashes( $httpData->columns ) ); //decofing data columns + $reportTable = new \ProcessMaker\BusinessModel\ReportTable(); - $isReportTable = $data['PRO_UID'] != '' ? true : false; - $oAdditionalTables = new AdditionalTables(); - $oFields = new Fields(); - $repTabClassName = $oAdditionalTables->getPHPName( $data['REP_TAB_NAME'] ); - $columns = $data['columns']; - - // Reserved Words Table - $reservedWords = array ('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 = array ('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 ($data['REP_TAB_UID'] == '' || (isset( $httpData->forceUid ) && $httpData->forceUid)) { - //new report table - if ($isReportTable && $alterTable) { - //setting default columns - $defaultColumns = $this->_getReportTableDefaultColumns( $data['REP_TAB_TYPE'] ); - $columns = array_merge( $defaultColumns, $columns ); - } - - /** - * validations * - */ - if (is_array( $oAdditionalTables->loadByName( $data['REP_TAB_NAME'] ) )) { - throw new Exception( G::loadTranslation( 'ID_PMTABLE_ALREADY_EXISTS', array ($data['REP_TAB_NAME'] - ) ) ); - } - - if (in_array( strtoupper( $data["REP_TAB_NAME"] ), $reservedWords ) || in_array( strtoupper( $data["REP_TAB_NAME"] ), $reservedWordsSql )) { - throw (new Exception( G::LoadTranslation( "ID_PMTABLE_INVALID_NAME", array ($data["REP_TAB_NAME"] - ) ) )); - } - } - //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", array ($columns[$i]->field_name - ) ) )); - } - - switch ($column->field_type) { - case 'INT': - $columns[$i]->field_type = 'INTEGER'; - break; - case 'TEXT': - $columns[$i]->field_type = 'LONGVARCHAR'; - break; - // propel DATETIME equivalent is TIMESTAMP - case 'DATETIME': - $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; - } - } - } - - G::LoadClass("pmTable"); - - $pmTable = new pmTable( $data['REP_TAB_NAME'] ); - $pmTable->setDataSource( $data['REP_TAB_CONNECTION'] ); - $pmTable->setColumns( $columns ); - $pmTable->setAlterTable( $alterTable ); - - if (isset($data["keepData"]) && $data["keepData"] == 1) { - //PM Table - $pmTable->setKeepData(true); - } - - $pmTable->build(); - - $buildResult = ob_get_contents(); - ob_end_clean(); - - // Updating additional table struture information - $addTabData = array ('ADD_TAB_UID' => $data['REP_TAB_UID'],'ADD_TAB_NAME' => $data['REP_TAB_NAME'],'ADD_TAB_CLASS_NAME' => $repTabClassName,'ADD_TAB_DESCRIPTION' => $data['REP_TAB_DSC'],'ADD_TAB_PLG_UID' => '','DBS_UID' => ($data['REP_TAB_CONNECTION'] ? $data['REP_TAB_CONNECTION'] : 'workflow'),'PRO_UID' => $data['PRO_UID'],'ADD_TAB_TYPE' => $data['REP_TAB_TYPE'],'ADD_TAB_GRID' => $data['REP_TAB_GRID'] - ); - if ($data['REP_TAB_UID'] == '' || (isset( $httpData->forceUid ) && $httpData->forceUid)) { - //new report table - //create record - - $addTabUid = $oAdditionalTables->create( $addTabData ); - } else { - //editing report table - //updating record - $addTabUid = $data['REP_TAB_UID']; - $oAdditionalTables->update( $addTabData ); - - //removing old data fields references - $oCriteria = new Criteria( 'workflow' ); - $oCriteria->add( FieldsPeer::ADD_TAB_UID, $data['REP_TAB_UID'] ); - FieldsPeer::doDelete( $oCriteria ); - } - // Updating pmtable fields - foreach ($columns as $i => $column) { - $field = array ( - '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 - ); - $oFields->create( $field ); - } - - if ($isReportTable && $alterTable) { - // the table was create successfully but we're catching problems while populating table - try { - $oAdditionalTables->populateReportTable( $data['REP_TAB_NAME'], $pmTable->getDataSource(), $data['REP_TAB_TYPE'], $data['PRO_UID'], $data['REP_TAB_GRID'], $addTabUid ); - } catch (Exception $e) { - $result->message = $result->msg = $e->getMessage(); - } - } - - //--- Message 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($data["REP_TAB_UID"]) && $data["REP_TAB_UID"] == "")? "CreatePmtable" : "UpdatePmtable", "Fields: " . $fieldsName); - - $result->success = true; - $result->message = $result->msg = $buildResult; + return $reportTable->saveStructureOfTable((array)($httpData), $alterTable); } catch (Exception $e) { - $result = new stdClass(); - $buildResult = 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(); + throw $e; } - - return $result; } /** @@ -447,16 +275,16 @@ class pmTablesProxy extends HttpProxyController } else { $at->deleteAll( $row->id ); $count ++; - } + } $oCriteria = new Criteria('workflow'); $oCriteria->add(CaseConsolidatedCorePeer::REP_TAB_UID, $row->id); $oResult = CaseConsolidatedCorePeer::doSelectOne($oCriteria); - if(!empty($oResult)) { + if(!empty($oResult)) { $sTasUid = $oResult->getTasUid(); $oCaseConsolidated = new CaseConsolidatedCore(); - $oCaseConsolidated = CaseConsolidatedCorePeer::retrieveByPK($sTasUid); - $oCaseConsolidated->delete(); + $oCaseConsolidated = CaseConsolidatedCorePeer::retrieveByPK($sTasUid); + $oCaseConsolidated->delete(); } } catch (Exception $e) { $tableName = isset( $table['ADD_TAB_NAME'] ) ? $table['ADD_TAB_NAME'] : $row->id; @@ -534,68 +362,22 @@ class pmTablesProxy extends HttpProxyController */ public function dataCreate ($httpData, $codification = 'json') { - if ($codification == 'base64') { - $rows = unserialize( base64_decode( $httpData->rows ) ); - } else { - $rows = G::json_decode( $httpData->rows ); - } + $result = new stdClass(); try { - require_once 'classes/model/AdditionalTables.php'; - $additionalTables = new AdditionalTables(); - $table = $additionalTables->load( $httpData->id, true ); - $primaryKeys = $additionalTables->getPrimaryKeys(); + $reportTable = new \ProcessMaker\BusinessModel\ReportTable(); - $this->className = $table['ADD_TAB_CLASS_NAME']; - $this->classPeerName = $this->className . 'Peer'; - $row = (array) $rows; + $arrayResult = $reportTable->createRecord((array)($httpData), $codification); - $row = array_merge( array_change_key_case( $row, CASE_LOWER ), array_change_key_case( $row, CASE_UPPER ) ); - $toSave = false; - - if (! file_exists( PATH_WORKSPACE . 'classes/' . $this->className . '.php' )) { - throw new Exception( 'Create::' . G::loadTranslation( 'ID_PMTABLE_CLASS_DOESNT_EXIST', $this->className ) ); - } - - require_once PATH_WORKSPACE . 'classes/' . $this->className . '.php'; - eval( '$obj = new ' . $this->className . '();' ); - - if (count( $row ) > 0) { - eval( '$con = Propel::getConnection(' . $this->classPeerName . '::DATABASE_NAME);' ); - $obj->fromArray( $row, BasePeer::TYPE_FIELDNAME ); - - if ($obj->validate()) { - $obj->save(); - $toSave = true; - G::auditLog("AddDataPmtable", "Table Name: ".$table['ADD_TAB_NAME']." Table ID: (".$table['ADD_TAB_UID'].") "); - $primaryKeysValues = array (); - foreach ($primaryKeys as $primaryKey) { - $method = 'get' . AdditionalTables::getPHPName( $primaryKey['FLD_NAME'] ); - $primaryKeysValues[] = $obj->$method(); - } - } else { - $msg = ''; - foreach ($obj->getValidationFailures() as $objValidationFailure) { - $msg .= $objValidationFailure->getMessage() . "\n"; - } - throw new Exception( G::LoadTranslation('ID_ERROR_TRYING_INSERT'). '"' . $table['ADD_TAB_NAME'] . "\"\n" . $msg ); - } - - $index = G::encrypt( implode( ',', $primaryKeysValues ), 'pmtable' ); - } else { - $toSave = false; - } - - $result = new stdclass(); - if ($toSave) { + if ($arrayResult['success']) { $result->success = true; - $result->message = G::LoadTranslation('ID_RECORD_SAVED_SUCCESFULLY'); - $result->rows = $obj->toArray( BasePeer::TYPE_FIELDNAME ); - $result->rows['__index__'] = $index; + $result->message = $arrayResult['message']; + $result->rows = $arrayResult['rows']; + $result->rows['__index__'] = $arrayResult['index']; } else { $result->success = false; - $result->rows = array (); $result->message = '$$'; + $result->rows = []; } } catch (Exception $e) { $result->success = false; @@ -937,26 +719,26 @@ class pmTablesProxy extends HttpProxyController */ public function import ($httpData) { - define('ERROR_PM_TABLES_OVERWRITE', '1'); - define('ERROR_PROCESS_NOT_EXIST', '2'); - define('ERROR_RP_TABLES_OVERWRITE', '3'); - define('ERROR_NO_REPORT_TABLE', '4'); - define('ERROR_OVERWRITE_RELATED_PROCESS', '5'); + define('ERROR_PM_TABLES_OVERWRITE', 1); + define('ERROR_PROCESS_NOT_EXIST', 2); + define('ERROR_RP_TABLES_OVERWRITE', 3); + define('ERROR_NO_REPORT_TABLE', 4); + define('ERROR_OVERWRITE_RELATED_PROCESS', 5); + $fromAdmin = false; if (isset( $_POST["form"]["TYPE_TABLE"] ) && ! empty( $_POST["form"]["TYPE_TABLE"] )) { if($_POST["form"]["TYPE_TABLE"] == 'admin') { $fromAdmin = true; - } + } } - - require_once 'classes/model/AdditionalTables.php'; + try { $result = new stdClass(); $errors = ''; $fromConfirm = false; $overWrite = isset( $_POST['form']['OVERWRITE'] ) ? true : false; - + if (isset( $_POST["form"]["FROM_CONFIRM"] ) && ! empty( $_POST["form"]["FROM_CONFIRM"] )) { $fromConfirm = $_POST["form"]["FROM_CONFIRM"]; $_FILES['form'] = $_SESSION['FILES_FORM']; @@ -968,19 +750,15 @@ class pmTablesProxy extends HttpProxyController } $_SESSION['FILES_FORM'] = $_FILES['form']; - $oAdditionalTables = new AdditionalTables(); - $tableNameMap = array (); - $processQueue = array (); - $processQueueTables = array (); $PUBLIC_ROOT_PATH = PATH_DATA . 'sites' . PATH_SEP . SYS_SYS . PATH_SEP . 'public' . PATH_SEP; $filename = $_FILES['form']['name']['FILENAME']; $tempName = $_FILES['form']['tmp_name']['FILENAME']; - + if(!$fromConfirm) { G::uploadFile( $tempName, $PUBLIC_ROOT_PATH, $filename ); } - + if ($fromConfirm == 'clear') { $fromConfirm = true; } @@ -1003,14 +781,66 @@ class pmTablesProxy extends HttpProxyController } } + //Get Additional Tables + $arrayTableSchema = []; + $arrayTableData = []; + + $f = fopen($PUBLIC_ROOT_PATH . $filename, 'rb'); + + $fdata = intval(fread($f, 9)); + $type = fread($f, $fdata); + + while (!feof($f)) { + switch ($type) { + case '@META': + $fdata = intval(fread($f, 9)); + $metadata = fread($f, $fdata); + break; + case '@SCHEMA': + $fdataUid = intval(fread($f, 9)); + $uid = fread($f, $fdataUid ); + + $fdata = intval(fread($f, 9)); + $schema = fread($f, $fdata); + + $arrayTableSchema[] = unserialize($schema); + break; + case '@DATA': + $fdata = intval(fread($f, 9)); + $tableName = fread($f, $fdata); + + $fdata = intval(fread($f, 9)); + + if ($fdata > 0) { + $data = fread($f, $fdata); + + $arrayTableData[$tableName] = unserialize($data); + } + break; + } + + $fdata = intval(fread($f, 9)); + + if ($fdata > 0) { + $type = fread($f, $fdata); + } else { + break; + } + } + + fclose($f); + //First Validate the file - $pathPmtableFile = $PUBLIC_ROOT_PATH . $filename; + $reportTable = new \ProcessMaker\BusinessModel\ReportTable(); + $arrayOverwrite = array(); $arrayRelated = array(); $arrayMessage = array(); $validationType = 0; if(!$fromConfirm){ - $aErrors = $this->checkPmtFileThrowErrors($pathPmtableFile,$filename,$fromAdmin,$overWrite,$currentProUid); + $aErrors = $reportTable->checkPmtFileThrowErrors( + $arrayTableSchema, $currentProUid, $fromAdmin, $overWrite, $_POST['form']['PRO_UID'] + ); $countC = 0; $countM = 0; $countI = 0; @@ -1039,9 +869,23 @@ class pmTablesProxy extends HttpProxyController $arrayOfNew = $_POST["form"]["TABLES_OF_NEW"]; $aTablesCreateNew = explode('|',$arrayOfNew); $aTablesNoCreate = explode('|',$arrayOfNo); - $errors = $this->createStructureOfTables($pathPmtableFile, $fromAdmin, $currentProUid, true, $aTablesNoCreate, $aTablesCreateNew); + $errors = $reportTable->createStructureOfTables( + $arrayTableSchema, + $arrayTableData, + $currentProUid, + $fromAdmin, + true, + $aTablesNoCreate, + $aTablesCreateNew + ); } else { - $errors = $this->createStructureOfTables($pathPmtableFile, $fromAdmin, $currentProUid, true); + $errors = $reportTable->createStructureOfTables( + $arrayTableSchema, + $arrayTableData, + $currentProUid, + $fromAdmin, + true + ); } if ($errors == '') { @@ -1078,333 +922,6 @@ class pmTablesProxy extends HttpProxyController return $result; } - /** - * Review the *.pmt file and Throw all errors - * @param string $tableFile - * @param string $fileName - * @param bool $fromAdmin - * @param bool $overWrite - * @param string $currentProUid - * @return string $aErrors - */ - public static function checkPmtFileThrowErrors($tableFile,$fileName,$fromAdmin,$overWrite,$currentProUid){ - $aErrors = array(); - //Ask for all Process - $processMap = new processMap(); - $aProcess = G::json_decode($processMap->getAllProcesses()); - foreach($aProcess as $key => $val){ - if ($val->value != ''){ - $proUids[] = $val->value; - } - } - - $fp = fopen( $tableFile, "rb" ); - $fsData = intval( fread( $fp, 9 ) ); //reading the metadata - $sType = fread( $fp, $fsData ); - $count = 0; - while (! feof( $fp )) { - $validationType = 0; - switch ($sType) { - case '@META': - $fsData = intval( fread( $fp, 9 ) ); - $METADATA = fread( $fp, $fsData ); - break; - case '@SCHEMA': - $fsUid = intval( fread( $fp, 9 ) ); - $uid = fread( $fp, $fsUid ); - $fsData = intval( fread( $fp, 9 ) ); - $schema = fread( $fp, $fsData ); - $contentSchema = unserialize( $schema ); - //The table exists? - $additionalTable = new additionalTables(); - $tableExists = $additionalTable->loadByName( $contentSchema['ADD_TAB_NAME'] ); - - $tableProUid = isset($contentSchema["PRO_UID"])?$contentSchema["PRO_UID"]:$_POST["form"]["PRO_UID"]; - $isPmTable = empty($contentSchema["PRO_UID"])? true : false; - - if($fromAdmin) { - if($isPmTable){ - if ($tableExists !== false && !$overWrite) { - $aErrors[$count]['NAME_TABLE'] = $contentSchema['ADD_TAB_NAME']; - $aErrors[$count]['ERROR_TYPE'] = ERROR_PM_TABLES_OVERWRITE; - $aErrors[$count]['ERROR_MESS'] = G::loadTranslation('ID_OVERWRITE_PMTABLE', array($contentSchema['ADD_TAB_NAME'])); - $aErrors[$count]['IS_PMTABLE'] = $isPmTable; - $aErrors[$count]['PRO_UID'] = $tableProUid; - } - } else { - if(!in_array($tableProUid, $proUids)){ - $aErrors[$count]['NAME_TABLE'] = $contentSchema['ADD_TAB_NAME']; - $aErrors[$count]['ERROR_TYPE'] = ERROR_PROCESS_NOT_EXIST; - $aErrors[$count]['ERROR_MESS'] = G::loadTranslation('ID_PROCESS_NOT_EXIST', array($contentSchema['ADD_TAB_NAME'])); - $aErrors[$count]['IS_PMTABLE'] = $isPmTable; - $aErrors[$count]['PRO_UID'] = $tableProUid; - } else { - if ($tableExists !== false && !$overWrite) { - $aErrors[$count]['NAME_TABLE'] = $contentSchema['ADD_TAB_NAME']; - $aErrors[$count]['ERROR_TYPE'] = ERROR_RP_TABLES_OVERWRITE; - $aErrors[$count]['ERROR_MESS'] = G::loadTranslation('ID_OVERWRITE_RPTABLE', array($contentSchema['ADD_TAB_NAME'])); - $aErrors[$count]['IS_PMTABLE'] = $isPmTable; - $aErrors[$count]['PRO_UID'] = $tableProUid; - } - } - } - } else { - if($isPmTable){ - $aErrors[$count]['NAME_TABLE'] = $contentSchema['ADD_TAB_NAME']; - $aErrors[$count]['ERROR_TYPE'] = ERROR_NO_REPORT_TABLE; - $aErrors[$count]['ERROR_MESS'] = G::loadTranslation('ID_NO_REPORT_TABLE', array($contentSchema['ADD_TAB_NAME'])); - $aErrors[$count]['IS_PMTABLE'] = $isPmTable; - $aErrors[$count]['PRO_UID'] = $tableProUid; - } else { - if(!$currentProUid != $tableProUid){ - $aErrors[$count]['NAME_TABLE'] = $contentSchema['ADD_TAB_NAME']; - $aErrors[$count]['ERROR_TYPE'] = ERROR_OVERWRITE_RELATED_PROCESS; - $aErrors[$count]['ERROR_MESS'] = G::loadTranslation('ID_OVERWRITE_RELATED_PROCESS', array($contentSchema['ADD_TAB_NAME'])); - $aErrors[$count]['IS_PMTABLE'] = $isPmTable; - $aErrors[$count]['PRO_UID'] = $tableProUid; - } else { - if ($tableExists !== false && !$overWrite) { - $aErrors[$count]['NAME_TABLE'] = $contentSchema['ADD_TAB_NAME']; - $aErrors[$count]['ERROR_TYPE'] = ERROR_RP_TABLES_OVERWRITE; - $aErrors[$count]['ERROR_MESS'] = G::loadTranslation('ID_OVERWRITE_RPTABLE', array($contentSchema['ADD_TAB_NAME'])); - $aErrors[$count]['IS_PMTABLE'] = $isPmTable; - $aErrors[$count]['PRO_UID'] = $tableProUid; - } - } - } - } - break; - case '@DATA': - break; - } - - $fsData = intval( fread( $fp, 9 ) ); - if ($fsData > 0) { - $sType = fread( $fp, $fsData ); - } else { - break; - } - $count++; - } - fclose( $fp ); - return $aErrors; - } - - /** - * Create the structure of tables - * @param string $tableFile, - * @param bool $fromAdmin - * @param string $currentProUid - * @param bool $overWrite - * @param array $aTables - * @return string $errors - */ - public function createStructureOfTables($tableFile,$fromAdmin,$currentProUid,$overWrite = true, $aTables=array(), $aTablesNew=array()){ - - $fp = fopen( $tableFile, "rb" ); - $fsData = intval( fread( $fp, 9 ) ); - $sType = fread( $fp, $fsData ); - $errors = ''; - $tableNameMap = array(); - $processQueue = array(); - $processQueueTables = array(); - while (! feof( $fp )) { - $validationType = 0; - switch ($sType) { - case '@META': - $fsData = intval( fread( $fp, 9 ) ); - $METADATA = fread( $fp, $fsData ); - break; - case '@SCHEMA': - $fsUid = intval( fread( $fp, 9 ) ); - $uid = fread( $fp, $fsUid ); - $fsData = intval( fread( $fp, 9 ) ); - $schema = fread( $fp, $fsData ); - $contentSchema = unserialize( $schema ); - $additionalTable = new additionalTables(); - if(!in_array($contentSchema['ADD_TAB_NAME'],$aTables)){ - $tableExists = $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"]; - } - $isPmTable = false; /*is a report table*/ - if($contentSchema["PRO_UID"] === '' ) { - $isPmTable = true; - } - if(!$fromAdmin && !$isPmTable) { - $tableData->PRO_UID = $currentProUid; - } - if(in_array($contentSchema['ADD_TAB_NAME'],$aTablesNew)){ - $overWrite = false; - } - if ($overWrite) { - if ($tableExists !== false) { - $additionalTable->deleteAll( $tableExists['ADD_TAB_UID'] ); - } - } else { - if ($tableExists !== false) { - // 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 = array (); - foreach ($contentSchema['FIELDS'] as $field) { - $column = array ( - '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 - ); - $columns[] = $column; - } - - $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->columns = G::json_encode( $columns ); - $tableData->forceUid = true; - - //save the table - $alterTable = false; - $result = $this->save( $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"; - } - } - break; - case '@DATA': - $fstName = intval( fread( $fp, 9 ) ); - $tableName = fread( $fp, $fstName ); - $fsData = intval( fread( $fp, 9 ) ); - if ($fsData > 0) { - $data = fread( $fp, $fsData ); - } - break; - } - - $fsData = intval( fread( $fp, 9 ) ); //reading the metadata - if ($fsData > 0) { - // reading next block type - $sType = fread( $fp, $fsData ); - } else { - break; - } - } - fclose( $fp ); - - G::loadClass( 'pmTable' ); - foreach ($processQueueTables as $dbsUid => $tables) { - $pmTable = new pmTable(); - ob_start(); - $pmTable->buildModelFor( $dbsUid, $tables ); - $buildResult = ob_get_contents(); - ob_end_clean(); - $errors .= $pmTable->upgradeDatabaseFor( $pmTable->getDataSource(), $tables ); - } - if(sizeof($tableNameMap)>0){ - $errors = $this->dataProcessingOfTables($tableFile,$tableNameMap); - } - return $errors; - } - /** - * Review the *.pmt file and populate the data - * @param string $tableFile - * @param array $tableNameMap - * @return string errors - */ - public function dataProcessingOfTables($tableFile,$tableNameMap){ - $fp = fopen( $tableFile, "rb" ); - $fsData = intval( fread( $fp, 9 ) ); - $sType = fread( $fp, $fsData ); - $errors = ''; - while (! feof( $fp )) { - switch ($sType) { - case '@META': - case '@SCHEMA': - break; - case '@DATA': - $fstName = intval( fread( $fp, 9 ) ); - $tableName = fread( $fp, $fstName ); - $fsData = intval( fread( $fp, 9 ) ); - if ($fsData > 0) { - $data = fread( $fp, $fsData ); - $contentData = unserialize( $data ); - if(isset($tableNameMap[$tableName])){ - $tableName = $tableNameMap[$tableName]; - - $oAdditionalTables = new AdditionalTables(); - $table = $oAdditionalTables->loadByName( $tableName ); - $isReport = $table['PRO_UID'] !== '' ? true : false; - - if ($table !== false) { - if (! $isReport) { - if (count( $contentData ) > 0) { - $oAdditionalTables->load( $table['ADD_TAB_UID'], true ); - $primaryKeys = $oAdditionalTables->getPrimaryKeys(); - // Obtain a list of columns - $primaryKeyColumn = array(); - foreach ($contentData as $key => $row) { - $primaryKeyColumn[$key] = $row[$primaryKeys[0]['FLD_NAME']]; - } - unset($row); - array_multisort($primaryKeyColumn, SORT_ASC, $contentData); - foreach ($contentData as $row) { - $data = new StdClass(); - $data->id = $table['ADD_TAB_UID']; - $data->rows = base64_encode( serialize( $row ) ); - $res = $this->dataCreate( $data, 'base64' ); - if (! $res->success) { - $errors .= $res->message; - } - } - } - } - } - } - } - break; - } - - $fsData = intval( fread( $fp, 9 ) ); - if ($fsData > 0) { - $sType = fread( $fp, $fsData ); - } else { - break; - } - } - return $errors; - } /** * Export PM tables @@ -1669,82 +1186,6 @@ class pmTablesProxy extends HttpProxyController return $result; } - /** - * Get report table default columns - * - * @param $type - */ - protected function _getReportTableDefaultColumns ($type = 'NORMAL') - { - $defaultColumns = array (); - $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; - } - /** * Get all dynaform fields from a process (without grid fields) * @@ -1863,7 +1304,7 @@ class pmTablesProxy extends HttpProxyController } $oDataset->next(); } - + // getting bpmn projects $oCriteria = new Criteria('workflow'); $oCriteria->addSelectColumn(BpmnProcessPeer::PRJ_UID); @@ -1911,7 +1352,7 @@ class pmTablesProxy extends HttpProxyController "_index" => $index ++, "_isset" => true )); - } + } array_push($fieldsNames, $row["VAR_NAME"]); @@ -2064,9 +1505,9 @@ class pmTablesProxy extends HttpProxyController } return $aFields; } - + /** - * Get all dynaform variables + * Get all dynaform variables * * @param $sProcessUID */ diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/Migrator/ReportTablesMigrator.php b/workflow/engine/src/ProcessMaker/BusinessModel/Migrator/ReportTablesMigrator.php index b9883cbd9..68954d28a 100644 --- a/workflow/engine/src/ProcessMaker/BusinessModel/Migrator/ReportTablesMigrator.php +++ b/workflow/engine/src/ProcessMaker/BusinessModel/Migrator/ReportTablesMigrator.php @@ -29,11 +29,52 @@ class ReportTablesMigrator implements Importable, Exportable public function import($data, $replace) { try { - $aReportTablesVars = array(); - if ($replace) { - //Todo Create - } else { - //Todo addOnlyNew + $reportTable = new \ProcessMaker\BusinessModel\ReportTable(); + + $arrayTableSchema = []; + $arrayTablesToExclude = []; + $processUid = ''; + + foreach ($data['reportTablesDefinition'] as $value) { + $arrayTable = $value; + + $processUid = $arrayTable['PRO_UID']; + + $arrayField = []; + + foreach ($data['reportTablesFields'] as $value2) { + if ($value2['ADD_TAB_UID'] == $arrayTable['ADD_TAB_UID']) { + unset($value2['ADD_TAB_UID']); + + $arrayField[] = $value2; + } + } + + if (!empty($arrayField)) { + $arrayTable['FIELDS'] = $arrayField; + + $arrayTableSchema[] = $arrayTable; + + //$replace: true //Delete all tables and create it again + //$replace: false //Only create the tables that do not exist + if (!$replace) { + $additionalTable = new \AdditionalTables(); + + if ($additionalTable->loadByName($arrayTable['ADD_TAB_NAME']) !== false) { + $arrayTablesToExclude[] = $arrayTable['ADD_TAB_NAME']; + } + } + } + } + + if (!empty($arrayTableSchema)) { + $errors = $reportTable->createStructureOfTables( + $arrayTableSchema, [], $processUid, false, true, $arrayTablesToExclude + ); + + if ($errors != '') { + throw new \Exception($errors); + } } } catch (\Exception $e) { $exception = new ImportException($e->getMessage()); diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/ReportTable.php b/workflow/engine/src/ProcessMaker/BusinessModel/ReportTable.php new file mode 100644 index 000000000..2cd8b52ac --- /dev/null +++ b/workflow/engine/src/ProcessMaker/BusinessModel/ReportTable.php @@ -0,0 +1,706 @@ +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 !== false) { + $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 !== false && !$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 !== false && !$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 !== false && !$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 + * + * @return object + */ + public function saveStructureOfTable($arrayData, $flagAlterTable = true) + { + $result = new \stdClass(); + + try { + ob_start(); + + $arrayData['PRO_UID'] = trim($arrayData['PRO_UID']); + $arrayData['columns'] = \G::json_decode(stripslashes($arrayData['columns'])); //Decofing data columns + + $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']])); + } + } + + //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['keepData']) && $arrayData['keepData'] == 1) { + //PM Table + $pmTable->setKeepData(true); + } + + $pmTable->build(); + + $buildResult = 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'] + ]; + + 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; + } catch (\Exception $e) { + $buildResult = 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; + } + + /** + * 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 !== false) { + $additionalTable->deleteAll($arrayAdditionalTableData['ADD_TAB_UID']); + } + } else { + if ($arrayAdditionalTableData !== false) { + //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->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(); + 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; + } + } +} +