2014-03-07 09:51:05 -04:00
< ? php
namespace ProcessMaker\Importer ;
2014-03-28 12:57:55 -04:00
use ProcessMaker\Util ;
2014-04-30 12:00:22 -04:00
use ProcessMaker\Project ;
2014-03-28 12:57:55 -04:00
use ProcessMaker\Project\Adapter ;
2014-03-07 09:51:05 -04:00
abstract class Importer
{
2014-03-28 12:57:55 -04:00
protected $data = array ();
protected $importData = array ();
2014-03-07 09:51:05 -04:00
protected $filename = " " ;
protected $saveDir = " " ;
2014-04-07 16:10:42 -04:00
protected $metadata = array ();
2014-03-07 09:51:05 -04:00
2014-04-07 16:10:42 -04:00
const IMPORT_OPTION_OVERWRITE = " project.import.override " ;
const IMPORT_OPTION_DISABLE_AND_CREATE_NEW = " project.import.disable_and_create_new " ;
2014-04-30 12:00:22 -04:00
const IMPORT_OPTION_KEEP_WITHOUT_CHANGING_AND_CREATE_NEW = " project.import.keep_without_changing_and_create_new " ;
2014-04-07 16:10:42 -04:00
const IMPORT_OPTION_CREATE_NEW = " project.import.create_new " ;
2014-03-07 09:51:05 -04:00
/**
* Success , Project imported successfully .
*/
const IMPORT_STAT_SUCCESS = 100 ;
/**
* Error , Target Project already exists .
*/
const IMPORT_STAT_TARGET_ALREADY_EXISTS = 101 ;
/**
* Error , Invalid file type or the file have corrupt data .
*/
const IMPORT_STAT_INVALID_SOURCE_FILE = 102 ;
2014-03-28 12:57:55 -04:00
public abstract function load ();
2014-03-07 09:51:05 -04:00
2014-03-26 09:39:18 -04:00
public function import ( $option = self :: IMPORT_OPTION_CREATE_NEW )
{
2014-03-28 12:57:55 -04:00
$this -> prepare ();
2014-04-30 12:00:22 -04:00
$name = $this -> importData [ " tables " ][ " bpmn " ][ " project " ][ 0 ][ " prj_name " ];
2014-03-26 09:39:18 -04:00
switch ( $option ) {
case self :: IMPORT_OPTION_CREATE_NEW :
2014-04-07 16:10:42 -04:00
if ( $this -> targetExists ()) {
throw new \Exception ( sprintf (
" Project already exists, you need set an action to continue. " .
2014-05-06 15:38:34 -04:00
" Available actions: [%s|%s|%s|%s]. " , self :: IMPORT_OPTION_CREATE_NEW ,
self :: IMPORT_OPTION_OVERWRITE , self :: IMPORT_OPTION_DISABLE_AND_CREATE_NEW , self :: IMPORT_OPTION_KEEP_WITHOUT_CHANGING_AND_CREATE_NEW
2014-04-07 16:10:42 -04:00
), self :: IMPORT_STAT_TARGET_ALREADY_EXISTS );
}
$generateUid = false ;
2014-04-30 12:00:22 -04:00
break ;
case self :: IMPORT_OPTION_OVERWRITE :
$this -> removeProject ();
// this option shouldn't generate new uid for all objects
$generateUid = false ;
2014-03-26 09:39:18 -04:00
break ;
case self :: IMPORT_OPTION_DISABLE_AND_CREATE_NEW :
2014-04-07 16:10:42 -04:00
$this -> disableProject ();
// this option should generate new uid for all objects
$generateUid = true ;
2014-04-30 12:00:22 -04:00
$name = " New - " . $name . " - " . date ( " M d, H:i " );
2014-03-26 09:39:18 -04:00
break ;
2014-04-30 12:00:22 -04:00
case self :: IMPORT_OPTION_KEEP_WITHOUT_CHANGING_AND_CREATE_NEW :
// this option should generate new uid for all objects
$generateUid = true ;
$name = \G :: LoadTranslation ( " ID_COPY_OF " ) . " - " . $name . " - " . date ( " M d, H:i " );
2014-03-26 09:39:18 -04:00
break ;
}
2014-03-28 12:57:55 -04:00
2014-04-30 12:00:22 -04:00
$this -> importData [ " tables " ][ " bpmn " ][ " project " ][ 0 ][ " prj_name " ] = $name ;
$this -> importData [ " tables " ][ " bpmn " ][ " diagram " ][ 0 ][ " dia_name " ] = $name ;
$this -> importData [ " tables " ][ " bpmn " ][ " process " ][ 0 ][ " pro_name " ] = $name ;
$this -> importData [ " tables " ][ " workflow " ][ " process " ][ 0 ][ " PRO_TITLE " ] = $name ;
if ( $this -> importData [ " tables " ][ " workflow " ][ " process " ][ 0 ][ " PRO_UPDATE_DATE " ] . " " == " " ) {
$this -> importData [ " tables " ][ " workflow " ][ " process " ][ 0 ][ " PRO_UPDATE_DATE " ] = null ;
}
$this -> importData [ " tables " ][ " workflow " ][ " process " ] = $this -> importData [ " tables " ][ " workflow " ][ " process " ][ 0 ];
//Import
$result = $this -> doImport ( $generateUid );
//Return
2014-03-28 12:57:55 -04:00
return $result ;
}
/**
* Prepare for import , it makes all validations needed
* @ return int
* @ throws \Exception
*/
public function prepare ()
{
if ( $this -> validateSource () === false ) {
throw new \Exception (
" Error, Invalid file type or the file have corrupt data " ,
self :: IMPORT_STAT_INVALID_SOURCE_FILE
);
}
$this -> importData = $this -> load ();
$this -> validateImportData ();
}
public function setData ( $key , $value )
{
$this -> data [ $key ] = $value ;
2014-03-26 09:39:18 -04:00
}
/**
* Validates the source file
* @ return mixed
*/
public function validateSource ()
{
return true ;
}
2014-03-28 12:57:55 -04:00
public function validateImportData ()
{
if ( ! isset ( $this -> importData [ " tables " ][ " bpmn " ])) {
throw new \Exception ( " BPMN Definition is missing. " );
}
if ( ! isset ( $this -> importData [ " tables " ][ " bpmn " ][ " project " ]) || count ( $this -> importData [ " tables " ][ " bpmn " ][ " project " ]) !== 1 ) {
throw new \Exception ( " BPMN table: \" Project \" , definition is missing or has multiple definition. " );
}
return true ;
}
2014-03-26 09:39:18 -04:00
/**
* Verify if the project already exists
* @ return mixed
*/
public function targetExists ()
{
2014-03-28 12:57:55 -04:00
$prjUid = $this -> importData [ " tables " ][ " bpmn " ][ " project " ][ 0 ][ " prj_uid " ];
2014-03-26 09:39:18 -04:00
2014-03-28 12:57:55 -04:00
$bpmnProject = \BpmnProjectPeer :: retrieveByPK ( $prjUid );
2014-03-26 09:39:18 -04:00
2014-03-28 12:57:55 -04:00
return is_object ( $bpmnProject );
2014-03-26 09:39:18 -04:00
}
2014-03-07 09:51:05 -04:00
2014-03-26 09:39:18 -04:00
public function updateProject ()
{
}
2014-04-07 16:10:42 -04:00
public function disableProject ()
2014-03-26 09:39:18 -04:00
{
2014-04-07 16:10:42 -04:00
$project = \ProcessMaker\Project\Adapter\BpmnWorkflow :: load ( $this -> metadata [ " uid " ]);
$project -> setDisabled ();
}
2014-03-07 09:51:05 -04:00
2014-04-07 16:10:42 -04:00
public function removeProject ()
{
$project = \ProcessMaker\Project\Adapter\BpmnWorkflow :: load ( $this -> metadata [ " uid " ]);
$force = true ;
$project -> remove ( $force );
2014-03-26 09:39:18 -04:00
}
/**
* Sets the temporal file save directory
* @ param $dirName
*/
2014-03-07 09:51:05 -04:00
public function setSaveDir ( $dirName )
{
$this -> saveDir = rtrim ( $dirName , DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR ;
}
2014-03-26 09:39:18 -04:00
/**
* Gets the temporal file save directory
* @ return string
*/
2014-03-07 09:51:05 -04:00
public function getSaveDir ()
{
if ( empty ( $this -> saveDir )) {
$this -> saveDir = sys_get_temp_dir () . DIRECTORY_SEPARATOR ;
}
return $this -> saveDir ;
}
2014-03-26 09:39:18 -04:00
/**
* Sets the temporal source file
* @ param $filename
*/
2014-03-07 09:51:05 -04:00
public function setSourceFile ( $filename )
{
$this -> filename = $filename ;
}
2014-03-26 09:39:18 -04:00
/**
* Set source from Global Http Request resource
* @ param $varName
* @ throws \Exception
*/
2014-03-07 09:51:05 -04:00
public function setSourceFromGlobals ( $varName )
{
if ( ! array_key_exists ( $varName , $_FILES )) {
throw new \Exception ( " Couldn't find specified source \" $varName\ " in PHP Globals " );
}
$data = $_FILES [ $varName ];
2014-05-06 15:38:34 -04:00
if ( $data [ " error " ] != 0 ) {
2014-03-07 09:51:05 -04:00
throw new \Exception ( " Error while uploading file. Error code: { $data [ " error " ] } " );
}
2014-05-14 09:16:20 -04:00
if ( ! is_dir ( $this -> getSaveDir ())) {
Util\Common :: mk_dir ( $this -> getSaveDir ());
}
2014-03-07 09:51:05 -04:00
$this -> filename = $this -> getSaveDir () . $data [ " name " ];
$oldUmask = umask ( 0 );
move_uploaded_file ( $data [ " tmp_name " ], $this -> filename );
@ chmod ( $this -> filename , 0755 );
umask ( $oldUmask );
}
2014-04-07 16:10:42 -04:00
protected function importBpmnTables ( array $tables , $generateUid = false )
2014-03-07 09:51:05 -04:00
{
2014-03-28 12:57:55 -04:00
// Build BPMN project struct
$project = $tables [ " project " ][ 0 ];
$diagram = $tables [ " diagram " ][ 0 ];
$diagram [ " activities " ] = $tables [ " activity " ];
$diagram [ " artifacts " ] = array ();
$diagram [ " events " ] = $tables [ " event " ];
$diagram [ " flows " ] = $tables [ " flow " ];
$diagram [ " gateways " ] = $tables [ " gateway " ];
$diagram [ " lanes " ] = array ();
$diagram [ " laneset " ] = array ();
$project [ " diagrams " ] = array ( $diagram );
$project [ " prj_author " ] = isset ( $this -> data [ " usr_uid " ]) ? $this -> data [ " usr_uid " ] : " 00000000000000000000000000000001 " ;
$project [ " process " ] = $tables [ " process " ][ 0 ];
2014-04-07 16:10:42 -04:00
return Adapter\BpmnWorkflow :: createFromStruct ( $project , $generateUid );
2014-03-28 12:57:55 -04:00
}
2014-03-07 09:51:05 -04:00
2014-03-28 12:57:55 -04:00
protected function importWfTables ( array $tables )
{
$tables = ( object ) $tables ;
$processes = new \Processes ();
2014-04-30 12:00:22 -04:00
2014-03-28 12:57:55 -04:00
$processes -> createProcessPropertiesFromData ( $tables );
}
protected function importWfFiles ( array $workflowFiles )
{
foreach ( $workflowFiles as $target => $files ) {
switch ( $target ) {
case " dynaforms " :
$basePath = PATH_DYNAFORM ;
break ;
case " public " :
$basePath = PATH_DATA . " sites " . PATH_SEP . SYS_SYS . PATH_SEP . " public " . PATH_SEP ;
break ;
case " templates " :
$basePath = PATH_DATA . " sites " . PATH_SEP . SYS_SYS . PATH_SEP . " mailTemplates " . PATH_SEP ;
break ;
default :
$basePath = " " ;
}
2014-05-06 15:38:34 -04:00
if ( empty ( $basePath )) {
continue ;
}
2014-03-28 12:57:55 -04:00
foreach ( $files as $file ) {
$filename = $basePath . $file [ " file_path " ];
$path = dirname ( $filename );
if ( ! is_dir ( $path )) {
Util\Common :: mk_dir ( $path , 0775 );
}
file_put_contents ( $filename , $file [ " file_content " ]);
chmod ( $filename , 0775 );
}
2014-03-07 09:51:05 -04:00
}
2014-03-28 12:57:55 -04:00
}
2014-04-07 16:10:42 -04:00
public function doImport ( $generateUid = true )
2014-03-28 12:57:55 -04:00
{
2014-04-30 12:00:22 -04:00
$arrayBpmnTables = $this -> importData [ " tables " ][ " bpmn " ];
$arrayWorkflowTables = $this -> importData [ " tables " ][ " workflow " ];
$arrayWorkflowFiles = $this -> importData [ " files " ][ " workflow " ];
2014-03-28 12:57:55 -04:00
2014-04-30 12:00:22 -04:00
//Import BPMN tables
$result = $this -> importBpmnTables ( $arrayBpmnTables , $generateUid );
2014-03-07 09:51:05 -04:00
2014-04-30 12:00:22 -04:00
$projectUidOld = $arrayBpmnTables [ " project " ][ 0 ][ " prj_uid " ];
$projectUid = ( $generateUid ) ? $result [ 0 ][ " new_uid " ] : $result ;
//Import workflow tables
2014-04-07 16:10:42 -04:00
if ( $generateUid ) {
2014-04-30 12:00:22 -04:00
//Update TAS_UID
foreach ( $arrayWorkflowTables [ " tasks " ] as $key1 => $value1 ) {
$taskUid = $arrayWorkflowTables [ " tasks " ][ $key1 ][ " TAS_UID " ];
foreach ( $result as $value2 ) {
$arrayItem = $value2 ;
if ( $arrayItem [ " old_uid " ] == $taskUid ) {
$arrayWorkflowTables [ " tasks " ][ $key1 ][ " TAS_UID_OLD " ] = $taskUid ;
$arrayWorkflowTables [ " tasks " ][ $key1 ][ " TAS_UID " ] = $arrayItem [ " new_uid " ];
break ;
}
}
}
//Workflow tables
$workflowTables = ( object )( $arrayWorkflowTables );
$processes = new \Processes ();
$processes -> setProcessGUID ( $workflowTables , $projectUid );
$processes -> renewAll ( $workflowTables );
$arrayWorkflowTables = ( array )( $workflowTables );
//Workflow files
foreach ( $arrayWorkflowFiles as $key1 => $value1 ) {
$arrayFiles = $value1 ;
foreach ( $arrayFiles as $key2 => $value2 ) {
$file = $value2 ;
$arrayWorkflowFiles [ $key1 ][ $key2 ][ " file_path " ] = str_replace ( $projectUidOld , $projectUid , $file [ " file_path " ]);
$arrayWorkflowFiles [ $key1 ][ $key2 ][ " file_content " ] = str_replace ( $projectUidOld , $projectUid , $file [ " file_content " ]);
}
}
if ( isset ( $arrayWorkflowTables [ " uid " ])) {
foreach ( $arrayWorkflowTables [ " uid " ] as $key1 => $value1 ) {
$arrayT = $value1 ;
foreach ( $arrayT as $key2 => $value2 ) {
$uidOld = $key2 ;
$uid = $value2 ;
foreach ( $arrayWorkflowFiles as $key3 => $value3 ) {
$arrayFiles = $value3 ;
foreach ( $arrayFiles as $key4 => $value4 ) {
$file = $value4 ;
$arrayWorkflowFiles [ $key3 ][ $key4 ][ " file_path " ] = str_replace ( $uidOld , $uid , $file [ " file_path " ]);
$arrayWorkflowFiles [ $key3 ][ $key4 ][ " file_content " ] = str_replace ( $uidOld , $uid , $file [ " file_content " ]);
}
}
}
}
}
2014-04-07 16:10:42 -04:00
}
2014-04-30 12:00:22 -04:00
$this -> importWfTables ( $arrayWorkflowTables );
//Import workflow files
$this -> importWfFiles ( $arrayWorkflowFiles );
//Update
$workflow = Project\Workflow :: load ( $projectUid );
foreach ( $arrayWorkflowTables [ " tasks " ] as $key => $value ) {
$arrayTaskData = $value ;
$result = $workflow -> updateTask ( $arrayTaskData [ " TAS_UID " ], $arrayTaskData );
}
2014-05-06 15:38:34 -04:00
unset ( $arrayWorkflowTables [ " process " ][ " PRO_CREATE_USER " ]);
unset ( $arrayWorkflowTables [ " process " ][ " PRO_CREATE_DATE " ]);
unset ( $arrayWorkflowTables [ " process " ][ " PRO_UPDATE_DATE " ]);
2014-04-30 12:00:22 -04:00
$workflow -> update ( $arrayWorkflowTables [ " process " ]);
//Return
return $projectUid ;
2014-03-07 09:51:05 -04:00
}
2014-05-05 12:19:20 -04:00
/**
* Imports a Project sent through the POST method ( $_FILES )
*
2014-05-06 15:38:34 -04:00
* @ param array $arrayData Data
* @ param string $option Option ( " CREATE " , " OVERWRITE " , " DISABLE " , " KEEP " )
* @ param array $arrayFieldName The field ' s names
2014-05-05 12:19:20 -04:00
*
* return array Returns the data sent and the unique id of Project
*/
2014-05-06 15:38:34 -04:00
public function importPostFile ( array $arrayData , $option = " CREATE " , array $arrayFieldName = array ())
2014-05-05 12:19:20 -04:00
{
try {
//Set data
2014-05-06 15:38:34 -04:00
$arrayFieldName [ " projectFile " ] = ( isset ( $arrayFieldName [ " projectFile " ])) ? $arrayFieldName [ " projectFile " ] : " PROJECT_FILE " ;
2014-05-05 12:19:20 -04:00
$arrayFieldName [ " option " ] = ( isset ( $arrayFieldName [ " option " ])) ? $arrayFieldName [ " option " ] : " OPTION " ;
$arrayFieldDefinition = array (
2014-05-06 15:38:34 -04:00
$arrayFieldName [ " projectFile " ] => array ( " type " => " string " , " required " => true , " empty " => false , " defaultValues " => array (), " fieldNameAux " => " projectFile " )
2014-05-05 12:19:20 -04:00
);
$arrayFieldNameForException = $arrayFieldName ;
if ( isset ( $_FILES [ $arrayFieldName [ " projectFile " ]])) {
2014-05-12 15:24:19 -04:00
$_FILES [ " filePmx " ] = $_FILES [ $arrayFieldName [ " projectFile " ]];
2014-05-05 12:19:20 -04:00
}
if ( isset ( $arrayData [ $arrayFieldName [ " projectFile " ]]) &&
isset ( $arrayData [ $arrayFieldName [ " projectFile " ]][ " name " ]) &&
is_array ( $arrayData [ $arrayFieldName [ " projectFile " ]])
) {
$arrayData [ $arrayFieldName [ " projectFile " ]] = $arrayData [ $arrayFieldName [ " projectFile " ]][ " name " ];
}
2014-05-06 15:38:34 -04:00
$optionCaseUpper = ( strtoupper ( $option ) == $option ) ? true : false ;
$option = strtoupper ( $option );
2014-05-05 12:19:20 -04:00
//Verify data
$process = new \ProcessMaker\BusinessModel\Process ();
$validator = new \ProcessMaker\BusinessModel\Validator ();
$validator -> throwExceptionIfDataIsEmpty ( $arrayData , " \$ arrayData " );
$process -> throwExceptionIfDataNotMetFieldDefinition ( $arrayData , $arrayFieldDefinition , $arrayFieldNameForException , true );
2014-05-06 15:38:34 -04:00
$arrayOptionDefaultValues = array ( " CREATE " , " OVERWRITE " , " DISABLE " , " KEEP " );
if ( $option . " " != " " ) {
if ( ! in_array ( $option , $arrayOptionDefaultValues , true )) {
$strdv = implode ( " | " , $arrayOptionDefaultValues );
throw ( new \Exception ( str_replace ( array ( " { 0} " , " { 1} " ), array ( $arrayFieldNameForException [ " option " ], ( $optionCaseUpper ) ? $strdv : strtolower ( $strdv )), " Invalid value for \" { 0} \" , it only accepts values: \" { 1} \" . " )));
}
}
2014-05-12 15:24:19 -04:00
if (( isset ( $_FILES [ " filePmx " ]) && pathinfo ( $_FILES [ " filePmx " ][ " name " ], PATHINFO_EXTENSION ) != " pmx " ) ||
2014-05-05 12:19:20 -04:00
( isset ( $arrayData [ $arrayFieldName [ " projectFile " ]]) && pathinfo ( $arrayData [ $arrayFieldName [ " projectFile " ]], PATHINFO_EXTENSION ) != " pmx " )
) {
throw ( new \Exception ( " The file extension not is \" pmx \" " ));
}
//Set variables
2014-05-06 15:38:34 -04:00
$opt = self :: IMPORT_OPTION_CREATE_NEW ; //CREATE
2014-05-05 12:19:20 -04:00
2014-05-06 15:38:34 -04:00
switch ( $option ) {
2014-05-05 12:19:20 -04:00
case " OVERWRITE " :
2014-05-06 15:38:34 -04:00
$opt = self :: IMPORT_OPTION_OVERWRITE ;
2014-05-05 12:19:20 -04:00
break ;
case " DISABLE " :
2014-05-06 15:38:34 -04:00
$opt = self :: IMPORT_OPTION_DISABLE_AND_CREATE_NEW ;
2014-05-05 12:19:20 -04:00
break ;
case " KEEP " :
2014-05-06 15:38:34 -04:00
$opt = self :: IMPORT_OPTION_KEEP_WITHOUT_CHANGING_AND_CREATE_NEW ;
2014-05-05 12:19:20 -04:00
break ;
}
2014-05-06 15:38:34 -04:00
$option = $opt ;
2014-05-12 15:24:19 -04:00
if ( isset ( $_FILES [ " filePmx " ])) {
$this -> setSourceFromGlobals ( " filePmx " );
2014-05-05 12:19:20 -04:00
} else {
2014-05-12 15:24:19 -04:00
$filePmx = rtrim ( $this -> getSaveDir (), PATH_SEP ) . PATH_SEP . $arrayData [ $arrayFieldName [ " projectFile " ]];
if ( isset ( $arrayData [ $arrayFieldName [ " projectFile " ]]) && file_exists ( $filePmx )) {
$this -> setSourceFile ( $filePmx );
2014-05-05 12:19:20 -04:00
} else {
throw ( new \Exception ( str_replace ( array ( " { 0} " , " { 1} " ), array ( $arrayFieldNameForException [ " projectFile " ], $arrayData [ $arrayFieldName [ " projectFile " ]]), " The file with { 0}: \" { 1} \" does not exist. " )));
}
}
//Import
try {
$projectUid = $this -> import ( $option );
$arrayData = array_merge ( array ( " PRJ_UID " => $projectUid ), $arrayData );
} catch ( \Exception $e ) {
2014-05-06 15:38:34 -04:00
$msg = str_replace ( array ( self :: IMPORT_OPTION_CREATE_NEW , self :: IMPORT_OPTION_OVERWRITE , self :: IMPORT_OPTION_DISABLE_AND_CREATE_NEW , self :: IMPORT_OPTION_KEEP_WITHOUT_CHANGING_AND_CREATE_NEW ), $arrayOptionDefaultValues , $e -> getMessage ());
throw ( new \Exception ( $msg ));
2014-05-05 12:19:20 -04:00
}
//Return
if ( $arrayFieldName [ " projectFile " ] != strtoupper ( $arrayFieldName [ " projectFile " ])) {
$arrayData = array_change_key_case ( $arrayData , CASE_LOWER );
}
return $arrayData ;
} catch ( \Exception $e ) {
throw $e ;
}
}
2014-04-30 12:00:22 -04:00
}