diff --git a/build-vendor.php b/build-vendor.php index f083bc1f7..3947c3606 100644 --- a/build-vendor.php +++ b/build-vendor.php @@ -174,14 +174,16 @@ printf ( "mafe-{$hashVendors}.js file has %d bytes\n", filesize("{$rootPath}/wor out("=> compresing and combining css files", 'info'); $cssFiles = array ( - "workflow/public_html/lib/pmUI/pmui.min.css", - "workflow/public_html/lib/mafe/mafe.min.css", "gulliver/js/codemirror/lib/codemirror.css", "gulliver/js/tinymce/jscripts/tiny_mce/themes/advanced/skins/o2k7/ui.css", "gulliver/js/tinymce/jscripts/tiny_mce/themes/advanced/skins/o2k7/ui_silver.css", "gulliver/js/tinymce/jscripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/window.css", - "gulliver/js/tinymce/jscripts/tiny_mce/themes/advanced/skins/o2k7/content.css" + "gulliver/js/tinymce/jscripts/tiny_mce/themes/advanced/skins/o2k7/content.css", + + "workflow/public_html/lib/pmUI/pmui.min.css", + "workflow/public_html/lib/mafe/mafe.min.css" + ); $bigHandler = fopen ("{$rootPath}/workflow/public_html/lib/css/mafe-{$hashVendors}.css", "w"); foreach ($cssFiles as $cssFile) { diff --git a/features/backend/admin_setup/users/departments/basic_sequence_department.feature b/features/backend/admin_setup/users/departments/basic_sequence_department.feature index 88fd626ea..a2f68d0a9 100644 --- a/features/backend/admin_setup/users/departments/basic_sequence_department.feature +++ b/features/backend/admin_setup/users/departments/basic_sequence_department.feature @@ -20,16 +20,17 @@ Background: Then the response status code should be 200 And the response charset is "UTF-8" And the type is "object" + And the "dep_uid" property equals "12921473252d567506e6e63079240767" And the "dep_parent" property equals "" And the "dep_title" property equals "Sales Division" And the "dep_status" property equals "ACTIVE" - And the "dep_manager" property equals "" + And the "dep_manager" property equals "38102442252d5671a629009013495090" And the "dep_ldap_dn" property equals "" And the "dep_last" property equals "0" - And the "dep_manager_username" property equals "" - And the "dep_manager_lastname" property equals "" + And the "dep_manager_username" property equals "dylan" + And the "dep_manager_firstname" property equals "Dylan" + And the "dep_manager_lastname" property equals "Burns" And the "has_children" property equals "0" - Scenario: Create a new department in the workspace Given POST this data: diff --git a/features/backend/admin_setup/users/departments/main_tests_department.feature b/features/backend/admin_setup/users/departments/main_tests_department.feature index ea03bb4f6..edf9f0313 100644 --- a/features/backend/admin_setup/users/departments/main_tests_department.feature +++ b/features/backend/admin_setup/users/departments/main_tests_department.feature @@ -20,14 +20,16 @@ Background: Then the response status code should be 200 And the response charset is "UTF-8" And the type is "object" + And the "dep_uid" property equals "12921473252d567506e6e63079240767" And the "dep_parent" property equals "" And the "dep_title" property equals "Sales Division" And the "dep_status" property equals "ACTIVE" - And the "dep_manager" property equals "" + And the "dep_manager" property equals "38102442252d5671a629009013495090" And the "dep_ldap_dn" property equals "" And the "dep_last" property equals "0" - And the "dep_manager_username" property equals "" - And the "dep_manager_lastname" property equals "" + And the "dep_manager_username" property equals "dylan" + And the "dep_manager_firstname" property equals "Dylan" + And the "dep_manager_lastname" property equals "Burns" And the "has_children" property equals "0" diff --git a/features/backend/admin_setup/users/departments/negative_tests_department.feature b/features/backend/admin_setup/users/departments/negative_tests_department.feature index 11a98b6d9..26ce78402 100644 --- a/features/backend/admin_setup/users/departments/negative_tests_department.feature +++ b/features/backend/admin_setup/users/departments/negative_tests_department.feature @@ -25,4 +25,13 @@ Scenario Outline: Create a new departments in the workspace with bad parameters | test_description | dep_title | dep_parent | dep_status | error_code | error_message | | without dep_title | | | ACTIVE | 400 | dep_title | | Invalid dep_parent | Department 2 | 28036030000000000000005009591640 | ACTIVE | 400 | dep_parent | - | Invalid dep_status | Department 3 | | TRIGGER | 400 | dep_status | \ No newline at end of file + | Invalid dep_status | Department 3 | | TRIGGER | 400 | dep_status | + + + +Scenario: Delete a department when have asigned user (negative tests) + Given that I want to delete a resource with the key "15978182252d5674d210310076985235" + And I request "department/15978182252d5674d210310076985235" + Then the response status code should be 400 + And the response status message should have the following text "" + \ No newline at end of file diff --git a/features/backend/application_cases/cases_lists_1-6/basic_sequence_cases_lists_1_6.feature b/features/backend/application_cases/cases_lists_1-6/basic_sequence_cases_lists_1_6.feature index 44e61b055..18d6fab12 100644 --- a/features/backend/application_cases/cases_lists_1-6/basic_sequence_cases_lists_1_6.feature +++ b/features/backend/application_cases/cases_lists_1-6/basic_sequence_cases_lists_1_6.feature @@ -92,7 +92,7 @@ Scenario Outline: Create a new case in workspace with process "Derivation rules -Scenario: Create a new case Impersonate in workspace with process "Derivation rules - sequential" +Scenario Outline: Create a new case Impersonate in workspace with process "Derivation rules - sequential" Given POST this data: """ { @@ -107,7 +107,13 @@ Scenario: Create a new case Impersonate in workspace with process "Derivation ru And the response charset is "UTF-8" And the content type is "application/json" And the type is "object" - And store "caseId" in session array as variable "case1" + And store "caseId" in session array as variable "caseId_" + And store "caseNumber" in session array as variable "caseNumber_" + + Examples: + | case_number | + | 1 | + Scenario: Reassigns a case to a different user @@ -127,6 +133,8 @@ Scenario: Reassigns a case to a different user And the type is "object" + + Scenario: Autoderivate a case to the next task in the process Given PUT this data: """ diff --git a/features/backend/projects/trigger_wizard/main_tests_trigger_wizards.feature b/features/backend/projects/trigger_wizard/main_tests_trigger_wizards.feature index 153ab1e5a..0905e49f5 100644 --- a/features/backend/projects/trigger_wizard/main_tests_trigger_wizards.feature +++ b/features/backend/projects/trigger_wizard/main_tests_trigger_wizards.feature @@ -142,46 +142,12 @@ Scenario Outline: Create new Trigger: createDWS And store "tri_uid" in session array as variable "tri_uid" Examples: - | i | lib_name | fn_name | tri_title | tri_description | tri_type | tri_params.input.sharepointServer | tri_params.input.auth | tri_params.input.name | tri_params.input.users | tri_params.input.title | tri_params.input.documents | tri_params.output.tri_answer | - | 1 | pmTrSharepoint | createDWS | Sharepoint 1 | | SCRIPT | @@SERVER | username:password | Test DWS | @@users | Test DWS | /files/test.doc | $respuesta | + | i | Description | lib_name | fn_name | tri_title | tri_description | tri_type | tri_params.input.sharepointServer | tri_params.input.auth | tri_params.input.name | tri_params.input.users | tri_params.input.title | tri_params.input.documents | tri_params.output.tri_answer | + | 1 | Create pmTrSharpoint | pmTrSharepoint | createDWS | Sharepoint 1 | | SCRIPT | @@SERVER | username:password | Test DWS | @@users | Test DWS | /files/test.doc | $respuesta | + | 2 | Create a trigger without sending fields not required | pmTrSharepoint | createDWS | Sharepoint 2 | | SCRIPT | @@SERVER | username:password | Test DWS 1 | @@users | Test DWS | /files/test.doc | | -Scenario Outline: Create new Trigger: createDWS (no enviar campos no requeridos) - Given POST this data: - """ - { - "tri_title": "", - "tri_description": "", - "tri_type": "", - "tri_params": { - "input": { - - "sharepointServer": "", - "auth": "", - "name": "", - "users": "", - "title": "", - "documents": "" - - }, - "output": { - "tri_answer": "" - } - } - } - """ - And I request "project/14414793652a5d718b65590036026581/trigger-wizard//" - And the content type is "application/json" - Then the response status code should be 201 - And the response charset is "UTF-8" - And the type is "object" - And store "tri_uid" in session array as variable "tri_uid" - Examples: - | i | lib_name | fn_name | tri_title | tri_description | tri_type | tri_params.input.sharepointServer | tri_params.input.auth | tri_params.input.name | tri_params.input.users | tri_params.input.title | tri_params.input.documents | tri_params.output.tri_answer | - | 2 | pmTrSharepoint | createDWS | Sharepoint 1 | | SCRIPT | @@SERVER | username:password | Test DWS | @@users | Test DWS | /files/test.doc | $respuesta | - - Scenario Outline: Update Trigger Given PUT this data: """ @@ -280,6 +246,7 @@ Scenario Outline: Create new Trigger: createDWS | i | | 0 | | 1 | + | 2 | Scenario: Get a List of triggers of a project diff --git a/framework/src/Maveriks/WebApplication.php b/framework/src/Maveriks/WebApplication.php index 7eb813e38..c0186d398 100644 --- a/framework/src/Maveriks/WebApplication.php +++ b/framework/src/Maveriks/WebApplication.php @@ -344,8 +344,8 @@ class WebApplication set_include_path(get_include_path() . PATH_SEPARATOR . PATH_WORKSPACE); // smarty constants -// define( "PATH_SMARTY_C", PATH_C . "smarty" . PATH_SEP . "c" ); -// define( "PATH_SMARTY_CACHE", PATH_C . "smarty" . PATH_SEP . "cache" ); + define( "PATH_SMARTY_C", PATH_C . "smarty" . PATH_SEP . "c" ); + define( "PATH_SMARTY_CACHE", PATH_C . "smarty" . PATH_SEP . "cache" ); define("PATH_DATA_SITE", PATH_DATA . "sites/" . SYS_SYS . "/"); define("PATH_DOCUMENT", PATH_DATA_SITE . "files/"); @@ -366,6 +366,33 @@ class WebApplication echo "WARNING! No server info found!"; } + /** + * Global definitions, before it was the defines.php file + */ + + // URL Key + define( "URL_KEY", 'c0l0s40pt1mu59r1m3' ); + + // Other definitions + define( 'TIMEOUT_RESPONSE', 100 ); //web service timeout + define( 'APPLICATION_CODE', 'ProcessMaker' ); //to login like workflow system + define( 'MAIN_POFILE', 'processmaker' ); + define( 'PO_SYSTEM_VERSION', 'PM 4.0.1' ); + + // Environment definitions + define( 'G_PRO_ENV', 'PRODUCTION' ); + define( 'G_DEV_ENV', 'DEVELOPMENT' ); + define( 'G_TEST_ENV', 'TEST' ); + + // Number of files per folder at PATH_UPLOAD (cases documents) + define( 'APPLICATION_DOCUMENTS_PER_FOLDER', 1000 ); + + // Server of ProcessMaker Library + define( 'PML_SERVER', 'http://library.processmaker.com' ); + define( 'PML_WSDL_URL', PML_SERVER . '/syspmLibrary/en/green/services/wsdl' ); + define( 'PML_UPLOAD_URL', PML_SERVER . '/syspmLibrary/en/green/services/uploadProcess' ); + define( 'PML_DOWNLOAD_URL', PML_SERVER . '/syspmLibrary/en/green/services/download' ); + // create memcached singleton //\Bootstrap::LoadClass("memcached"); //$memcache = PMmemcached::getSingleton( SYS_SYS ); diff --git a/gulliver/system/class.bootstrap.php b/gulliver/system/class.bootstrap.php index 14776abdd..31b5af658 100644 --- a/gulliver/system/class.bootstrap.php +++ b/gulliver/system/class.bootstrap.php @@ -159,6 +159,7 @@ class Bootstrap self::registerClass("XmlForm_Field_cellMark", PATH_GULLIVER . "class.xmlformExtension.php"); self::registerClass("XmlForm_Field_DVEditor", PATH_GULLIVER . "class.xmlformExtension.php"); self::registerClass("XmlForm_Field_FastSearch", PATH_GULLIVER . "class.xmlformExtension.php"); + self::registerClass("xmlformTemplate", PATH_GULLIVER . "class.xmlformTemplate.php"); self::registerClass("ymlDomain", PATH_GULLIVER . "class.ymlDomain.php"); self::registerClass("ymlTestCases", PATH_GULLIVER . "class.ymlTestCases.php"); @@ -743,7 +744,7 @@ class Bootstrap * @param array list plugins active * @return void */ - public function LoadTranslationPlugins ($lang = SYS_LANG, $listPluginsActive) + public static function LoadTranslationPlugins ($lang = SYS_LANG, $listPluginsActive) { if ( ! ( is_array ( $listPluginsActive ) ) ) { return null; diff --git a/gulliver/system/class.xmlform.php b/gulliver/system/class.xmlform.php index 54e830d8c..1c97d03b4 100755 --- a/gulliver/system/class.xmlform.php +++ b/gulliver/system/class.xmlform.php @@ -5463,417 +5463,7 @@ class XmlForm } } -/** - * Class xmlformTemplate - * - * @author David S. Callizaya S. - * @package gulliver.system - * @access public - */ -class xmlformTemplate extends Smarty -{ - public $template; - public $templateFile; - /** - * Function xmlformTemplate - * - * @author David S. Callizaya S. - * @access public - * @param string form - * @param string templateFile - * @return string - */ - public function xmlformTemplate (&$form, $templateFile) - { - $this->template_dir = PATH_XMLFORM; - $this->compile_dir = PATH_SMARTY_C; - $this->cache_dir = PATH_SMARTY_CACHE; - $this->config_dir = PATH_THIRDPARTY . 'smarty/configs'; - $this->caching = false; - - // register the resource name "db" - $this->templateFile = $templateFile; - } - - /** - * Function printTemplate - * - * @author David S. Callizaya S. - * @access public - * @param string form - * @param string target - * @return string - */ - public function printTemplate (&$form, $target = 'smarty') - { - if (strcasecmp( $target, 'smarty' ) === 0) { - $varPrefix = '$'; - } - if (strcasecmp( $target, 'templatePower' ) === 0) { - $varPrefix = ''; - } - - $ft = new StdClass(); - foreach ($form as $name => $value) { - if (($name !== 'fields') && ($value !== '')) { - $ft->{$name} = '{$form_' . $name . '}'; - } - if ($name === 'cols') { - $ft->{$name} = $value; - } - if ($name === 'owner') { - $ft->owner = & $form->owner; - } - if ($name === 'deleteRow') { - $ft->deleteRow = $form->deleteRow; - } - if ($name === 'addRow') { - $ft->addRow = $form->addRow; - } - if ($name === 'editRow') { - $ft->editRow = $form->editRow; - } - } - if (! isset( $ft->action )) { - $ft->action = '{$form_action}'; - } - $hasRequiredFields = false; - - foreach ($form->fields as $k => $v) { - $ft->fields[$k] = $v->cloneObject(); - $ft->fields[$k]->label = '{' . $varPrefix . $k . '}'; - - if ($form->type === 'grid') { - if (strcasecmp( $target, 'smarty' ) === 0) { - $ft->fields[$k]->field = '{' . $varPrefix . 'form.' . $k . '[row]}'; - } - if (strcasecmp( $target, 'templatePower' ) === 0) { - $ft->fields[$k]->field = '{' . $varPrefix . 'form[' . $k . '][row]}'; - } - } else { - if (strcasecmp( $target, 'smarty' ) === 0) { - $ft->fields[$k]->field = '{' . $varPrefix . 'form.' . $k . '}'; - } - if (strcasecmp( $target, 'templatePower' ) === 0) { - $ft->fields[$k]->field = '{' . $varPrefix . 'form[' . $k . ']}'; - } - } - - $hasRequiredFields = $hasRequiredFields | (isset( $v->required ) && ($v->required == '1') && ($v->mode == 'edit')); - - if ($v->type == 'xmlmenu') { - $menu = $v; - } - } - - if (isset( $menu )) { - if (isset( $menu->owner->values['__DYNAFORM_OPTIONS']['PREVIOUS_STEP'] )) { - $prevStep_url = $menu->owner->values['__DYNAFORM_OPTIONS']['PREVIOUS_STEP']; - - $this->assign( 'prevStep_url', $prevStep_url ); - $this->assign( 'prevStep_label', G::loadTranslation( 'ID_BACK' ) ); - } - } - - $this->assign( 'hasRequiredFields', $hasRequiredFields ); - $this->assign( 'form', $ft ); - $this->assign( 'printTemplate', true ); - $this->assign( 'printJSFile', false ); - $this->assign( 'printJavaScript', false ); - //$this->assign ( 'dynaformSetFocus', "try {literal}{{/literal} dynaformSetFocus();}catch(e){literal}{{/literal}}" ); - return $this->fetch( $this->templateFile ); - } - - /** - * Function printJavaScript - * - * @author David S. Callizaya S. - * @access public - * @param string form - * @return string - */ - public function printJavaScript (&$form) - { - $this->assign( 'form', $form ); - $this->assign( 'printTemplate', false ); - $this->assign( 'printJSFile', false ); - $this->assign( 'printJavaScript', true ); - return $this->fetch( $this->templateFile ); - } - - /** - * Function printJSFile - * - * @author David S. Callizaya S. - * @access public - * @param string form - * @return string - */ - public function printJSFile (&$form) - { - //JS designer>preview - if (isset($_SERVER["HTTP_REFERER"]) && !empty($_SERVER["HTTP_REFERER"]) && preg_match("/^.*dynaforms_Editor\?.*PRO_UID=.*DYN_UID=.*$/", $_SERVER["HTTP_REFERER"]) && preg_match("/^.*dynaforms\/dynaforms_Ajax.*$/", $_SERVER["REQUEST_URI"])) { - $js = null; - - foreach ($form->fields as $index => $value) { - $field = $value; - - if ($field->type == "javascript" && !empty($field->code)) { - $js = $js . " " . $field->code; - } - } - - if ($js != null) { - $form->jsDesignerPreview = " - //JS designer>preview - $js - - loadForm_" . $form->id . "(\"../gulliver/defaultAjaxDynaform\"); - - if (typeof(dynaformOnload) != \"undefined\") { - dynaformOnload(); - } - "; - } - } - - $this->assign( 'form', $form ); - $this->assign( 'printTemplate', false ); - $this->assign( 'printJSFile', true ); - $this->assign( 'printJavaScript', false ); - return $this->fetch( $this->templateFile ); - } - - /** - * Function getFields - * - * @author David S. Callizaya S. - * @access public - * @param string form - * @return string - */ - public function getFields (&$form, $therow = -1) - { - $result = array (); - - foreach ($form->fields as $k => $v) { - $field = $v; - - if ($form->mode != '') { - #@ last modification: erik - $field->mode = $form->mode; #@ - } #@ - - //if (isset($form->fields[$k]->sql)) $form->fields[$k]->executeSQL( $form ); - $value = (isset( $form->values[$k] )) ? $form->values[$k] : null; - $result[$k] = G::replaceDataField( $form->fields[$k]->label, $form->values ); - - if ($form->type == 'xmlform') { - if (in_array($field->type, array("text", "currency", "percentage", "password", "suggest", "textarea", "dropdown", "yesno", "listbox", "checkbox", "date", "link", "file"))) { - $result[$k] = ''; - } - } - - if (! is_array( $value )) { - if ($form->type == 'grid') { - $aAux = array (); - if (!isset($form->values[$form->name])) { - $form->values[$form->name] = array(); - } - if ($therow == - 1) { - for ($i = 0; $i < count( $form->values[$form->name] ); $i ++) { - $aAux[] = ''; - } - } else { - for ($i = 0; $i < $therow; $i ++) { - $aAux[] = ''; - } - } - - switch ($field->type) { - case "link": - $result["form"][$k] = $form->fields[$k]->renderGrid($aAux, array(), $form); - break; - default: - $result["form"][$k] = $form->fields[$k]->renderGrid($aAux, $form); - break; - } - } else { - switch ($field->type) { - case "link": - $result["form"][$k] = $form->fields[$k]->render( - $value, - (isset($form->values[$k . "_label"]))? $form->values[$k . "_label"] : null, - $form - ); - break; - default: - $result["form"][$k] = $form->fields[$k]->render($value, $form); - break; - } - } - } else { - /*if (isset ( $form->owner )) { - if (count ( $value ) < count ( $form->owner->values [$form->name] )) { - $i = count ( $value ); - $j = count ( $form->owner->values [$form->name] ); - - for($i; $i < $j; $i ++) { - $value [] = ''; - } - } - }*/ - - if ($field->type == "grid") { - // Fix data for grids - if (is_array($form->fields[$k]->fields)) { - foreach ($form->fields[$k]->fields as $gridFieldName => $gridField) { - $valueLength = count($value); - for ($i = 1; $i <= $valueLength; $i++) { - if (!isset($value[$i][$gridFieldName])) { - switch ($gridField->type) { - case 'checkbox': - $defaultAttribute = 'falseValue'; - break; - default: - $defaultAttribute = 'defaultValue'; - break; - } - $value[$i][$gridFieldName] = isset($gridField->$defaultAttribute) ? $gridField->$defaultAttribute : ''; - } - } - } - } - $form->fields[$k]->setScrollStyle( $form ); - $result["form"][$k] = $form->fields[$k]->renderGrid( $value, $form, $therow ); - } else { - switch ($field->type) { - case "dropdown": - $result["form"][$k] = $form->fields[$k]->renderGrid( $value, $form, false, $therow ); - break; - case "file": - $result["form"][$k] = $form->fields[$k]->renderGrid( $value, $form, $therow ); - break; - case "link": - $result["form"][$k] = $form->fields[$k]->renderGrid( - $value, - (isset($form->values[$k . "_label"]))? $form->values[$k . "_label"] : array(), - $form - ); - break; - default: - $result["form"][$k] = $form->fields[$k]->renderGrid( $value, $form ); - break; - } - } - } - } - - foreach ($form as $name => $value) { - if ($name !== 'fields') { - $result['form_' . $name] = $value; - } - } - - return $result; - } - - /** - * Function printObject - * @author David S. Callizaya S. - * @access public - * @param string form - * @return string - */ - public function printObject(&$form, $therow = -1) - { - //to do: generate the template for templatePower. - //DONE: The template was generated in printTemplate, to use it - // is necesary to load the file with templatePower and send the array - //result - $this->register_resource ( 'mem', array (array (&$this, '_get_template' ), array ($this, '_get_timestamp' ), array ($this, '_get_secure' ), array ($this, '_get_trusted' ) ) ); - $result = $this->getFields ( $form, $therow ); - - $this->assign ( array ('PATH_TPL' => PATH_TPL ) ); - $this->assign ( $result ); - if ( defined('SYS_LANG_DIRECTION') && SYS_LANG_DIRECTION == 'R' ) { - switch( $form->type ){ - case 'toolbar': - $form->align = 'right'; - break; - } - } - - $this->assign ( array ('_form' => $form ) ); - //'mem:defaultTemplate'.$form->name obtains the template generated for the - //current "form" object, then this resource y saved by Smarty in the - //cache_dir. To avoiding troubles when two forms with the same id are being - //drawed in a same page with different templates, add an . rand(1,1000) - //to the resource name. This is because the process of creating templates - //(with the method "printTemplate") and painting takes less than 1 second - //so the new template resource generally will had the same timestamp. - $output = $this->fetch ( 'mem:defaultTemplate' . $form->name ); - return $output; - } - - /** - * Smarty plugin - * ------------------------------------------------------------- - * Type: resource - * Name: mem - * Purpose: Fetches templates from this object - * ------------------------------------------------------------- - */ - public function _get_template($tpl_name, &$tpl_source, &$smarty_obj) - { - $tpl_source = $this->template; - return true; - } - - /** - * Function _get_timestamp - * @author David S. Callizaya S. - * @access public - * @param string tpl_name - * @param string tpl_timestamp - * @param string smarty_obj - * @return string - */ - public function _get_timestamp($tpl_name, &$tpl_timestamp, &$smarty_obj) - { - //NOTE: +1 prevents to load the smarty cache instead of this resource - $tpl_timestamp = time () + 1; - return true; - } - - /** - * Function _get_secure - * @author David S. Callizaya S. - * @access public - * @param string tpl_name - * @param string smarty_obj - * @return string - */ - public function _get_secure($tpl_name, &$smarty_obj) - { - // assume all templates are secure - return true; - } - - /** - * Function _get_trusted - * @author David S. Callizaya S. - * @access public - * @param string tpl_name - * @param string smarty_obj - * @return string - */ - public function _get_trusted($tpl_name, &$smarty_obj) - { - // not used for templates - } -} /** * @package gulliver.system diff --git a/gulliver/system/class.xmlformTemplate.php b/gulliver/system/class.xmlformTemplate.php new file mode 100644 index 000000000..4337ec002 --- /dev/null +++ b/gulliver/system/class.xmlformTemplate.php @@ -0,0 +1,412 @@ + + * @package gulliver.system + * @access public + */ +class xmlformTemplate extends Smarty +{ + public $template; + public $templateFile; + + /** + * Function xmlformTemplate + * + * @author David S. Callizaya S. + * @access public + * @param string form + * @param string templateFile + * @return string + */ + public function xmlformTemplate (&$form, $templateFile) + { + $this->template_dir = PATH_XMLFORM; + $this->compile_dir = PATH_SMARTY_C; + $this->cache_dir = PATH_SMARTY_CACHE; + $this->config_dir = PATH_THIRDPARTY . 'smarty/configs'; + $this->caching = false; + + // register the resource name "db" + $this->templateFile = $templateFile; + } + + /** + * Function printTemplate + * + * @author David S. Callizaya S. + * @access public + * @param string form + * @param string target + * @return string + */ + public function printTemplate (&$form, $target = 'smarty') + { + if (strcasecmp( $target, 'smarty' ) === 0) { + $varPrefix = '$'; + } + if (strcasecmp( $target, 'templatePower' ) === 0) { + $varPrefix = ''; + } + + $ft = new StdClass(); + foreach ($form as $name => $value) { + if (($name !== 'fields') && ($value !== '')) { + $ft->{$name} = '{$form_' . $name . '}'; + } + if ($name === 'cols') { + $ft->{$name} = $value; + } + if ($name === 'owner') { + $ft->owner = & $form->owner; + } + if ($name === 'deleteRow') { + $ft->deleteRow = $form->deleteRow; + } + if ($name === 'addRow') { + $ft->addRow = $form->addRow; + } + if ($name === 'editRow') { + $ft->editRow = $form->editRow; + } + } + if (! isset( $ft->action )) { + $ft->action = '{$form_action}'; + } + $hasRequiredFields = false; + + foreach ($form->fields as $k => $v) { + $ft->fields[$k] = $v->cloneObject(); + $ft->fields[$k]->label = '{' . $varPrefix . $k . '}'; + + if ($form->type === 'grid') { + if (strcasecmp( $target, 'smarty' ) === 0) { + $ft->fields[$k]->field = '{' . $varPrefix . 'form.' . $k . '[row]}'; + } + if (strcasecmp( $target, 'templatePower' ) === 0) { + $ft->fields[$k]->field = '{' . $varPrefix . 'form[' . $k . '][row]}'; + } + } else { + if (strcasecmp( $target, 'smarty' ) === 0) { + $ft->fields[$k]->field = '{' . $varPrefix . 'form.' . $k . '}'; + } + if (strcasecmp( $target, 'templatePower' ) === 0) { + $ft->fields[$k]->field = '{' . $varPrefix . 'form[' . $k . ']}'; + } + } + + $hasRequiredFields = $hasRequiredFields | (isset( $v->required ) && ($v->required == '1') && ($v->mode == 'edit')); + + if ($v->type == 'xmlmenu') { + $menu = $v; + } + } + + if (isset( $menu )) { + if (isset( $menu->owner->values['__DYNAFORM_OPTIONS']['PREVIOUS_STEP'] )) { + $prevStep_url = $menu->owner->values['__DYNAFORM_OPTIONS']['PREVIOUS_STEP']; + + $this->assign( 'prevStep_url', $prevStep_url ); + $this->assign( 'prevStep_label', G::loadTranslation( 'ID_BACK' ) ); + } + } + + $this->assign( 'hasRequiredFields', $hasRequiredFields ); + $this->assign( 'form', $ft ); + $this->assign( 'printTemplate', true ); + $this->assign( 'printJSFile', false ); + $this->assign( 'printJavaScript', false ); + //$this->assign ( 'dynaformSetFocus', "try {literal}{{/literal} dynaformSetFocus();}catch(e){literal}{{/literal}}" ); + return $this->fetch( $this->templateFile ); + } + + /** + * Function printJavaScript + * + * @author David S. Callizaya S. + * @access public + * @param string form + * @return string + */ + public function printJavaScript (&$form) + { + $this->assign( 'form', $form ); + $this->assign( 'printTemplate', false ); + $this->assign( 'printJSFile', false ); + $this->assign( 'printJavaScript', true ); + return $this->fetch( $this->templateFile ); + } + + /** + * Function printJSFile + * + * @author David S. Callizaya S. + * @access public + * @param string form + * @return string + */ + public function printJSFile (&$form) + { + //JS designer>preview + if (isset($_SERVER["HTTP_REFERER"]) && !empty($_SERVER["HTTP_REFERER"]) && preg_match("/^.*dynaforms_Editor\?.*PRO_UID=.*DYN_UID=.*$/", $_SERVER["HTTP_REFERER"]) && preg_match("/^.*dynaforms\/dynaforms_Ajax.*$/", $_SERVER["REQUEST_URI"])) { + $js = null; + + foreach ($form->fields as $index => $value) { + $field = $value; + + if ($field->type == "javascript" && !empty($field->code)) { + $js = $js . " " . $field->code; + } + } + + if ($js != null) { + $form->jsDesignerPreview = " + //JS designer>preview + $js + + loadForm_" . $form->id . "(\"../gulliver/defaultAjaxDynaform\"); + + if (typeof(dynaformOnload) != \"undefined\") { + dynaformOnload(); + } + "; + } + } + + $this->assign( 'form', $form ); + $this->assign( 'printTemplate', false ); + $this->assign( 'printJSFile', true ); + $this->assign( 'printJavaScript', false ); + return $this->fetch( $this->templateFile ); + } + + /** + * Function getFields + * + * @author David S. Callizaya S. + * @access public + * @param string form + * @return string + */ + public function getFields (&$form, $therow = -1) + { + $result = array (); + + foreach ($form->fields as $k => $v) { + $field = $v; + + if ($form->mode != '') { + #@ last modification: erik + $field->mode = $form->mode; #@ + } #@ + + //if (isset($form->fields[$k]->sql)) $form->fields[$k]->executeSQL( $form ); + $value = (isset( $form->values[$k] )) ? $form->values[$k] : null; + $result[$k] = G::replaceDataField( $form->fields[$k]->label, $form->values ); + + if ($form->type == 'xmlform') { + if (in_array($field->type, array("text", "currency", "percentage", "password", "suggest", "textarea", "dropdown", "yesno", "listbox", "checkbox", "date", "link", "file"))) { + $result[$k] = ''; + } + } + + if (! is_array( $value )) { + if ($form->type == 'grid') { + $aAux = array (); + if (!isset($form->values[$form->name])) { + $form->values[$form->name] = array(); + } + if ($therow == - 1) { + for ($i = 0; $i < count( $form->values[$form->name] ); $i ++) { + $aAux[] = ''; + } + } else { + for ($i = 0; $i < $therow; $i ++) { + $aAux[] = ''; + } + } + + switch ($field->type) { + case "link": + $result["form"][$k] = $form->fields[$k]->renderGrid($aAux, array(), $form); + break; + default: + $result["form"][$k] = $form->fields[$k]->renderGrid($aAux, $form); + break; + } + } else { + switch ($field->type) { + case "link": + $result["form"][$k] = $form->fields[$k]->render( + $value, + (isset($form->values[$k . "_label"]))? $form->values[$k . "_label"] : null, + $form + ); + break; + default: + $result["form"][$k] = $form->fields[$k]->render($value, $form); + break; + } + } + } else { + /*if (isset ( $form->owner )) { + if (count ( $value ) < count ( $form->owner->values [$form->name] )) { + $i = count ( $value ); + $j = count ( $form->owner->values [$form->name] ); + + for($i; $i < $j; $i ++) { + $value [] = ''; + } + } + }*/ + + if ($field->type == "grid") { + // Fix data for grids + if (is_array($form->fields[$k]->fields)) { + foreach ($form->fields[$k]->fields as $gridFieldName => $gridField) { + $valueLength = count($value); + for ($i = 1; $i <= $valueLength; $i++) { + if (!isset($value[$i][$gridFieldName])) { + switch ($gridField->type) { + case 'checkbox': + $defaultAttribute = 'falseValue'; + break; + default: + $defaultAttribute = 'defaultValue'; + break; + } + $value[$i][$gridFieldName] = isset($gridField->$defaultAttribute) ? $gridField->$defaultAttribute : ''; + } + } + } + } + $form->fields[$k]->setScrollStyle( $form ); + $result["form"][$k] = $form->fields[$k]->renderGrid( $value, $form, $therow ); + } else { + switch ($field->type) { + case "dropdown": + $result["form"][$k] = $form->fields[$k]->renderGrid( $value, $form, false, $therow ); + break; + case "file": + $result["form"][$k] = $form->fields[$k]->renderGrid( $value, $form, $therow ); + break; + case "link": + $result["form"][$k] = $form->fields[$k]->renderGrid( + $value, + (isset($form->values[$k . "_label"]))? $form->values[$k . "_label"] : array(), + $form + ); + break; + default: + $result["form"][$k] = $form->fields[$k]->renderGrid( $value, $form ); + break; + } + } + } + } + + foreach ($form as $name => $value) { + if ($name !== 'fields') { + $result['form_' . $name] = $value; + } + } + + return $result; + } + + /** + * Function printObject + * @author David S. Callizaya S. + * @access public + * @param string form + * @return string + */ + public function printObject(&$form, $therow = -1) + { + //to do: generate the template for templatePower. + //DONE: The template was generated in printTemplate, to use it + // is necesary to load the file with templatePower and send the array + //result + $this->register_resource ( 'mem', array (array (&$this, '_get_template' ), array ($this, '_get_timestamp' ), array ($this, '_get_secure' ), array ($this, '_get_trusted' ) ) ); + $result = $this->getFields ( $form, $therow ); + + $this->assign ( array ('PATH_TPL' => PATH_TPL ) ); + $this->assign ( $result ); + if ( defined('SYS_LANG_DIRECTION') && SYS_LANG_DIRECTION == 'R' ) { + switch( $form->type ){ + case 'toolbar': + $form->align = 'right'; + break; + } + } + + $this->assign ( array ('_form' => $form ) ); + //'mem:defaultTemplate'.$form->name obtains the template generated for the + //current "form" object, then this resource y saved by Smarty in the + //cache_dir. To avoiding troubles when two forms with the same id are being + //drawed in a same page with different templates, add an . rand(1,1000) + //to the resource name. This is because the process of creating templates + //(with the method "printTemplate") and painting takes less than 1 second + //so the new template resource generally will had the same timestamp. + $output = $this->fetch ( 'mem:defaultTemplate' . $form->name ); + return $output; + } + + /** + * Smarty plugin + * ------------------------------------------------------------- + * Type: resource + * Name: mem + * Purpose: Fetches templates from this object + * ------------------------------------------------------------- + */ + public function _get_template($tpl_name, &$tpl_source, &$smarty_obj) + { + $tpl_source = $this->template; + return true; + } + + /** + * Function _get_timestamp + * @author David S. Callizaya S. + * @access public + * @param string tpl_name + * @param string tpl_timestamp + * @param string smarty_obj + * @return string + */ + public function _get_timestamp($tpl_name, &$tpl_timestamp, &$smarty_obj) + { + //NOTE: +1 prevents to load the smarty cache instead of this resource + $tpl_timestamp = time () + 1; + return true; + } + + /** + * Function _get_secure + * @author David S. Callizaya S. + * @access public + * @param string tpl_name + * @param string smarty_obj + * @return string + */ + public function _get_secure($tpl_name, &$smarty_obj) + { + // assume all templates are secure + return true; + } + + /** + * Function _get_trusted + * @author David S. Callizaya S. + * @access public + * @param string tpl_name + * @param string smarty_obj + * @return string + */ + public function _get_trusted($tpl_name, &$smarty_obj) + { + // not used for templates + } +} \ No newline at end of file diff --git a/gulliver/thirdparty/pear/Archive/Tar.php b/gulliver/thirdparty/pear/Archive/Tar.php index ecd769eea..8197d94aa 100755 --- a/gulliver/thirdparty/pear/Archive/Tar.php +++ b/gulliver/thirdparty/pear/Archive/Tar.php @@ -30,82 +30,86 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * - * @category File_Formats - * @package Archive_Tar - * @author Vincent Blavet - * @copyright 1997-2008 The Authors - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Tar.php 295988 2010-03-09 08:39:37Z mrook $ - * @link http://pear.php.net/package/Archive_Tar + * @category File_Formats + * @package Archive_Tar + * @author Vincent Blavet + * @copyright 1997-2010 The Authors + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id$ + * @link http://pear.php.net/package/Archive_Tar */ require_once 'PEAR.php'; - -define ('ARCHIVE_TAR_ATT_SEPARATOR', 90001); -define ('ARCHIVE_TAR_END_BLOCK', pack("a512", '')); +define('ARCHIVE_TAR_ATT_SEPARATOR', 90001); +define('ARCHIVE_TAR_END_BLOCK', pack("a512", '')); /** -* Creates a (compressed) Tar archive -* -* @author Vincent Blavet -* @version $Revision: 295988 $ -* @license http://www.opensource.org/licenses/bsd-license.php New BSD License -* @package Archive_Tar -*/ + * Creates a (compressed) Tar archive + * + * @package Archive_Tar + * @author Vincent Blavet + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Revision$ + */ class Archive_Tar extends PEAR { /** - * @var string Name of the Tar - */ + * @var string Name of the Tar + */ var $_tarname=''; /** - * @var boolean if true, the Tar file will be gzipped - */ + * @var boolean if true, the Tar file will be gzipped + */ var $_compress=false; /** - * @var string Type of compression : 'none', 'gz' or 'bz2' - */ + * @var string Type of compression : 'none', 'gz' or 'bz2' + */ var $_compress_type='none'; /** - * @var string Explode separator - */ + * @var string Explode separator + */ var $_separator=' '; /** - * @var file descriptor - */ + * @var file descriptor + */ var $_file=0; /** - * @var string Local Tar name of a remote Tar (http:// or ftp://) - */ + * @var string Local Tar name of a remote Tar (http:// or ftp://) + */ var $_temp_tarname=''; /** - * @var string regular expression for ignoring files or directories - */ + * @var string regular expression for ignoring files or directories + */ var $_ignore_regexp=''; + /** + * @var object PEAR_Error object + */ + var $error_object=null; + // {{{ constructor /** - * Archive_Tar Class constructor. This flavour of the constructor only - * declare a new Archive_Tar object, identifying it by the name of the - * tar file. - * If the compress argument is set the tar will be read or created as a - * gzip or bz2 compressed TAR file. - * - * @param string $p_tarname The name of the tar archive to create - * @param string $p_compress can be null, 'gz' or 'bz2'. This - * parameter indicates if gzip or bz2 compression - * is required. For compatibility reason the - * boolean value 'true' means 'gz'. - * @access public - */ + * Archive_Tar Class constructor. This flavour of the constructor only + * declare a new Archive_Tar object, identifying it by the name of the + * tar file. + * If the compress argument is set the tar will be read or created as a + * gzip or bz2 compressed TAR file. + * + * @param string $p_tarname The name of the tar archive to create + * @param string $p_compress can be null, 'gz' or 'bz2'. This + * parameter indicates if gzip or bz2 compression + * is required. For compatibility reason the + * boolean value 'true' means 'gz'. + * + * @access public + */ function Archive_Tar($p_tarname, $p_compress = null) { $this->PEAR(); @@ -120,7 +124,7 @@ class Archive_Tar extends PEAR if ($data == "\37\213") { $this->_compress = true; $this->_compress_type = 'gz'; - // No sure it's enought for a magic code .... + // No sure it's enought for a magic code .... } elseif ($data == "BZ") { $this->_compress = true; $this->_compress_type = 'bz2'; @@ -133,7 +137,7 @@ class Archive_Tar extends PEAR $this->_compress = true; $this->_compress_type = 'gz'; } elseif ((substr($p_tarname, -3) == 'bz2') || - (substr($p_tarname, -2) == 'bz')) { + (substr($p_tarname, -2) == 'bz')) { $this->_compress = true; $this->_compress_type = 'bz2'; } @@ -184,26 +188,27 @@ class Archive_Tar extends PEAR // {{{ create() /** - * This method creates the archive file and add the files / directories - * that are listed in $p_filelist. - * If a file with the same name exist and is writable, it is replaced - * by the new tar. - * The method return false and a PEAR error text. - * The $p_filelist parameter can be an array of string, each string - * representing a filename or a directory name with their path if - * needed. It can also be a single string with names separated by a - * single blank. - * For each directory added in the archive, the files and - * sub-directories are also added. - * See also createModify() method for more details. - * - * @param array $p_filelist An array of filenames and directory names, or a - * single string with names separated by a single - * blank space. - * @return true on success, false on error. - * @see createModify() - * @access public - */ + * This method creates the archive file and add the files / directories + * that are listed in $p_filelist. + * If a file with the same name exist and is writable, it is replaced + * by the new tar. + * The method return false and a PEAR error text. + * The $p_filelist parameter can be an array of string, each string + * representing a filename or a directory name with their path if + * needed. It can also be a single string with names separated by a + * single blank. + * For each directory added in the archive, the files and + * sub-directories are also added. + * See also createModify() method for more details. + * + * @param array $p_filelist An array of filenames and directory names, or a + * single string with names separated by a single + * blank space. + * + * @return true on success, false on error. + * @see createModify() + * @access public + */ function create($p_filelist) { return $this->createModify($p_filelist, '', ''); @@ -212,20 +217,21 @@ class Archive_Tar extends PEAR // {{{ add() /** - * This method add the files / directories that are listed in $p_filelist in - * the archive. If the archive does not exist it is created. - * The method return false and a PEAR error text. - * The files and directories listed are only added at the end of the archive, - * even if a file with the same name is already archived. - * See also createModify() method for more details. - * - * @param array $p_filelist An array of filenames and directory names, or a - * single string with names separated by a single - * blank space. - * @return true on success, false on error. - * @see createModify() - * @access public - */ + * This method add the files / directories that are listed in $p_filelist in + * the archive. If the archive does not exist it is created. + * The method return false and a PEAR error text. + * The files and directories listed are only added at the end of the archive, + * even if a file with the same name is already archived. + * See also createModify() method for more details. + * + * @param array $p_filelist An array of filenames and directory names, or a + * single string with names separated by a single + * blank space. + * + * @return true on success, false on error. + * @see createModify() + * @access public + */ function add($p_filelist) { return $this->addModify($p_filelist, '', ''); @@ -233,9 +239,9 @@ class Archive_Tar extends PEAR // }}} // {{{ extract() - function extract($p_path='') + function extract($p_path='', $p_preserve=false) { - return $this->extractModify($p_path, ''); + return $this->extractModify($p_path, '', $p_preserve); } // }}} @@ -258,40 +264,41 @@ class Archive_Tar extends PEAR // {{{ createModify() /** - * This method creates the archive file and add the files / directories - * that are listed in $p_filelist. - * If the file already exists and is writable, it is replaced by the - * new tar. It is a create and not an add. If the file exists and is - * read-only or is a directory it is not replaced. The method return - * false and a PEAR error text. - * The $p_filelist parameter can be an array of string, each string - * representing a filename or a directory name with their path if - * needed. It can also be a single string with names separated by a - * single blank. - * The path indicated in $p_remove_dir will be removed from the - * memorized path of each file / directory listed when this path - * exists. By default nothing is removed (empty path '') - * The path indicated in $p_add_dir will be added at the beginning of - * the memorized path of each file / directory listed. However it can - * be set to empty ''. The adding of a path is done after the removing - * of path. - * The path add/remove ability enables the user to prepare an archive - * for extraction in a different path than the origin files are. - * See also addModify() method for file adding properties. - * - * @param array $p_filelist An array of filenames and directory names, - * or a single string with names separated by - * a single blank space. - * @param string $p_add_dir A string which contains a path to be added - * to the memorized path of each element in - * the list. - * @param string $p_remove_dir A string which contains a path to be - * removed from the memorized path of each - * element in the list, when relevant. - * @return boolean true on success, false on error. - * @access public - * @see addModify() - */ + * This method creates the archive file and add the files / directories + * that are listed in $p_filelist. + * If the file already exists and is writable, it is replaced by the + * new tar. It is a create and not an add. If the file exists and is + * read-only or is a directory it is not replaced. The method return + * false and a PEAR error text. + * The $p_filelist parameter can be an array of string, each string + * representing a filename or a directory name with their path if + * needed. It can also be a single string with names separated by a + * single blank. + * The path indicated in $p_remove_dir will be removed from the + * memorized path of each file / directory listed when this path + * exists. By default nothing is removed (empty path '') + * The path indicated in $p_add_dir will be added at the beginning of + * the memorized path of each file / directory listed. However it can + * be set to empty ''. The adding of a path is done after the removing + * of path. + * The path add/remove ability enables the user to prepare an archive + * for extraction in a different path than the origin files are. + * See also addModify() method for file adding properties. + * + * @param array $p_filelist An array of filenames and directory names, + * or a single string with names separated by + * a single blank space. + * @param string $p_add_dir A string which contains a path to be added + * to the memorized path of each element in + * the list. + * @param string $p_remove_dir A string which contains a path to be + * removed from the memorized path of each + * element in the list, when relevant. + * + * @return boolean true on success, false on error. + * @access public + * @see addModify() + */ function createModify($p_filelist, $p_add_dir, $p_remove_dir='') { $v_result = true; @@ -325,52 +332,53 @@ class Archive_Tar extends PEAR // {{{ addModify() /** - * This method add the files / directories listed in $p_filelist at the - * end of the existing archive. If the archive does not yet exists it - * is created. - * The $p_filelist parameter can be an array of string, each string - * representing a filename or a directory name with their path if - * needed. It can also be a single string with names separated by a - * single blank. - * The path indicated in $p_remove_dir will be removed from the - * memorized path of each file / directory listed when this path - * exists. By default nothing is removed (empty path '') - * The path indicated in $p_add_dir will be added at the beginning of - * the memorized path of each file / directory listed. However it can - * be set to empty ''. The adding of a path is done after the removing - * of path. - * The path add/remove ability enables the user to prepare an archive - * for extraction in a different path than the origin files are. - * If a file/dir is already in the archive it will only be added at the - * end of the archive. There is no update of the existing archived - * file/dir. However while extracting the archive, the last file will - * replace the first one. This results in a none optimization of the - * archive size. - * If a file/dir does not exist the file/dir is ignored. However an - * error text is send to PEAR error. - * If a file/dir is not readable the file/dir is ignored. However an - * error text is send to PEAR error. - * - * @param array $p_filelist An array of filenames and directory - * names, or a single string with names - * separated by a single blank space. - * @param string $p_add_dir A string which contains a path to be - * added to the memorized path of each - * element in the list. - * @param string $p_remove_dir A string which contains a path to be - * removed from the memorized path of - * each element in the list, when - * relevant. - * @return true on success, false on error. - * @access public - */ + * This method add the files / directories listed in $p_filelist at the + * end of the existing archive. If the archive does not yet exists it + * is created. + * The $p_filelist parameter can be an array of string, each string + * representing a filename or a directory name with their path if + * needed. It can also be a single string with names separated by a + * single blank. + * The path indicated in $p_remove_dir will be removed from the + * memorized path of each file / directory listed when this path + * exists. By default nothing is removed (empty path '') + * The path indicated in $p_add_dir will be added at the beginning of + * the memorized path of each file / directory listed. However it can + * be set to empty ''. The adding of a path is done after the removing + * of path. + * The path add/remove ability enables the user to prepare an archive + * for extraction in a different path than the origin files are. + * If a file/dir is already in the archive it will only be added at the + * end of the archive. There is no update of the existing archived + * file/dir. However while extracting the archive, the last file will + * replace the first one. This results in a none optimization of the + * archive size. + * If a file/dir does not exist the file/dir is ignored. However an + * error text is send to PEAR error. + * If a file/dir is not readable the file/dir is ignored. However an + * error text is send to PEAR error. + * + * @param array $p_filelist An array of filenames and directory + * names, or a single string with names + * separated by a single blank space. + * @param string $p_add_dir A string which contains a path to be + * added to the memorized path of each + * element in the list. + * @param string $p_remove_dir A string which contains a path to be + * removed from the memorized path of + * each element in the list, when + * relevant. + * + * @return true on success, false on error. + * @access public + */ function addModify($p_filelist, $p_add_dir, $p_remove_dir='') { $v_result = true; if (!$this->_isArchive()) $v_result = $this->createModify($p_filelist, $p_add_dir, - $p_remove_dir); + $p_remove_dir); else { if (is_array($p_filelist)) $v_list = $p_filelist; @@ -390,19 +398,22 @@ class Archive_Tar extends PEAR // {{{ addString() /** - * This method add a single string as a file at the - * end of the existing archive. If the archive does not yet exists it - * is created. - * - * @param string $p_filename A string which contains the full - * filename path that will be associated - * with the string. - * @param string $p_string The content of the file added in - * the archive. - * @return true on success, false on error. - * @access public - */ - function addString($p_filename, $p_string) + * This method add a single string as a file at the + * end of the existing archive. If the archive does not yet exists it + * is created. + * + * @param string $p_filename A string which contains the full + * filename path that will be associated + * with the string. + * @param string $p_string The content of the file added in + * the archive. + * @param int $p_datetime A custom date/time (unix timestamp) + * for the file (optional). + * + * @return true on success, false on error. + * @access public + */ + function addString($p_filename, $p_string, $p_datetime = false) { $v_result = true; @@ -417,7 +428,7 @@ class Archive_Tar extends PEAR return false; // Need to check the get back to the temporary file ? .... - $v_result = $this->_addString($p_filename, $p_string); + $v_result = $this->_addString($p_filename, $p_string, $p_datetime); $this->_writeFooter(); @@ -429,46 +440,48 @@ class Archive_Tar extends PEAR // {{{ extractModify() /** - * This method extract all the content of the archive in the directory - * indicated by $p_path. When relevant the memorized path of the - * files/dir can be modified by removing the $p_remove_path path at the - * beginning of the file/dir path. - * While extracting a file, if the directory path does not exists it is - * created. - * While extracting a file, if the file already exists it is replaced - * without looking for last modification date. - * While extracting a file, if the file already exists and is write - * protected, the extraction is aborted. - * While extracting a file, if a directory with the same name already - * exists, the extraction is aborted. - * While extracting a directory, if a file with the same name already - * exists, the extraction is aborted. - * While extracting a file/directory if the destination directory exist - * and is write protected, or does not exist but can not be created, - * the extraction is aborted. - * If after extraction an extracted file does not show the correct - * stored file size, the extraction is aborted. - * When the extraction is aborted, a PEAR error text is set and false - * is returned. However the result can be a partial extraction that may - * need to be manually cleaned. - * - * @param string $p_path The path of the directory where the - * files/dir need to by extracted. - * @param string $p_remove_path Part of the memorized path that can be - * removed if present at the beginning of - * the file/dir path. - * @return boolean true on success, false on error. - * @access public - * @see extractList() - */ - function extractModify($p_path, $p_remove_path) + * This method extract all the content of the archive in the directory + * indicated by $p_path. When relevant the memorized path of the + * files/dir can be modified by removing the $p_remove_path path at the + * beginning of the file/dir path. + * While extracting a file, if the directory path does not exists it is + * created. + * While extracting a file, if the file already exists it is replaced + * without looking for last modification date. + * While extracting a file, if the file already exists and is write + * protected, the extraction is aborted. + * While extracting a file, if a directory with the same name already + * exists, the extraction is aborted. + * While extracting a directory, if a file with the same name already + * exists, the extraction is aborted. + * While extracting a file/directory if the destination directory exist + * and is write protected, or does not exist but can not be created, + * the extraction is aborted. + * If after extraction an extracted file does not show the correct + * stored file size, the extraction is aborted. + * When the extraction is aborted, a PEAR error text is set and false + * is returned. However the result can be a partial extraction that may + * need to be manually cleaned. + * + * @param string $p_path The path of the directory where the + * files/dir need to by extracted. + * @param string $p_remove_path Part of the memorized path that can be + * removed if present at the beginning of + * the file/dir path. + * @param boolean $p_preserve Preserve user/group ownership of files + * + * @return boolean true on success, false on error. + * @access public + * @see extractList() + */ + function extractModify($p_path, $p_remove_path, $p_preserve=false) { $v_result = true; $v_list_detail = array(); if ($v_result = $this->_openRead()) { $v_result = $this->_extractList($p_path, $v_list_detail, - "complete", 0, $p_remove_path); + "complete", 0, $p_remove_path, $p_preserve); $this->_close(); } @@ -478,19 +491,21 @@ class Archive_Tar extends PEAR // {{{ extractInString() /** - * This method extract from the archive one file identified by $p_filename. - * The return value is a string with the file content, or NULL on error. - * @param string $p_filename The path of the file to extract in a string. - * @return a string with the file content or NULL. - * @access public - */ + * This method extract from the archive one file identified by $p_filename. + * The return value is a string with the file content, or NULL on error. + * + * @param string $p_filename The path of the file to extract in a string. + * + * @return a string with the file content or NULL. + * @access public + */ function extractInString($p_filename) { if ($this->_openRead()) { $v_result = $this->_extractInString($p_filename); $this->_close(); } else { - $v_result = NULL; + $v_result = null; } return $v_result; @@ -499,24 +514,27 @@ class Archive_Tar extends PEAR // {{{ extractList() /** - * This method extract from the archive only the files indicated in the - * $p_filelist. These files are extracted in the current directory or - * in the directory indicated by the optional $p_path parameter. - * If indicated the $p_remove_path can be used in the same way as it is - * used in extractModify() method. - * @param array $p_filelist An array of filenames and directory names, - * or a single string with names separated - * by a single blank space. - * @param string $p_path The path of the directory where the - * files/dir need to by extracted. - * @param string $p_remove_path Part of the memorized path that can be - * removed if present at the beginning of - * the file/dir path. - * @return true on success, false on error. - * @access public - * @see extractModify() - */ - function extractList($p_filelist, $p_path='', $p_remove_path='') + * This method extract from the archive only the files indicated in the + * $p_filelist. These files are extracted in the current directory or + * in the directory indicated by the optional $p_path parameter. + * If indicated the $p_remove_path can be used in the same way as it is + * used in extractModify() method. + * + * @param array $p_filelist An array of filenames and directory names, + * or a single string with names separated + * by a single blank space. + * @param string $p_path The path of the directory where the + * files/dir need to by extracted. + * @param string $p_remove_path Part of the memorized path that can be + * removed if present at the beginning of + * the file/dir path. + * @param boolean $p_preserve Preserve user/group ownership of files + * + * @return true on success, false on error. + * @access public + * @see extractModify() + */ + function extractList($p_filelist, $p_path='', $p_remove_path='', $p_preserve=false) { $v_result = true; $v_list_detail = array(); @@ -532,7 +550,7 @@ class Archive_Tar extends PEAR if ($v_result = $this->_openRead()) { $v_result = $this->_extractList($p_path, $v_list_detail, "partial", - $v_list, $p_remove_path); + $v_list, $p_remove_path, $p_preserve); $this->_close(); } @@ -542,13 +560,15 @@ class Archive_Tar extends PEAR // {{{ setAttribute() /** - * This method set specific attributes of the archive. It uses a variable - * list of parameters, in the format attribute code + attribute values : - * $arch->setAttribute(ARCHIVE_TAR_ATT_SEPARATOR, ','); - * @param mixed $argv variable list of attributes and values - * @return true on success, false on error. - * @access public - */ + * This method set specific attributes of the archive. It uses a variable + * list of parameters, in the format attribute code + attribute values : + * $arch->setAttribute(ARCHIVE_TAR_ATT_SEPARATOR, ','); + * + * @param mixed $argv variable list of attributes and values + * + * @return true on success, false on error. + * @access public + */ function setAttribute() { $v_result = true; @@ -572,14 +592,14 @@ class Archive_Tar extends PEAR // ----- Check the number of parameters if (($i+1) >= $v_size) { $this->_error('Invalid number of parameters for ' - .'attribute ARCHIVE_TAR_ATT_SEPARATOR'); + .'attribute ARCHIVE_TAR_ATT_SEPARATOR'); return false; } // ----- Get the value $this->_separator = $v_att_list[$i+1]; $i++; - break; + break; default : $this->_error('Unknow attribute code '.$v_att_list[$i].''); @@ -596,54 +616,56 @@ class Archive_Tar extends PEAR // {{{ setIgnoreRegexp() /** - * This method sets the regular expression for ignoring files and directories - * at import, for example: - * $arch->setIgnoreRegexp("#CVS|\.svn#"); - * @param string $regexp regular expression defining which files or directories to ignore - * @access public - */ + * This method sets the regular expression for ignoring files and directories + * at import, for example: + * $arch->setIgnoreRegexp("#CVS|\.svn#"); + * + * @param string $regexp regular expression defining which files or directories to ignore + * + * @access public + */ function setIgnoreRegexp($regexp) { - $this->_ignore_regexp = $regexp; + $this->_ignore_regexp = $regexp; } // }}} // {{{ setIgnoreList() /** - * This method sets the regular expression for ignoring all files and directories - * matching the filenames in the array list at import, for example: - * $arch->setIgnoreList(array('CVS', '.svn', 'bin/tool')); - * @param array $list a list of file or directory names to ignore - * @access public - */ + * This method sets the regular expression for ignoring all files and directories + * matching the filenames in the array list at import, for example: + * $arch->setIgnoreList(array('CVS', '.svn', 'bin/tool')); + * + * @param array $list a list of file or directory names to ignore + * + * @access public + */ function setIgnoreList($list) { - $regexp = str_replace(array('#', '.', '^', '$'), array('\#', '\.', '\^', '\$'), $list); - $regexp = '#/'.join('$|/', $list).'#'; - $this->setIgnoreRegexp($regexp); + $regexp = str_replace(array('#', '.', '^', '$'), array('\#', '\.', '\^', '\$'), $list); + $regexp = '#/'.join('$|/', $list).'#'; + $this->setIgnoreRegexp($regexp); } // }}} // {{{ _error() function _error($p_message) { - // ----- To be completed - $this->raiseError($p_message); + $this->error_object = &$this->raiseError($p_message); } // }}} // {{{ _warning() function _warning($p_message) { - // ----- To be completed - $this->raiseError($p_message); + $this->error_object = &$this->raiseError($p_message); } // }}} // {{{ _isArchive() - function _isArchive($p_filename=NULL) + function _isArchive($p_filename=null) { - if ($p_filename == NULL) { + if ($p_filename == null) { $p_filename = $this->_tarname; } clearstatcache(); @@ -654,19 +676,21 @@ class Archive_Tar extends PEAR // {{{ _openWrite() function _openWrite() { - if ($this->_compress_type == 'gz') + if ($this->_compress_type == 'gz' && function_exists('gzopen')) $this->_file = @gzopen($this->_tarname, "wb9"); - else if ($this->_compress_type == 'bz2') + else if ($this->_compress_type == 'bz2' && function_exists('bzopen')) $this->_file = @bzopen($this->_tarname, "w"); else if ($this->_compress_type == 'none') $this->_file = @fopen($this->_tarname, "wb"); - else + else { $this->_error('Unknown or missing compression type (' - .$this->_compress_type.')'); + .$this->_compress_type.')'); + return false; + } if ($this->_file == 0) { $this->_error('Unable to open in write mode \'' - .$this->_tarname.'\''); + .$this->_tarname.'\''); return false; } @@ -679,43 +703,45 @@ class Archive_Tar extends PEAR { if (strtolower(substr($this->_tarname, 0, 7)) == 'http://') { - // ----- Look if a local copy need to be done - if ($this->_temp_tarname == '') { - $this->_temp_tarname = uniqid('tar').'.tmp'; - if (!$v_file_from = @fopen($this->_tarname, 'rb')) { - $this->_error('Unable to open in read mode \'' - .$this->_tarname.'\''); - $this->_temp_tarname = ''; - return false; - } - if (!$v_file_to = @fopen($this->_temp_tarname, 'wb')) { - $this->_error('Unable to open in write mode \'' - .$this->_temp_tarname.'\''); - $this->_temp_tarname = ''; - return false; - } - while ($v_data = @fread($v_file_from, 1024)) - @fwrite($v_file_to, $v_data); - @fclose($v_file_from); - @fclose($v_file_to); - } + // ----- Look if a local copy need to be done + if ($this->_temp_tarname == '') { + $this->_temp_tarname = uniqid('tar').'.tmp'; + if (!$v_file_from = @fopen($this->_tarname, 'rb')) { + $this->_error('Unable to open in read mode \'' + .$this->_tarname.'\''); + $this->_temp_tarname = ''; + return false; + } + if (!$v_file_to = @fopen($this->_temp_tarname, 'wb')) { + $this->_error('Unable to open in write mode \'' + .$this->_temp_tarname.'\''); + $this->_temp_tarname = ''; + return false; + } + while ($v_data = @fread($v_file_from, 1024)) + @fwrite($v_file_to, $v_data); + @fclose($v_file_from); + @fclose($v_file_to); + } - // ----- File to open if the local copy - $v_filename = $this->_temp_tarname; + // ----- File to open if the local copy + $v_filename = $this->_temp_tarname; } else - // ----- File to open if the normal Tar file - $v_filename = $this->_tarname; + // ----- File to open if the normal Tar file + $v_filename = $this->_tarname; - if ($this->_compress_type == 'gz') + if ($this->_compress_type == 'gz' && function_exists('gzopen')) $this->_file = @gzopen($v_filename, "rb"); - else if ($this->_compress_type == 'bz2') + else if ($this->_compress_type == 'bz2' && function_exists('bzopen')) $this->_file = @bzopen($v_filename, "r"); else if ($this->_compress_type == 'none') $this->_file = @fopen($v_filename, "rb"); - else + else { $this->_error('Unknown or missing compression type (' - .$this->_compress_type.')'); + .$this->_compress_type.')'); + return false; + } if ($this->_file == 0) { $this->_error('Unable to open in read mode \''.$v_filename.'\''); @@ -733,17 +759,19 @@ class Archive_Tar extends PEAR $this->_file = @gzopen($this->_tarname, "r+b"); else if ($this->_compress_type == 'bz2') { $this->_error('Unable to open bz2 in read/write mode \'' - .$this->_tarname.'\' (limitation of bz2 extension)'); + .$this->_tarname.'\' (limitation of bz2 extension)'); return false; } else if ($this->_compress_type == 'none') $this->_file = @fopen($this->_tarname, "r+b"); - else + else { $this->_error('Unknown or missing compression type (' - .$this->_compress_type.')'); + .$this->_compress_type.')'); + return false; + } if ($this->_file == 0) { $this->_error('Unable to open in read/write mode \'' - .$this->_tarname.'\''); + .$this->_tarname.'\''); return false; } @@ -764,7 +792,7 @@ class Archive_Tar extends PEAR @fclose($this->_file); else $this->_error('Unknown or missing compression type (' - .$this->_compress_type.')'); + .$this->_compress_type.')'); $this->_file = 0; } @@ -803,259 +831,258 @@ class Archive_Tar extends PEAR // {{{ _writeBlock() function _writeBlock($p_binary_data, $p_len=null) { - if (is_resource($this->_file)) { - if ($p_len === null) { - if ($this->_compress_type == 'gz') - @gzputs($this->_file, $p_binary_data); - else if ($this->_compress_type == 'bz2') - @bzwrite($this->_file, $p_binary_data); - else if ($this->_compress_type == 'none') - @fputs($this->_file, $p_binary_data); - else - $this->_error('Unknown or missing compression type (' - .$this->_compress_type.')'); - } else { - if ($this->_compress_type == 'gz') - @gzputs($this->_file, $p_binary_data, $p_len); - else if ($this->_compress_type == 'bz2') - @bzwrite($this->_file, $p_binary_data, $p_len); - else if ($this->_compress_type == 'none') - @fputs($this->_file, $p_binary_data, $p_len); - else - $this->_error('Unknown or missing compression type (' - .$this->_compress_type.')'); + if (is_resource($this->_file)) { + if ($p_len === null) { + if ($this->_compress_type == 'gz') + @gzputs($this->_file, $p_binary_data); + else if ($this->_compress_type == 'bz2') + @bzwrite($this->_file, $p_binary_data); + else if ($this->_compress_type == 'none') + @fputs($this->_file, $p_binary_data); + else + $this->_error('Unknown or missing compression type (' + .$this->_compress_type.')'); + } else { + if ($this->_compress_type == 'gz') + @gzputs($this->_file, $p_binary_data, $p_len); + else if ($this->_compress_type == 'bz2') + @bzwrite($this->_file, $p_binary_data, $p_len); + else if ($this->_compress_type == 'none') + @fputs($this->_file, $p_binary_data, $p_len); + else + $this->_error('Unknown or missing compression type (' + .$this->_compress_type.')'); - } - } - return true; + } + } + return true; } // }}} // {{{ _readBlock() function _readBlock() { - $v_block = null; - if (is_resource($this->_file)) { - if ($this->_compress_type == 'gz') - $v_block = @gzread($this->_file, 512); - else if ($this->_compress_type == 'bz2') - $v_block = @bzread($this->_file, 512); - else if ($this->_compress_type == 'none') - $v_block = @fread($this->_file, 512); - else - $this->_error('Unknown or missing compression type (' - .$this->_compress_type.')'); - } - return $v_block; + $v_block = null; + if (is_resource($this->_file)) { + if ($this->_compress_type == 'gz') + $v_block = @gzread($this->_file, 512); + else if ($this->_compress_type == 'bz2') + $v_block = @bzread($this->_file, 512); + else if ($this->_compress_type == 'none') + $v_block = @fread($this->_file, 512); + else + $this->_error('Unknown or missing compression type (' + .$this->_compress_type.')'); + } + return $v_block; } // }}} // {{{ _jumpBlock() function _jumpBlock($p_len=null) { - if (is_resource($this->_file)) { - if ($p_len === null) - $p_len = 1; + if (is_resource($this->_file)) { + if ($p_len === null) + $p_len = 1; - if ($this->_compress_type == 'gz') { - @gzseek($this->_file, gztell($this->_file)+($p_len*512)); - } - else if ($this->_compress_type == 'bz2') { - // ----- Replace missing bztell() and bzseek() - for ($i=0; $i<$p_len; $i++) - $this->_readBlock(); - } else if ($this->_compress_type == 'none') - @fseek($this->_file, $p_len*512, SEEK_CUR); - else - $this->_error('Unknown or missing compression type (' - .$this->_compress_type.')'); + if ($this->_compress_type == 'gz') { + @gzseek($this->_file, gztell($this->_file)+($p_len*512)); + } + else if ($this->_compress_type == 'bz2') { + // ----- Replace missing bztell() and bzseek() + for ($i=0; $i<$p_len; $i++) + $this->_readBlock(); + } else if ($this->_compress_type == 'none') + @fseek($this->_file, $p_len*512, SEEK_CUR); + else + $this->_error('Unknown or missing compression type (' + .$this->_compress_type.')'); - } - return true; + } + return true; } // }}} // {{{ _writeFooter() function _writeFooter() { - if (is_resource($this->_file)) { - // ----- Write the last 0 filled block for end of archive - $v_binary_data = pack('a1024', ''); - $this->_writeBlock($v_binary_data); - } - return true; + if (is_resource($this->_file)) { + // ----- Write the last 0 filled block for end of archive + $v_binary_data = pack('a1024', ''); + $this->_writeBlock($v_binary_data); + } + return true; } // }}} // {{{ _addList() function _addList($p_list, $p_add_dir, $p_remove_dir) { - $v_result=true; - $v_header = array(); + $v_result=true; + $v_header = array(); - // ----- Remove potential windows directory separator - $p_add_dir = $this->_translateWinPath($p_add_dir); - $p_remove_dir = $this->_translateWinPath($p_remove_dir, false); + // ----- Remove potential windows directory separator + $p_add_dir = $this->_translateWinPath($p_add_dir); + $p_remove_dir = $this->_translateWinPath($p_remove_dir, false); - if (!$this->_file) { - $this->_error('Invalid file descriptor'); - return false; - } - - if (sizeof($p_list) == 0) - return true; - - foreach ($p_list as $v_filename) { - if (!$v_result) { - break; - } - - // ----- Skip the current tar name - if ($v_filename == $this->_tarname) - continue; - - if ($v_filename == '') - continue; - - if($v_filename == $p_remove_dir.'/plugin.singleton') - continue; - - if($v_filename == $p_remove_dir.'/ee') - continue; - - // ----- ignore files and directories matching the ignore regular expression - if ($this->_ignore_regexp && preg_match($this->_ignore_regexp, '/'.$v_filename)) { - $this->_warning("File '$v_filename' ignored"); - continue; - } - - if (!file_exists($v_filename)) { - $this->_warning("File '$v_filename' does not exist"); - continue; + if (!$this->_file) { + $this->_error('Invalid file descriptor'); + return false; } - // ----- Add the file or directory header - if (!$this->_addFile($v_filename, $v_header, $p_add_dir, $p_remove_dir)) - return false; + if (sizeof($p_list) == 0) + return true; - if (@is_dir($v_filename) && !@is_link($v_filename)) { - if (!($p_hdir = opendir($v_filename))) { - $this->_warning("Directory '$v_filename' can not be read"); + foreach ($p_list as $v_filename) { + if (!$v_result) { + break; + } + + // ----- Skip the current tar name + if ($v_filename == $this->_tarname) + continue; + + if ($v_filename == '') + continue; + + // ----- ignore files and directories matching the ignore regular expression + if ($this->_ignore_regexp && preg_match($this->_ignore_regexp, '/'.$v_filename)) { + $this->_warning("File '$v_filename' ignored"); continue; } - while (false !== ($p_hitem = readdir($p_hdir))) { - if (($p_hitem != '.') && ($p_hitem != '..')) { - if ($v_filename != ".") - $p_temp_list[0] = $v_filename.'/'.$p_hitem; - else - $p_temp_list[0] = $p_hitem; - $v_result = $this->_addList($p_temp_list, - $p_add_dir, - $p_remove_dir); - } + if (!file_exists($v_filename) && !is_link($v_filename)) { + $this->_warning("File '$v_filename' does not exist"); + continue; } - unset($p_temp_list); - unset($p_hdir); - unset($p_hitem); - } - } + // ----- Add the file or directory header + if (!$this->_addFile($v_filename, $v_header, $p_add_dir, $p_remove_dir)) + return false; - return $v_result; + if (@is_dir($v_filename) && !@is_link($v_filename)) { + if (!($p_hdir = opendir($v_filename))) { + $this->_warning("Directory '$v_filename' can not be read"); + continue; + } + while (false !== ($p_hitem = readdir($p_hdir))) { + if (($p_hitem != '.') && ($p_hitem != '..')) { + if ($v_filename != ".") + $p_temp_list[0] = $v_filename.'/'.$p_hitem; + else + $p_temp_list[0] = $p_hitem; + + $v_result = $this->_addList($p_temp_list, + $p_add_dir, + $p_remove_dir); + } + } + + unset($p_temp_list); + unset($p_hdir); + unset($p_hitem); + } + } + + return $v_result; } // }}} // {{{ _addFile() function _addFile($p_filename, &$p_header, $p_add_dir, $p_remove_dir) { - if (!$this->_file) { - $this->_error('Invalid file descriptor'); - return false; - } + if (!$this->_file) { + $this->_error('Invalid file descriptor'); + return false; + } - if ($p_filename == '') { - $this->_error('Invalid file name'); - return false; - } + if ($p_filename == '') { + $this->_error('Invalid file name'); + return false; + } - // ----- Calculate the stored filename - $p_filename = $this->_translateWinPath($p_filename, false);; - $v_stored_filename = $p_filename; - if (strcmp($p_filename, $p_remove_dir) == 0) { - return true; - } - if ($p_remove_dir != '') { - if (substr($p_remove_dir, -1) != '/') - $p_remove_dir .= '/'; + // ----- Calculate the stored filename + $p_filename = $this->_translateWinPath($p_filename, false);; + $v_stored_filename = $p_filename; + if (strcmp($p_filename, $p_remove_dir) == 0) { + return true; + } + if ($p_remove_dir != '') { + if (substr($p_remove_dir, -1) != '/') + $p_remove_dir .= '/'; - if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir) - $v_stored_filename = substr($p_filename, strlen($p_remove_dir)); - } - $v_stored_filename = $this->_translateWinPath($v_stored_filename); - if ($p_add_dir != '') { - if (substr($p_add_dir, -1) == '/') - $v_stored_filename = $p_add_dir.$v_stored_filename; - else - $v_stored_filename = $p_add_dir.'/'.$v_stored_filename; - } + if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir) + $v_stored_filename = substr($p_filename, strlen($p_remove_dir)); + } + $v_stored_filename = $this->_translateWinPath($v_stored_filename); + if ($p_add_dir != '') { + if (substr($p_add_dir, -1) == '/') + $v_stored_filename = $p_add_dir.$v_stored_filename; + else + $v_stored_filename = $p_add_dir.'/'.$v_stored_filename; + } - $v_stored_filename = $this->_pathReduction($v_stored_filename); + $v_stored_filename = $this->_pathReduction($v_stored_filename); - if ($this->_isArchive($p_filename)) { - if (($v_file = @fopen($p_filename, "rb")) == 0) { - $this->_warning("Unable to open file '".$p_filename - ."' in binary read mode"); - return true; - } + if ($this->_isArchive($p_filename)) { + if (($v_file = @fopen($p_filename, "rb")) == 0) { + $this->_warning("Unable to open file '".$p_filename + ."' in binary read mode"); + return true; + } - if (!$this->_writeHeader($p_filename, $v_stored_filename)) - return false; + if (!$this->_writeHeader($p_filename, $v_stored_filename)) + return false; - while (($v_buffer = fread($v_file, 512)) != '') { - $v_binary_data = pack("a512", "$v_buffer"); - $this->_writeBlock($v_binary_data); - } + while (($v_buffer = fread($v_file, 512)) != '') { + $v_binary_data = pack("a512", "$v_buffer"); + $this->_writeBlock($v_binary_data); + } - fclose($v_file); + fclose($v_file); - } else { - // ----- Only header for dir - if (!$this->_writeHeader($p_filename, $v_stored_filename)) - return false; - } + } else { + // ----- Only header for dir + if (!$this->_writeHeader($p_filename, $v_stored_filename)) + return false; + } - return true; + return true; } // }}} // {{{ _addString() - function _addString($p_filename, $p_string) + function _addString($p_filename, $p_string, $p_datetime = false) { - if (!$this->_file) { - $this->_error('Invalid file descriptor'); - return false; - } + if (!$this->_file) { + $this->_error('Invalid file descriptor'); + return false; + } - if ($p_filename == '') { - $this->_error('Invalid file name'); - return false; - } + if ($p_filename == '') { + $this->_error('Invalid file name'); + return false; + } - // ----- Calculate the stored filename - $p_filename = $this->_translateWinPath($p_filename, false);; + // ----- Calculate the stored filename + $p_filename = $this->_translateWinPath($p_filename, false);; - if (!$this->_writeHeaderBlock($p_filename, strlen($p_string), - time(), 384, "", 0, 0)) - return false; + // ----- If datetime is not specified, set current time + if ($p_datetime === false) { + $p_datetime = time(); + } - $i=0; - while (($v_buffer = substr($p_string, (($i++)*512), 512)) != '') { - $v_binary_data = pack("a512", $v_buffer); - $this->_writeBlock($v_binary_data); - } + if (!$this->_writeHeaderBlock($p_filename, strlen($p_string), + $p_datetime, 384, "", 0, 0)) + return false; - return true; + $i=0; + while (($v_buffer = substr($p_string, (($i++)*512), 512)) != '') { + $v_binary_data = pack("a512", $v_buffer); + $this->_writeBlock($v_binary_data); + } + + return true; } // }}} @@ -1067,8 +1094,8 @@ class Archive_Tar extends PEAR $v_reduce_filename = $this->_pathReduction($p_stored_filename); if (strlen($v_reduce_filename) > 99) { - if (!$this->_writeLongHeader($v_reduce_filename)) - return false; + if (!$this->_writeLongHeader($v_reduce_filename)) + return false; } $v_info = lstat($p_filename); @@ -1081,16 +1108,16 @@ class Archive_Tar extends PEAR $v_linkname = ''; if (@is_link($p_filename)) { - $v_typeflag = '2'; - $v_linkname = readlink($p_filename); - $v_size = sprintf("%011s", DecOct(0)); + $v_typeflag = '2'; + $v_linkname = readlink($p_filename); + $v_size = sprintf("%011s", DecOct(0)); } elseif (@is_dir($p_filename)) { - $v_typeflag = "5"; - $v_size = sprintf("%011s", DecOct(0)); + $v_typeflag = "5"; + $v_size = sprintf("%011s", DecOct(0)); } else { - $v_typeflag = '0'; - clearstatcache(); - $v_size = sprintf("%011s", DecOct($v_info['size'])); + $v_typeflag = '0'; + clearstatcache(); + $v_size = sprintf("%011s", DecOct($v_info['size'])); } $v_magic = 'ustar '; @@ -1099,16 +1126,16 @@ class Archive_Tar extends PEAR if (function_exists('posix_getpwuid')) { - $userinfo = posix_getpwuid($v_info[4]); - $groupinfo = posix_getgrgid($v_info[5]); + $userinfo = posix_getpwuid($v_info[4]); + $groupinfo = posix_getgrgid($v_info[5]); - $v_uname = $userinfo['name']; - $v_gname = $groupinfo['name']; + $v_uname = $userinfo['name']; + $v_gname = $groupinfo['name']; } else { - $v_uname = ''; - $v_gname = ''; + $v_uname = ''; + $v_gname = ''; } $v_devmajor = ''; @@ -1118,12 +1145,12 @@ class Archive_Tar extends PEAR $v_prefix = ''; $v_binary_data_first = pack("a100a8a8a8a12a12", - $v_reduce_filename, $v_perms, $v_uid, - $v_gid, $v_size, $v_mtime); + $v_reduce_filename, $v_perms, $v_uid, + $v_gid, $v_size, $v_mtime); $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12", - $v_typeflag, $v_linkname, $v_magic, - $v_version, $v_uname, $v_gname, - $v_devmajor, $v_devminor, $v_prefix, ''); + $v_typeflag, $v_linkname, $v_magic, + $v_version, $v_uname, $v_gname, + $v_devmajor, $v_devminor, $v_prefix, ''); // ----- Calculate the checksum $v_checksum = 0; @@ -1154,19 +1181,19 @@ class Archive_Tar extends PEAR // {{{ _writeHeaderBlock() function _writeHeaderBlock($p_filename, $p_size, $p_mtime=0, $p_perms=0, - $p_type='', $p_uid=0, $p_gid=0) + $p_type='', $p_uid=0, $p_gid=0) { $p_filename = $this->_pathReduction($p_filename); if (strlen($p_filename) > 99) { - if (!$this->_writeLongHeader($p_filename)) - return false; + if (!$this->_writeLongHeader($p_filename)) + return false; } if ($p_type == "5") { - $v_size = sprintf("%011s", DecOct(0)); + $v_size = sprintf("%011s", DecOct(0)); } else { - $v_size = sprintf("%011s", DecOct($p_size)); + $v_size = sprintf("%011s", DecOct($p_size)); } $v_uid = sprintf("%07s", DecOct($p_uid)); @@ -1183,16 +1210,16 @@ class Archive_Tar extends PEAR if (function_exists('posix_getpwuid')) { - $userinfo = posix_getpwuid($p_uid); - $groupinfo = posix_getgrgid($p_gid); + $userinfo = posix_getpwuid($p_uid); + $groupinfo = posix_getgrgid($p_gid); - $v_uname = $userinfo['name']; - $v_gname = $groupinfo['name']; + $v_uname = $userinfo['name']; + $v_gname = $groupinfo['name']; } else { - $v_uname = ''; - $v_gname = ''; + $v_uname = ''; + $v_gname = ''; } $v_devmajor = ''; @@ -1202,12 +1229,12 @@ class Archive_Tar extends PEAR $v_prefix = ''; $v_binary_data_first = pack("a100a8a8a8a12A12", - $p_filename, $v_perms, $v_uid, $v_gid, - $v_size, $v_mtime); + $p_filename, $v_perms, $v_uid, $v_gid, + $v_size, $v_mtime); $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12", - $p_type, $v_linkname, $v_magic, - $v_version, $v_uname, $v_gname, - $v_devmajor, $v_devminor, $v_prefix, ''); + $p_type, $v_linkname, $v_magic, + $v_version, $v_uname, $v_gname, + $v_devmajor, $v_devminor, $v_prefix, ''); // ----- Calculate the checksum $v_checksum = 0; @@ -1260,11 +1287,11 @@ class Archive_Tar extends PEAR $v_prefix = ''; $v_binary_data_first = pack("a100a8a8a8a12a12", - '././@LongLink', 0, 0, 0, $v_size, 0); + '././@LongLink', 0, 0, 0, $v_size, 0); $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12", - $v_typeflag, $v_linkname, $v_magic, - $v_version, $v_uname, $v_gname, - $v_devmajor, $v_devminor, $v_prefix, ''); + $v_typeflag, $v_linkname, $v_magic, + $v_version, $v_uname, $v_gname, + $v_devmajor, $v_devminor, $v_prefix, ''); // ----- Calculate the checksum $v_checksum = 0; @@ -1327,12 +1354,22 @@ class Archive_Tar extends PEAR $v_checksum += ord(' '); // ..... Last part of the header for ($i=156; $i<512; $i++) - $v_checksum+=ord(substr($v_binary_data,$i,1)); + $v_checksum+=ord(substr($v_binary_data,$i,1)); - $v_data = unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/" - ."a8checksum/a1typeflag/a100link/a6magic/a2version/" - ."a32uname/a32gname/a8devmajor/a8devminor", - $v_binary_data); + if (version_compare(PHP_VERSION,"5.5.0-dev")<0) { + $fmt = "a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/" . + "a8checksum/a1typeflag/a100link/a6magic/a2version/" . + "a32uname/a32gname/a8devmajor/a8devminor/a131prefix"; + } else { + $fmt = "Z100filename/Z8mode/Z8uid/Z8gid/Z12size/Z12mtime/" . + "Z8checksum/Z1typeflag/Z100link/Z6magic/Z2version/" . + "Z32uname/Z32gname/Z8devmajor/Z8devminor/Z131prefix"; + } + $v_data = unpack($fmt, $v_binary_data); + + if (strlen($v_data["prefix"]) > 0) { + $v_data["filename"] = "$v_data[prefix]/$v_data[filename]"; + } // ----- Extract the checksum $v_header['checksum'] = OctDec(trim($v_data['checksum'])); @@ -1344,8 +1381,8 @@ class Archive_Tar extends PEAR return true; $this->_error('Invalid checksum for file "'.$v_data['filename'] - .'" : '.$v_checksum.' calculated, ' - .$v_header['checksum'].' expected'); + .'" : '.$v_checksum.' calculated, ' + .$v_header['checksum'].' expected'); return false; } @@ -1362,7 +1399,7 @@ class Archive_Tar extends PEAR $v_header['size'] = OctDec(trim($v_data['size'])); $v_header['mtime'] = OctDec(trim($v_data['mtime'])); if (($v_header['typeflag'] = $v_data['typeflag']) == "5") { - $v_header['size'] = 0; + $v_header['size'] = 0; } $v_header['link'] = trim($v_data['link']); /* ----- All these fields are removed form the header because @@ -1384,6 +1421,7 @@ class Archive_Tar extends PEAR * Detect and report a malicious file name * * @param string $file + * * @return bool * @access private */ @@ -1402,305 +1440,323 @@ class Archive_Tar extends PEAR // {{{ _readLongHeader() function _readLongHeader(&$v_header) { - $v_filename = ''; - $n = floor($v_header['size']/512); - for ($i=0; $i<$n; $i++) { - $v_content = $this->_readBlock(); - $v_filename .= $v_content; - } - if (($v_header['size'] % 512) != 0) { - $v_content = $this->_readBlock(); - $v_filename .= trim($v_content); - } + $v_filename = ''; + $n = floor($v_header['size']/512); + for ($i=0; $i<$n; $i++) { + $v_content = $this->_readBlock(); + $v_filename .= $v_content; + } + if (($v_header['size'] % 512) != 0) { + $v_content = $this->_readBlock(); + $v_filename .= trim($v_content); + } - // ----- Read the next header - $v_binary_data = $this->_readBlock(); + // ----- Read the next header + $v_binary_data = $this->_readBlock(); - if (!$this->_readHeader($v_binary_data, $v_header)) - return false; + if (!$this->_readHeader($v_binary_data, $v_header)) + return false; - $v_filename = trim($v_filename); - $v_header['filename'] = $v_filename; + $v_filename = trim($v_filename); + $v_header['filename'] = $v_filename; if ($this->_maliciousFilename($v_filename)) { $this->_error('Malicious .tar detected, file "' . $v_filename . '" will not install in desired directory tree'); return false; - } + } - return true; + return true; } // }}} // {{{ _extractInString() /** - * This method extract from the archive one file identified by $p_filename. - * The return value is a string with the file content, or NULL on error. - * @param string $p_filename The path of the file to extract in a string. - * @return a string with the file content or NULL. - * @access private - */ + * This method extract from the archive one file identified by $p_filename. + * The return value is a string with the file content, or null on error. + * + * @param string $p_filename The path of the file to extract in a string. + * + * @return a string with the file content or null. + * @access private + */ function _extractInString($p_filename) { $v_result_str = ""; While (strlen($v_binary_data = $this->_readBlock()) != 0) { - if (!$this->_readHeader($v_binary_data, $v_header)) - return NULL; + if (!$this->_readHeader($v_binary_data, $v_header)) + return null; - if ($v_header['filename'] == '') - continue; + if ($v_header['filename'] == '') + continue; - // ----- Look for long filename - if ($v_header['typeflag'] == 'L') { - if (!$this->_readLongHeader($v_header)) - return NULL; - } + // ----- Look for long filename + if ($v_header['typeflag'] == 'L') { + if (!$this->_readLongHeader($v_header)) + return null; + } - if ($v_header['filename'] == $p_filename) { - if ($v_header['typeflag'] == "5") { - $this->_error('Unable to extract in string a directory ' - .'entry {'.$v_header['filename'].'}'); - return NULL; - } else { - $n = floor($v_header['size']/512); - for ($i=0; $i<$n; $i++) { - $v_result_str .= $this->_readBlock(); - } - if (($v_header['size'] % 512) != 0) { - $v_content = $this->_readBlock(); - $v_result_str .= substr($v_content, 0, - ($v_header['size'] % 512)); - } - return $v_result_str; - } - } else { - $this->_jumpBlock(ceil(($v_header['size']/512))); - } + if ($v_header['filename'] == $p_filename) { + if ($v_header['typeflag'] == "5") { + $this->_error('Unable to extract in string a directory ' + .'entry {'.$v_header['filename'].'}'); + return null; + } else { + $n = floor($v_header['size']/512); + for ($i=0; $i<$n; $i++) { + $v_result_str .= $this->_readBlock(); + } + if (($v_header['size'] % 512) != 0) { + $v_content = $this->_readBlock(); + $v_result_str .= substr($v_content, 0, + ($v_header['size'] % 512)); + } + return $v_result_str; + } + } else { + $this->_jumpBlock(ceil(($v_header['size']/512))); + } } - return NULL; + return null; } // }}} // {{{ _extractList() function _extractList($p_path, &$p_list_detail, $p_mode, - $p_file_list, $p_remove_path) + $p_file_list, $p_remove_path, $p_preserve=false) { - $v_result=true; - $v_nb = 0; - $v_extract_all = true; - $v_listing = false; + $v_result=true; + $v_nb = 0; + $v_extract_all = true; + $v_listing = false; - $p_path = $this->_translateWinPath($p_path, false); - if ($p_path == '' || (substr($p_path, 0, 1) != '/' - && substr($p_path, 0, 3) != "../" && !strpos($p_path, ':'))) { - $p_path = "./".$p_path; - } - $p_remove_path = $this->_translateWinPath($p_remove_path); + $p_path = $this->_translateWinPath($p_path, false); + if ($p_path == '' || (substr($p_path, 0, 1) != '/' + && substr($p_path, 0, 3) != "../" && !strpos($p_path, ':'))) { + $p_path = "./".$p_path; + } + $p_remove_path = $this->_translateWinPath($p_remove_path); - // ----- Look for path to remove format (should end by /) - if (($p_remove_path != '') && (substr($p_remove_path, -1) != '/')) - $p_remove_path .= '/'; - $p_remove_path_size = strlen($p_remove_path); + // ----- Look for path to remove format (should end by /) + if (($p_remove_path != '') && (substr($p_remove_path, -1) != '/')) + $p_remove_path .= '/'; + $p_remove_path_size = strlen($p_remove_path); - switch ($p_mode) { - case "complete" : - $v_extract_all = TRUE; - $v_listing = FALSE; - break; - case "partial" : - $v_extract_all = FALSE; - $v_listing = FALSE; - break; - case "list" : - $v_extract_all = FALSE; - $v_listing = TRUE; - break; - default : - $this->_error('Invalid extract mode ('.$p_mode.')'); - return false; - } + switch ($p_mode) { + case "complete" : + $v_extract_all = true; + $v_listing = false; + break; + case "partial" : + $v_extract_all = false; + $v_listing = false; + break; + case "list" : + $v_extract_all = false; + $v_listing = true; + break; + default : + $this->_error('Invalid extract mode ('.$p_mode.')'); + return false; + } - clearstatcache(); + clearstatcache(); - while (strlen($v_binary_data = $this->_readBlock()) != 0) - { - $v_extract_file = FALSE; - $v_extraction_stopped = 0; + while (strlen($v_binary_data = $this->_readBlock()) != 0) + { + $v_extract_file = FALSE; + $v_extraction_stopped = 0; - if (!$this->_readHeader($v_binary_data, $v_header)) - return false; + if (!$this->_readHeader($v_binary_data, $v_header)) + return false; - if ($v_header['filename'] == '') { - continue; - } - - // ----- Look for long filename - if ($v_header['typeflag'] == 'L') { - if (!$this->_readLongHeader($v_header)) - return false; - } - - if ((!$v_extract_all) && (is_array($p_file_list))) { - // ----- By default no unzip if the file is not found - $v_extract_file = false; - - for ($i=0; $i strlen($p_file_list[$i])) - && (substr($v_header['filename'], 0, strlen($p_file_list[$i])) - == $p_file_list[$i])) { - $v_extract_file = TRUE; - break; + if ($v_header['filename'] == '') { + continue; } - } - // ----- It is a file, so compare the file names - elseif ($p_file_list[$i] == $v_header['filename']) { - $v_extract_file = TRUE; - break; - } - } - } else { - $v_extract_file = TRUE; - } + // ----- Look for long filename + if ($v_header['typeflag'] == 'L') { + if (!$this->_readLongHeader($v_header)) + return false; + } - // ----- Look if this file need to be extracted - if (($v_extract_file) && (!$v_listing)) - { - if (($p_remove_path != '') - && (substr($v_header['filename'], 0, $p_remove_path_size) - == $p_remove_path)) - $v_header['filename'] = substr($v_header['filename'], - $p_remove_path_size); - if (($p_path != './') && ($p_path != '/')) { - while (substr($p_path, -1) == '/') - $p_path = substr($p_path, 0, strlen($p_path)-1); + if ((!$v_extract_all) && (is_array($p_file_list))) { + // ----- By default no unzip if the file is not found + $v_extract_file = false; - if (substr($v_header['filename'], 0, 1) == '/') - $v_header['filename'] = $p_path.$v_header['filename']; - else - $v_header['filename'] = $p_path.'/'.$v_header['filename']; - } - if (file_exists($v_header['filename'])) { - if ( (@is_dir($v_header['filename'])) - && ($v_header['typeflag'] == '')) { - $this->_error('File '.$v_header['filename'] - .' already exists as a directory'); - return false; - } - if ( ($this->_isArchive($v_header['filename'])) - && ($v_header['typeflag'] == "5")) { - $this->_error('Directory '.$v_header['filename'] - .' already exists as a file'); - return false; - } - if (!is_writeable($v_header['filename'])) { - $this->_error('File '.$v_header['filename'] - .' already exists and is write protected'); - return false; - } - if (filemtime($v_header['filename']) > $v_header['mtime']) { - // To be completed : An error or silent no replace ? - } - } + for ($i=0; $i strlen($p_file_list[$i])) + && (substr($v_header['filename'], 0, strlen($p_file_list[$i])) + == $p_file_list[$i])) { + $v_extract_file = true; + break; + } + } - // ----- Check the directory availability and create it if necessary - elseif (($v_result - = $this->_dirCheck(($v_header['typeflag'] == "5" - ?$v_header['filename'] - :dirname($v_header['filename'])))) != 1) { - $this->_error('Unable to create path for '.$v_header['filename']); - return false; - } + // ----- It is a file, so compare the file names + elseif ($p_file_list[$i] == $v_header['filename']) { + $v_extract_file = true; + break; + } + } + } else { + $v_extract_file = true; + } - if ($v_extract_file) { - if ($v_header['typeflag'] == "5") { - if (!@file_exists($v_header['filename'])) { - if (!@mkdir($v_header['filename'], 0777)) { - $this->_error('Unable to create directory {' - .$v_header['filename'].'}'); + // ----- Look if this file need to be extracted + if (($v_extract_file) && (!$v_listing)) + { + if (($p_remove_path != '') + && (substr($v_header['filename'].'/', 0, $p_remove_path_size) + == $p_remove_path)) { + $v_header['filename'] = substr($v_header['filename'], + $p_remove_path_size); + if( $v_header['filename'] == '' ){ + continue; + } + } + if (($p_path != './') && ($p_path != '/')) { + while (substr($p_path, -1) == '/') + $p_path = substr($p_path, 0, strlen($p_path)-1); + + if (substr($v_header['filename'], 0, 1) == '/') + $v_header['filename'] = $p_path.$v_header['filename']; + else + $v_header['filename'] = $p_path.'/'.$v_header['filename']; + } + if (file_exists($v_header['filename'])) { + if ( (@is_dir($v_header['filename'])) + && ($v_header['typeflag'] == '')) { + $this->_error('File '.$v_header['filename'] + .' already exists as a directory'); + return false; + } + if ( ($this->_isArchive($v_header['filename'])) + && ($v_header['typeflag'] == "5")) { + $this->_error('Directory '.$v_header['filename'] + .' already exists as a file'); + return false; + } + if (!is_writeable($v_header['filename'])) { + $this->_error('File '.$v_header['filename'] + .' already exists and is write protected'); + return false; + } + if (filemtime($v_header['filename']) > $v_header['mtime']) { + // To be completed : An error or silent no replace ? + } + } + + // ----- Check the directory availability and create it if necessary + elseif (($v_result + = $this->_dirCheck(($v_header['typeflag'] == "5" + ?$v_header['filename'] + :dirname($v_header['filename'])))) != 1) { + $this->_error('Unable to create path for '.$v_header['filename']); return false; } - } - } elseif ($v_header['typeflag'] == "2") { - if (@file_exists($v_header['filename'])) { - @unlink($v_header['filename']); - } - if (!@symlink($v_header['link'], $v_header['filename'])) { - $this->_error('Unable to extract symbolic link {' + + if ($v_extract_file) { + if ($v_header['typeflag'] == "5") { + if (!@file_exists($v_header['filename'])) { + if (!@mkdir($v_header['filename'], 0777)) { + $this->_error('Unable to create directory {' + .$v_header['filename'].'}'); + return false; + } + } + } elseif ($v_header['typeflag'] == "2") { + if (@file_exists($v_header['filename'])) { + @unlink($v_header['filename']); + } + if (!@symlink($v_header['link'], $v_header['filename'])) { + $this->_error('Unable to extract symbolic link {' .$v_header['filename'].'}'); - return false; - } - } else { - if (($v_dest_file = @fopen($v_header['filename'], "wb")) == 0) { - $this->_error('Error while opening {'.$v_header['filename'] - .'} in write binary mode'); - return false; - } else { - $n = floor($v_header['size']/512); - for ($i=0; $i<$n; $i++) { - $v_content = $this->_readBlock(); - fwrite($v_dest_file, $v_content, 512); - } - if (($v_header['size'] % 512) != 0) { - $v_content = $this->_readBlock(); - fwrite($v_dest_file, $v_content, ($v_header['size'] % 512)); + return false; + } + } else { + if (($v_dest_file = @fopen($v_header['filename'], "wb")) == 0) { + $this->_error('Error while opening {'.$v_header['filename'] + .'} in write binary mode'); + return false; + } else { + $n = floor($v_header['size']/512); + for ($i=0; $i<$n; $i++) { + $v_content = $this->_readBlock(); + fwrite($v_dest_file, $v_content, 512); + } + if (($v_header['size'] % 512) != 0) { + $v_content = $this->_readBlock(); + fwrite($v_dest_file, $v_content, ($v_header['size'] % 512)); + } + + @fclose($v_dest_file); + + if ($p_preserve) { + @chown($v_header['filename'], $v_header['uid']); + @chgrp($v_header['filename'], $v_header['gid']); + } + + // ----- Change the file mode, mtime + @touch($v_header['filename'], $v_header['mtime']); + if ($v_header['mode'] & 0111) { + // make file executable, obey umask + $mode = fileperms($v_header['filename']) | (~umask() & 0111); + @chmod($v_header['filename'], $mode); + } + } + + // ----- Check the file size + clearstatcache(); + if (!is_file($v_header['filename'])) { + $this->_error('Extracted file '.$v_header['filename'] + .'does not exist. Archive may be corrupted.'); + return false; + } + + $filesize = filesize($v_header['filename']); + if ($filesize != $v_header['size']) { + $this->_error('Extracted file '.$v_header['filename'] + .' does not have the correct file size \'' + .$filesize + .'\' ('.$v_header['size'] + .' expected). Archive may be corrupted.'); + return false; + } + } + } else { + $this->_jumpBlock(ceil(($v_header['size']/512))); + } + } else { + $this->_jumpBlock(ceil(($v_header['size']/512))); } - @fclose($v_dest_file); + /* TBC : Seems to be unused ... + if ($this->_compress) + $v_end_of_file = @gzeof($this->_file); + else + $v_end_of_file = @feof($this->_file); + */ - // ----- Change the file mode, mtime - @touch($v_header['filename'], $v_header['mtime']); - if ($v_header['mode'] & 0111) { - // make file executable, obey umask - $mode = fileperms($v_header['filename']) | (~umask() & 0111); - @chmod($v_header['filename'], $mode); + if ($v_listing || $v_extract_file || $v_extraction_stopped) { + // ----- Log extracted files + if (($v_file_dir = dirname($v_header['filename'])) + == $v_header['filename']) + $v_file_dir = ''; + if ((substr($v_header['filename'], 0, 1) == '/') && ($v_file_dir == '')) + $v_file_dir = '/'; + + $p_list_detail[$v_nb++] = $v_header; + if (is_array($p_file_list) && (count($p_list_detail) == count($p_file_list))) { + return true; + } } - } - - // ----- Check the file size - clearstatcache(); - if (filesize($v_header['filename']) != $v_header['size']) { - $this->_error('Extracted file '.$v_header['filename'] - .' does not have the correct file size \'' - .filesize($v_header['filename']) - .'\' ('.$v_header['size'] - .' expected). Archive may be corrupted.'); - return false; - } - } - } else { - $this->_jumpBlock(ceil(($v_header['size']/512))); } - } else { - $this->_jumpBlock(ceil(($v_header['size']/512))); - } - - /* TBC : Seems to be unused ... - if ($this->_compress) - $v_end_of_file = @gzeof($this->_file); - else - $v_end_of_file = @feof($this->_file); - */ - - if ($v_listing || $v_extract_file || $v_extraction_stopped) { - // ----- Log extracted files - if (($v_file_dir = dirname($v_header['filename'])) - == $v_header['filename']) - $v_file_dir = ''; - if ((substr($v_header['filename'], 0, 1) == '/') && ($v_file_dir == '')) - $v_file_dir = '/'; - - $p_list_detail[$v_nb++] = $v_header; - if (is_array($p_file_list) && (count($p_list_detail) == count($p_file_list))) { - return true; - } - } - } return true; } @@ -1710,15 +1766,15 @@ class Archive_Tar extends PEAR function _openAppend() { if (filesize($this->_tarname) == 0) - return $this->_openWrite(); + return $this->_openWrite(); if ($this->_compress) { $this->_close(); if (!@rename($this->_tarname, $this->_tarname.".tmp")) { $this->_error('Error while renaming \''.$this->_tarname - .'\' to temporary file \''.$this->_tarname - .'.tmp\''); + .'\' to temporary file \''.$this->_tarname + .'.tmp\''); return false; } @@ -1729,7 +1785,7 @@ class Archive_Tar extends PEAR if ($v_temp_tar == 0) { $this->_error('Unable to open file \''.$this->_tarname - .'.tmp\' in binary read mode'); + .'.tmp\' in binary read mode'); @rename($this->_tarname.".tmp", $this->_tarname); return false; } @@ -1740,12 +1796,20 @@ class Archive_Tar extends PEAR } if ($this->_compress_type == 'gz') { + $end_blocks = 0; + while (!@gzeof($v_temp_tar)) { $v_buffer = @gzread($v_temp_tar, 512); - if ($v_buffer == ARCHIVE_TAR_END_BLOCK) { + if ($v_buffer == ARCHIVE_TAR_END_BLOCK || strlen($v_buffer) == 0) { + $end_blocks++; // do not copy end blocks, we will re-make them // after appending continue; + } elseif ($end_blocks > 0) { + for ($i = 0; $i < $end_blocks; $i++) { + $this->_writeBlock(ARCHIVE_TAR_END_BLOCK); + } + $end_blocks = 0; } $v_binary_data = pack("a512", $v_buffer); $this->_writeBlock($v_binary_data); @@ -1754,9 +1818,19 @@ class Archive_Tar extends PEAR @gzclose($v_temp_tar); } elseif ($this->_compress_type == 'bz2') { + $end_blocks = 0; + while (strlen($v_buffer = @bzread($v_temp_tar, 512)) > 0) { - if ($v_buffer == ARCHIVE_TAR_END_BLOCK) { + if ($v_buffer == ARCHIVE_TAR_END_BLOCK || strlen($v_buffer) == 0) { + $end_blocks++; + // do not copy end blocks, we will re-make them + // after appending continue; + } elseif ($end_blocks > 0) { + for ($i = 0; $i < $end_blocks; $i++) { + $this->_writeBlock(ARCHIVE_TAR_END_BLOCK); + } + $end_blocks = 0; } $v_binary_data = pack("a512", $v_buffer); $this->_writeBlock($v_binary_data); @@ -1767,14 +1841,14 @@ class Archive_Tar extends PEAR if (!@unlink($this->_tarname.".tmp")) { $this->_error('Error while deleting temporary file \'' - .$this->_tarname.'.tmp\''); + .$this->_tarname.'.tmp\''); } } else { // ----- For not compressed tar, just add files before the last - // one or two 512 bytes block + // one or two 512 bytes block if (!$this->_openReadWrite()) - return false; + return false; clearstatcache(); $v_size = filesize($this->_tarname); @@ -1802,7 +1876,7 @@ class Archive_Tar extends PEAR return false; if ($this->_addList($p_filelist, $p_add_dir, $p_remove_dir)) - $this->_writeFooter(); + $this->_writeFooter(); $this->_close(); @@ -1818,7 +1892,7 @@ class Archive_Tar extends PEAR * * @param string $p_dir directory to check * - * @return bool TRUE if the directory exists or was created + * @return bool true if the directory exists or was created */ function _dirCheck($p_dir) { @@ -1831,7 +1905,7 @@ class Archive_Tar extends PEAR if (($p_parent_dir != $p_dir) && ($p_parent_dir != '') && (!$this->_dirCheck($p_parent_dir))) - return false; + return false; if (!@mkdir($p_dir, 0777)) { $this->_error("Unable to create directory '$p_dir'"); @@ -1877,17 +1951,21 @@ class Archive_Tar extends PEAR $i--; } else if ( ($v_list[$i] == '') - && ($i!=(sizeof($v_list)-1)) - && ($i!=0)) { + && ($i!=(sizeof($v_list)-1)) + && ($i!=0)) { // ----- Ignore only the double '//' in path, // but not the first and last / } else { $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?'/' - .$v_result:''); + .$v_result:''); } } } - $v_result = strtr($v_result, '\\', '/'); + + if (defined('OS_WINDOWS') && OS_WINDOWS) { + $v_result = strtr($v_result, '\\', '/'); + } + return $v_result; } @@ -1896,20 +1974,20 @@ class Archive_Tar extends PEAR // {{{ _translateWinPath() function _translateWinPath($p_path, $p_remove_disk_letter=true) { - if (defined('OS_WINDOWS') && OS_WINDOWS) { - // ----- Look for potential disk letter - if ( ($p_remove_disk_letter) - && (($v_position = strpos($p_path, ':')) != false)) { - $p_path = substr($p_path, $v_position+1); - } - // ----- Change potential windows directory separator - if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) { - $p_path = strtr($p_path, '\\', '/'); - } - } - return $p_path; + if (defined('OS_WINDOWS') && OS_WINDOWS) { + // ----- Look for potential disk letter + if ( ($p_remove_disk_letter) + && (($v_position = strpos($p_path, ':')) != false)) { + $p_path = substr($p_path, $v_position+1); + } + // ----- Change potential windows directory separator + if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) { + $p_path = strtr($p_path, '\\', '/'); + } + } + return $p_path; } // }}} } -?> +?> \ No newline at end of file diff --git a/workflow/engine/classes/class.pluginRegistry.php b/workflow/engine/classes/class.pluginRegistry.php index 1e3f3af87..d51baadc7 100755 --- a/workflow/engine/classes/class.pluginRegistry.php +++ b/workflow/engine/classes/class.pluginRegistry.php @@ -139,6 +139,24 @@ class PMPluginRegistry return self::$instance; } + /** + * Load the singleton instance from a serialized stored file + * + * @param $file + * @return PMPluginRegistry + * @throws Exception + */ + public static function loadSingleton($file) + { + self::$instance = unserialize(file_get_contents($file)); + + if (! is_object(self::$instance) || get_class(self::$instance) != "PMPluginRegistry") { + throw new Exception("Can't load main PMPluginRegistry object."); + } + + return self::$instance; + } + /** * This function generates a storable representation of a value * param diff --git a/workflow/engine/src/BusinessModel/CaseTracker.php b/workflow/engine/src/BusinessModel/CaseTracker.php index 8dbf2a8a2..bb01280cb 100644 --- a/workflow/engine/src/BusinessModel/CaseTracker.php +++ b/workflow/engine/src/BusinessModel/CaseTracker.php @@ -155,13 +155,6 @@ class CaseTracker //Array DB $arrayCaseTrackerObject = array(); - $arrayCaseTrackerObject[] = array( - "obj_uid" => "char", - "obj_title" => "char", - "obj_description" => "char", - "obj_type" => "char" - ); - $delimiter = \DBAdapter::getStringDelimiter(); //DynaForms @@ -297,13 +290,13 @@ class CaseTracker ); } - $arrayAvailableCaseTrackerObject = \ProcessMaker\Util\ArrayUtil::sort( - $arrayAvailableCaseTrackerObject, + $arrayCaseTrackerObject = \ProcessMaker\Util\ArrayUtil::sort( + $arrayCaseTrackerObject, array("obj_type", "obj_title"), SORT_ASC ); - return $arrayAvailableCaseTrackerObject; + return $arrayCaseTrackerObject; } catch (\Exception $e) { throw $e; } @@ -390,8 +383,6 @@ class CaseTracker ); } - //Set data - \G::LoadClass("ArrayPeer"); $arraydbCaseTrackerObject = \ProcessMaker\Util\ArrayUtil::sort($arraydbCaseTrackerObject, array("cto_position"), SORT_ASC); return $arrayCaseTrackerObject; diff --git a/workflow/engine/src/BusinessModel/WebEntry.php b/workflow/engine/src/BusinessModel/WebEntry.php index 1f6d20914..f0386d6f8 100644 --- a/workflow/engine/src/BusinessModel/WebEntry.php +++ b/workflow/engine/src/BusinessModel/WebEntry.php @@ -477,6 +477,11 @@ class WebEntry case "HTML": global $G_FORM; + if (! class_exists("Smarty")) { + $loader = \Maveriks\Util\ClassLoader::getInstance(); + $loader->addClass("Smarty", PATH_THIRDPARTY . "smarty".PATH_SEP."libs".PATH_SEP."Smarty.class.php"); + } + $G_FORM = new \Form($processUid . "/" . $dynaFormUid, PATH_DYNAFORM, SYS_LANG, false); $G_FORM->action = $http . $_SERVER["HTTP_HOST"] . "/sys" . SYS_SYS . "/" . SYS_LANG . "/" . SYS_SKIN . "/services/cases_StartExternal.php"; diff --git a/workflow/public_html/sysGeneric.php b/workflow/public_html/sysGeneric.php index 7e7079375..3f98d190d 100755 --- a/workflow/public_html/sysGeneric.php +++ b/workflow/public_html/sysGeneric.php @@ -27,7 +27,6 @@ * this file is used initialize main variables, redirect and dispatch all requests */ - function transactionLog($transactionName){ if (extension_loaded('newrelic')) { $baseName="ProcessMaker"; @@ -609,12 +608,13 @@ Bootstrap::LoadClass( 'plugin' ); //here we are loading all plugins registered //the singleton has a list of enabled plugins $sSerializedFile = PATH_DATA_SITE . 'plugin.singleton'; -$oPluginRegistry = & PMPluginRegistry::getSingleton(); if (file_exists( $sSerializedFile )) { - $oPluginRegistry->unSerializeInstance( file_get_contents( $sSerializedFile ) ); + $oPluginRegistry = PMPluginRegistry::loadSingleton($sSerializedFile); $attributes = $oPluginRegistry->getAttributes(); Bootstrap::LoadTranslationPlugins( defined( 'SYS_LANG' ) ? SYS_LANG : "en" , $attributes); +} else{ + $oPluginRegistry = PMPluginRegistry::getSingleton(); } // setup propel definitions and logging