diff --git a/workflow/engine/classes/class.processes.php b/workflow/engine/classes/class.processes.php index 1d998e61d..c39c52a81 100644 --- a/workflow/engine/classes/class.processes.php +++ b/workflow/engine/classes/class.processes.php @@ -4018,11 +4018,23 @@ class Processes { try { $webEntry = new \ProcessMaker\BusinessModel\WebEntry(); - foreach ($arrayData as $value) { $record = $value; - - $arrayWebEntryData = $webEntry->create($processUid, $userUidCreator, $record); + //This $record["WE_TITLE"] value only exists for bpmn projects, because + //it is saving the value in the 'CONTENT' table when creating the + //web entry from the designer. A classic process uses the methods + //of bpmn to be able to perform the import of the web entry so this + //value is required, since for the classics the name of the dynaform + //is used as filename, this value is filled with this option. + if (empty($record["WE_TITLE"])) { + $fileName = $record["WE_DATA"]; + $name = pathinfo($fileName, PATHINFO_FILENAME); + $record["WE_TITLE"] = $name; + } + //The false parameter is sent in order to prevent the WebEntry::create + //method from performing integrity validation with tasks and users + //assigned to the task and other tables related to web entry + $arrayWebEntryData = $webEntry->create($processUid, $userUidCreator, $record, false); } } catch (Exception $e) { throw $e; diff --git a/workflow/engine/classes/class.wsTools.php b/workflow/engine/classes/class.wsTools.php index 3e1a0af59..29d8be18d 100644 --- a/workflow/engine/classes/class.wsTools.php +++ b/workflow/engine/classes/class.wsTools.php @@ -188,6 +188,12 @@ class workspaceTools $this->migratePopulateIndexingACV($workSpace); $stop = microtime(true); CLI::logging("<*> Migrating an populating indexing for avoiding the use of table APP_CACHE_VIEW process took " . ($stop - $start) . " seconds.\n"); + + $start = microtime(true); + CLI::logging("> Updating rows in Web Entry table for classic processes...\n"); + $this->updatingWebEntryClassicModel($workSpace); + $stop = microtime(true); + CLI::logging("<*> Updating rows in Web Entry table for classic processes took " . ($stop - $start) . " seconds.\n"); } /** @@ -3675,5 +3681,105 @@ class workspaceTools CLI::logging("-> Populating PRO_ID, USR_ID at LIST_* Done \n"); } + + /** + * It populates the WEB_ENTRY table for the classic processes, this procedure + * is done to verify the execution of php files generated when the WebEntry + * is configured. + * @param type $workSpace + */ + public function updatingWebEntryClassicModel($workSpace, $force = false) + { + //We obtain from the configuration the list of proUids obtained so that + //we do not go through again. + $cfgUid = 'UPDATING_ROWS_WEB_ENTRY'; + $objUid = 'blackList'; + $blackList = []; + $conf = new Configuration(); + $ifExists = $conf->exists($cfgUid, $objUid); + if ($ifExists) { + $oConfig = $conf->load($cfgUid, $objUid); + $blackList = unserialize($oConfig['CFG_VALUE']); + } + + //The following query returns all the classic processes that do not have + //a record in the WEB_ENTRY table. + $oCriteria = new Criteria("workflow"); + $oCriteria->addSelectColumn(ProcessPeer::PRO_UID); + $oCriteria->addSelectColumn(BpmnProcessPeer::PRJ_UID); + $oCriteria->addJoin(ProcessPeer::PRO_UID, BpmnProcessPeer::PRJ_UID, Criteria::LEFT_JOIN); + $oCriteria->addJoin(ProcessPeer::PRO_UID, WebEntryPeer::PRO_UID, Criteria::LEFT_JOIN); + $oCriteria->add(BpmnProcessPeer::PRJ_UID, null, Criteria::EQUAL); + $oCriteria->add(WebEntryPeer::PRO_UID, null, Criteria::EQUAL); + if ($force === false) { + $oCriteria->add(ProcessPeer::PRO_UID, $blackList, Criteria::NOT_IN); + } + $rsCriteria = ProcessPeer::doSelectRS($oCriteria); + $rsCriteria->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $process = new Process(); + while ($rsCriteria->next()) { + $row = $rsCriteria->getRow(); + $proUid = $row['PRO_UID']; + if (!in_array($proUid, $blackList)) { + $blackList[] = $proUid; + } + $path = PATH_DATA . "sites" . PATH_SEP . $this->name . PATH_SEP . "public" . PATH_SEP . $proUid; + if (is_dir($path)) { + $dir = opendir($path); + while ($fileName = readdir($dir)) { + if ($fileName !== "." && $fileName !== ".." && strpos($fileName, "wsClient.php") === false && strpos($fileName, "Post.php") === false + ) { + CLI::logging("Verifying if file: " . $fileName . " is a web entry\n"); + $step = new Criteria("workflow"); + $step->addSelectColumn(StepPeer::PRO_UID); + $step->addSelectColumn(StepPeer::TAS_UID); + $step->addSelectColumn(StepPeer::STEP_TYPE_OBJ); + $step->addSelectColumn(StepPeer::STEP_UID_OBJ); + $step->add(StepPeer::STEP_TYPE_OBJ, "DYNAFORM", Criteria::EQUAL); + $step->add(StepPeer::PRO_UID, $proUid, Criteria::EQUAL); + $stepRs = StepPeer::doSelectRS($step); + $stepRs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + while ($stepRs->next()) { + $row1 = $stepRs->getRow(); + $content = file_get_contents($path . "/" . $fileName); + if (strpos($content, $proUid . "/" . $row1["STEP_UID_OBJ"]) !== false) { + //The default user admin is set. This task is + //carried out by the system administrator. + $userUid = "00000000000000000000000000000001"; + //save data in table WEB_ENTRY + $arrayData = [ + "PRO_UID" => $proUid, + "DYN_UID" => $row1["STEP_UID_OBJ"], + "TAS_UID" => $row1["TAS_UID"], + "WE_DATA" => $fileName, + "USR_UID" => $userUid, + "WE_CREATE_USR_UID" => $userUid, + "WE_UPDATE_USR_UID" => $userUid + ]; + $webEntry = new \ProcessMaker\BusinessModel\WebEntry(); + $webEntry->createClassic($arrayData); + } + } + } + } + } + } + + //The list of proUids obtained is saved in the configuration so that it + //does not go through again. + $data = [ + "CFG_UID" => $cfgUid, + "OBJ_UID" => $objUid, + "CFG_VALUE" => serialize($blackList), + "PRO_UID" => '', + "USR_UID" => '', + "APP_UID" => '' + ]; + if ($ifExists) { + $conf->update($data); + } else { + $conf->create($data); + } + } } diff --git a/workflow/engine/methods/processes/processes_Ajax.php b/workflow/engine/methods/processes/processes_Ajax.php index 1d23d5ae8..e0a582bc5 100644 --- a/workflow/engine/methods/processes/processes_Ajax.php +++ b/workflow/engine/methods/processes/processes_Ajax.php @@ -193,17 +193,18 @@ try { G::LoadSystem('inputfilter'); $filter = new InputFilter(); $form = $_REQUEST; - if(file_exists(PATH_DATA . "sites" . PATH_SEP . SYS_SYS . PATH_SEP . "public" . PATH_SEP . $form['PRO_UID'] . PATH_SEP . $form['FILENAME'])) { - unlink($filter->validateInput(PATH_DATA . "sites" . PATH_SEP . SYS_SYS . PATH_SEP . "public" . - PATH_SEP . $form['PRO_UID'] . PATH_SEP . $form['FILENAME'], 'path')); + $filePath = PATH_DATA . "sites" . PATH_SEP . SYS_SYS . PATH_SEP . "public" . PATH_SEP . $form['PRO_UID'] . PATH_SEP . $form['FILENAME']; + if (file_exists($filePath)) { + unlink($filter->validateInput($filePath, 'path')); + $webEntry = new \ProcessMaker\BusinessModel\WebEntry(); + $webEntry->deleteClassic($form['PRO_UID'], $filePath); } - if(file_exists(PATH_DATA . "sites" . PATH_SEP . SYS_SYS . PATH_SEP . "public" . PATH_SEP . $form['PRO_UID'] . PATH_SEP . str_replace(".php", "Post", $form['FILENAME']) . ".php")) { - unlink($filter->validateInput(PATH_DATA . "sites" . PATH_SEP . SYS_SYS . PATH_SEP . "public" . - PATH_SEP . $form['PRO_UID'] . PATH_SEP . str_replace(".php", "Post", $form['FILENAME']) . ".php", - 'path')); + $filePath = PATH_DATA . "sites" . PATH_SEP . SYS_SYS . PATH_SEP . "public" . PATH_SEP . $form['PRO_UID'] . PATH_SEP . str_replace(".php", "Post", $form['FILENAME']) . ".php"; + if (file_exists($filePath)) { + unlink($filter->validateInput($filePath, 'path')); } $oProcessMap->webEntry($_REQUEST['PRO_UID']); - G::auditLog('WebEntry','Delete web entry ('.$form['FILENAME'].') in process "'.$resultProcess['PRO_TITLE'].'"'); + G::auditLog('WebEntry', 'Delete web entry (' . $form['FILENAME'] . ') in process "' . $resultProcess['PRO_TITLE'] . '"'); break; case 'webEntry_new': $oProcessMap->webEntry_new($oData->PRO_UID); diff --git a/workflow/engine/methods/processes/processes_webEntryGenerate.php b/workflow/engine/methods/processes/processes_webEntryGenerate.php index f6194487d..551c0cd87 100644 --- a/workflow/engine/methods/processes/processes_webEntryGenerate.php +++ b/workflow/engine/methods/processes/processes_webEntryGenerate.php @@ -106,6 +106,19 @@ try { file_put_contents( $fileName, $template->getOutputContent() ); } + //save data in table WEB_ENTRY + $arrayData = [ + "PRO_UID" => $sPRO_UID, + "DYN_UID" => $sDYNAFORM, + "TAS_UID" => $sTASKS, + "WE_DATA" => $dynTitle . ".php", + "USR_UID" => $_SESSION['USER_LOGGED'], + "WE_CREATE_USR_UID" => $_SESSION['USER_LOGGED'], + "WE_UPDATE_USR_UID" => $_SESSION['USER_LOGGED'] + ]; + $webEntry = new \ProcessMaker\BusinessModel\WebEntry(); + $webEntry->createClassic($arrayData); + require_once 'classes/model/Event.php'; $oEvent = new Event(); $aDataEvent = array (); diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/FilesManager.php b/workflow/engine/src/ProcessMaker/BusinessModel/FilesManager.php index 467f00eb3..910c28eb0 100644 --- a/workflow/engine/src/ProcessMaker/BusinessModel/FilesManager.php +++ b/workflow/engine/src/ProcessMaker/BusinessModel/FilesManager.php @@ -148,7 +148,7 @@ class FilesManager * * @access public */ - public function addProcessFilesManager($sProcessUID, $userUID, $aData) + public function addProcessFilesManager($sProcessUID, $userUID, $aData, $isImport = false) { try { $aData['prf_path'] = rtrim($aData['prf_path'], '/') . '/'; @@ -190,7 +190,7 @@ class FilesManager if ($extention == '.exe') { throw new \Exception(\G::LoadTranslation('ID_FILE_UPLOAD_INCORRECT_EXTENSION')); } - if (\Bootstrap::getDisablePhpUploadExecution() === 1 && $extention === '.php') { + if (\Bootstrap::getDisablePhpUploadExecution() === 1 && $extention === '.php' && !$isImport) { $message = \G::LoadTranslation('THE_UPLOAD_OF_PHP_FILES_WAS_DISABLED'); \Bootstrap::registerMonologPhpUploadExecution('phpUpload', 550, $message, $aData['prf_filename']); throw new \Exception($message); @@ -708,7 +708,7 @@ class FilesManager * * return void */ - public function processFilesUpgrade($projectUid = "") + public function processFilesUpgrade($projectUid = "", $isImport = false) { try { //Set variables @@ -778,7 +778,7 @@ class FilesManager "prf_content" => "" ); - $arrayData = $this->addProcessFilesManager($row["PRJ_UID"], "00000000000000000000000000000001", $arrayData); + $arrayData = $this->addProcessFilesManager($row["PRJ_UID"], "00000000000000000000000000000001", $arrayData, $isImport); rename($dir . PATH_SEP . $file . ".tmp", $dir . PATH_SEP . $file); } diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/WebEntry.php b/workflow/engine/src/ProcessMaker/BusinessModel/WebEntry.php index fa796a27f..d6e6add93 100644 --- a/workflow/engine/src/ProcessMaker/BusinessModel/WebEntry.php +++ b/workflow/engine/src/ProcessMaker/BusinessModel/WebEntry.php @@ -571,7 +571,7 @@ class WebEntry * * return array Return data of the new Web Entry created */ - public function create($processUid, $userUidCreator, array $arrayData) + public function create($processUid, $userUidCreator, array $arrayData, $validate = true) { try { //Verify data @@ -590,7 +590,9 @@ class WebEntry //Verify data $process->throwExceptionIfNotExistsProcess($processUid, $this->arrayFieldNameForException["processUid"]); - $this->throwExceptionIfDataIsInvalid("", $processUid, $arrayData); + if ($validate === true) { + $this->throwExceptionIfDataIsInvalid("", $processUid, $arrayData); + } //Create $cnn = \Propel::getConnection("workflow"); @@ -946,5 +948,90 @@ class WebEntry throw $e; } } + + /** + * Check the existence of a file of type web entry, returns true if it exists + * and false otherwise. Verification is done by the field WE_DATA and PRO_UID. + * The PRO_UID key and the file path are required. + * @param type $proUid + * @param type $filePath + * @return boolean + */ + public static function isWebEntry($proUid, $filePath) + { + $fileName = basename($filePath); + if (empty($proUid) || empty($fileName)) { + return false; + } + $fileName = trim($fileName); + $postfix = "Post.php"; + $n = strlen($postfix); + $string = substr($fileName, 0, -$n); + if ($string . $postfix === $fileName) { + $fileName = $string . ".php"; + } + $criteria = new \Criteria("workflow"); + $criteria->addSelectColumn(\WebEntryPeer::WE_DATA); + $criteria->add(\WebEntryPeer::PRO_UID, $proUid, \Criteria::EQUAL); + $criteria->add(\WebEntryPeer::WE_DATA, $fileName, \Criteria::EQUAL); + $resultSet = \WebEntryPeer::doSelectRS($criteria); + $resultSet->setFetchmode(\ResultSet::FETCHMODE_ASSOC); + $resultSet->next(); + $row = $resultSet->getRow(); + return isset($row["WE_DATA"]); + } + + /** + * Fill the WEB_ENTRY table for the classic processes. + * @param type $data + */ + public function createClassic($data) + { + $cnn = \Propel::getConnection("workflow"); + $criteria = new \Criteria("workflow"); + $criteria->add(\WebEntryPeer::PRO_UID, $data["PRO_UID"], \Criteria::EQUAL); + $criteria->add(\WebEntryPeer::WE_DATA, $data["WE_DATA"], \Criteria::EQUAL); + $result = \WebEntryPeer::doSelect($criteria, $cnn); + + if (isset($result[0])) { + $webEntry = $result[0]; + $webEntry->fromArray($data, \BasePeer::TYPE_FIELDNAME); + } else { + $webEntry = new \WebEntry(); + $webEntry->fromArray($data, \BasePeer::TYPE_FIELDNAME); + $webEntry->setWeUid(\ProcessMaker\Util\Common::generateUID()); + $webEntry->setWeCreateDate("now"); + $webEntry->setWeMethod("WS"); + $webEntry->setWeInputDocumentAccess(1); + } + $webEntry->setWeUpdateDate("now"); + + if ($webEntry->validate()) { + $cnn->begin(); + $result = $webEntry->save(); + $cnn->commit(); + } + } + + /** + * Removes a record from the WEB_ENTRY table for the classic processes. + * The PRO_UID key and the file path are required. + * @param type $proUid + * @param type $filePath + * @return boolean + */ + public function deleteClassic($proUid, $filePath) + { + $fileName = basename($filePath); + if (empty($proUid) || empty($fileName)) { + return false; + } + $criteria = new \Criteria("workflow"); + $criteria->add(\WebEntryPeer::PRO_UID, $proUid, \Criteria::EQUAL); + $criteria->add(\WebEntryPeer::WE_DATA, $fileName, \Criteria::EQUAL); + $result = \WebEntryPeer::doDelete($criteria); + return $result; + } + } diff --git a/workflow/engine/src/ProcessMaker/Importer/Importer.php b/workflow/engine/src/ProcessMaker/Importer/Importer.php index b03643944..701f3e326 100644 --- a/workflow/engine/src/ProcessMaker/Importer/Importer.php +++ b/workflow/engine/src/ProcessMaker/Importer/Importer.php @@ -596,7 +596,9 @@ abstract class Importer //Process-Files upgrade $filesManager = new \ProcessMaker\BusinessModel\FilesManager(); - $filesManager->processFilesUpgrade($projectUid); + //The true parameter tells the method to ignore the php file upload + //check when it is an import. + $filesManager->processFilesUpgrade($projectUid, true); //Return return $projectUid; diff --git a/workflow/public_html/sysGeneric.php b/workflow/public_html/sysGeneric.php index 78b1a4ae8..cc46b4782 100644 --- a/workflow/public_html/sysGeneric.php +++ b/workflow/public_html/sysGeneric.php @@ -798,13 +798,14 @@ if (substr( SYS_COLLECTION, 0, 8 ) === 'gulliver') { if ($extension != 'php') { //NewRelic Snippet - By JHL transactionLog($phpFile); - Bootstrap::streamFile( $phpFile ); + Bootstrap::streamFile($phpFile); die(); } Bootstrap::initVendors(); - Bootstrap::LoadSystem( 'monologProvider' ); - if (\Bootstrap::getDisablePhpUploadExecution() === 1) { + Bootstrap::LoadSystem('monologProvider'); + $isWebEntry = \ProcessMaker\BusinessModel\WebEntry::isWebEntry(SYS_COLLECTION, $phpFile); + if (\Bootstrap::getDisablePhpUploadExecution() === 1 && !$isWebEntry) { $message = \G::LoadTranslation('THE_PHP_FILES_EXECUTION_WAS_DISABLED'); \Bootstrap::registerMonologPhpUploadExecution('phpExecution', 550, $message, $phpFile); echo $message;