diff --git a/.gitignore b/.gitignore index 9ddb5993..3e610631 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ upgrade.log *.sav *~ +vendor +/src/local.* diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 00000000..162ef6f1 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,18 @@ +stages: + - tests + +tests: + image: composer + stage: tests + rules: + - changes: + - src/* + script: + - composer install + - ./vendor/bin/phpstan analyse --no-interaction --configuration=phpstan.neon --error-format=junit > tests-report.xml + artifacts: + when: always + paths: + - tests-report.xml + reports: + junit: tests-report.xml diff --git a/composer.json b/composer.json new file mode 100644 index 00000000..bbde3bbb --- /dev/null +++ b/composer.json @@ -0,0 +1,5 @@ +{ + "require-dev": { + "phpstan/phpstan": "^1.9" + } +} diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 00000000..1a8ddb38 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,22 @@ +parameters: + level: 0 + paths: + - src + excludePaths: + - src/local + - src/tmp + # Error message "Class Smarty_Resource_LdapSaisie extends unknown class Smarty_Resource_Custom." cannot be ignored, use excludePaths instead. + - src/includes/class/class.LStemplate_smarty3_support.php + ignoreErrors: + - "#Instantiated class (Smarty|Console_Table|ZxcvbnPhp\\\\Zxcvbn|phpseclib\\\\Crypt\\\\RSA|phpseclib\\\\Net\\\\SFTP|phpseclib\\\\Net\\\\SSH2|Net_FTP) not found\\.#" + - "#Call to static method (connect|isError)\\(\\) on an unknown class Net_LDAP2\\.#" + - "#Class (Net_LDAP2_Filter|Net_LDAP2_Entry|PEAR_Error) not found\\.#" + - "#Call to static method (create|parse|combine|escape)\\(\\) on an unknown class Net_LDAP2_Filter\\.#" + - "#Call to static method (createFresh)\\(\\) on an unknown class Net_LDAP2_Entry\\.#" + - "#Call to static method (forceAuthentication|getUser|logout|setDebug|client|setNoCasServerValidation|setCasServerCACert|setExtraCurlOption)\\(\\) on an unknown class phpCAS\\.#" + - + message: "#Call to static method factory\\(\\) on an unknown class Mail\\.#" + path: src/includes/addons/LSaddons.mail.php + - + message: "#Instantiated class Mail_mime not found\\.#" + path: src/includes/addons/LSaddons.mail.php diff --git a/src/conf/LSobjects/config.LSobjects.LSpeople.php b/src/conf/LSobjects/config.LSobjects.LSpeople.php index f2244681..dc54e8fd 100644 --- a/src/conf/LSobjects/config.LSobjects.LSpeople.php +++ b/src/conf/LSobjects/config.LSobjects.LSpeople.php @@ -122,10 +122,6 @@ $GLOBALS['LSobjects']['LSpeople'] = array ( ), ), - 'before_modify' => 'valid', - 'after_modify' => 'valid', - //'after_create' => 'createMaildirByFTP', - //'after_delete' => 'removeMaildirByFTP', 'display_name_format' => '%{cn}', 'label' => 'Users', diff --git a/src/includes/addons/LSaddons.orgchart.php b/src/includes/addons/LSaddons.orgchart.php index c1c47512..47a6988e 100644 --- a/src/includes/addons/LSaddons.orgchart.php +++ b/src/includes/addons/LSaddons.orgchart.php @@ -115,7 +115,7 @@ function organizationalChartData() { $parent_id_attr = LSconfig :: get('parent_id_attr', '', 'string', $conf); if ($parent_id_attr) { if (!$obj_type :: hasAttr($parent_id_attr)) - LStemplate :: fatal_error("Object '$obj_type' does not have attribute '$id_attr'."); + LStemplate :: fatal_error("Object '$obj_type' does not have attribute '$parent_id_attr'."); $requested_attrs[$obj_type][] = $parent_id_attr; } $objects_conf[$obj_type]['parent_id_attr'] = $parent_id_attr; @@ -130,7 +130,7 @@ function organizationalChartData() { foreach(getFieldInFormat($attr) as $a) { if (!$obj_type :: hasAttr($a)) LStemplate :: fatal_error("Object '$obj_type' does not have attribute '$a'."); - if (!in_array($a, $attrs)) + if (!in_array($a, $requested_attrs[$obj_type])) $requested_attrs[$obj_type][] = $a; } } @@ -276,7 +276,7 @@ function organizationalChartData() { echo json_encode( $entities, ( - $pretty || isset($_REQUEST['pretty'])? + isset($_REQUEST['pretty'])? JSON_PRETTY_PRINT: 0 ) diff --git a/src/includes/addons/LSaddons.ppolicy.php b/src/includes/addons/LSaddons.ppolicy.php index 92f00b9d..e0afbf32 100644 --- a/src/includes/addons/LSaddons.ppolicy.php +++ b/src/includes/addons/LSaddons.ppolicy.php @@ -282,7 +282,7 @@ function ppolicy_export_search_info($LSsearch, $as_csv=true, $return=false) { if ($return) return $data; header("Content-disposition: attachment; filename=ppolicy-".$LSsearch->LSobject.".json"); - displayAjaxReturn($data); + LSsession :: displayAjaxReturn($data); exit(); } @@ -330,9 +330,11 @@ function _ppolicy_write_row_in_csv(&$csv, &$row) { * @return void **/ function handle_api_LSobject_exportPpolicyInfo($request) { - get_LSobject_from_API_request($request); + $object = get_LSobject_from_API_request($request); + if (!$object) + return; $container_dn = LSconfig::get( - "LSobjects.".$LSsearch->LSobject.".container_dn", + "LSobjects.".$object->LSobject.".container_dn", "", "string"); $whoami = LSsession :: whoami( $container_dn? @@ -423,8 +425,8 @@ function cli_export_ppolicy_info($command_args) { print($data); exit(); } - $fd = fopen($output, 'w') or fatal_error("Fail to open output file '$output'"); - fwrite($fd, $data) or fatal_error("Fail to write result in output file '$output'"); + $fd = fopen($output, 'w') or LStemplate::fatal_error("Fail to open output file '$output'"); + fwrite($fd, $data) or LStemplate::fatal_error("Fail to write result in output file '$output'"); @fclose($fd); } diff --git a/src/includes/addons/LSaddons.samba.php b/src/includes/addons/LSaddons.samba.php index 2348e9eb..2bf9206d 100644 --- a/src/includes/addons/LSaddons.samba.php +++ b/src/includes/addons/LSaddons.samba.php @@ -491,7 +491,7 @@ function generate_sambaProfilePath($ldapObject) { function generate_shadowExpire_from_sambaPwdMustChange($ldapObject) { $time = $ldapObject -> getValue('sambaPwdMustChange', true, null); if ($time) - return str_val(round(int_val($time)/86400)); + return strval(round(intval($time)/86400)); return ''; } @@ -507,7 +507,7 @@ function generate_shadowExpire_from_sambaPwdMustChange($ldapObject) { function generate_timestamp_from_shadowExpire($ldapObject) { $days = $ldapObject -> getValue('shadowExpire', true, null); if ($days) - return str_val(int_val($days) * 86400); + return strval(intval($days) * 86400); return ''; } diff --git a/src/includes/addons/LSaddons.showTechInfo.php b/src/includes/addons/LSaddons.showTechInfo.php index 86f6c577..d0aea6d8 100644 --- a/src/includes/addons/LSaddons.showTechInfo.php +++ b/src/includes/addons/LSaddons.showTechInfo.php @@ -65,7 +65,6 @@ function showTechInfo($object) { 'creatorsName' => _('Creator DN'), 'modifyTimestamp' => _('Last modification date'), 'modifiersName' => _('Last modifier DN'), - 'modifiersName' => _('Last modifier DN'), 'entryCSN' => _('LDAP entry change sequence number'), 'entryUUID' => _('LDAP entry UUID'), 'hasSubordinates' => _('LDAP entry has children'), diff --git a/src/includes/addons/LSaddons.supann.php b/src/includes/addons/LSaddons.supann.php index fc7782f4..7479078d 100644 --- a/src/includes/addons/LSaddons.supann.php +++ b/src/includes/addons/LSaddons.supann.php @@ -814,6 +814,26 @@ function supannGetOIDCGenrePossibleValues($options, $name, $ldapObject) { return supannGetNomenclaturePossibleValues('oidc_genre', false); } +/** + * Détecte et alimente la liste des codes de populations dans la variable + * $GLOBALS['supannNomenclatures']['SUPANN']['codePopulation']. + * + * @param array $populations + * @param string $prefix + * @return void + */ +function supannDetectCodesPopulations($populations, $prefix="") { + if (!$populations) { + return; + } + foreach($populations as $letter => $infos) { + $code = "$prefix$letter"; + if (isset($infos['label'])) + $GLOBALS['supannNomenclatures']['SUPANN']['codePopulation'][$code] = $infos['label']." ($code)"; + supannDetectCodesPopulations($infos['subpopulations'], $code); + } +} + /* * Charge une nomenclature SUPANN * @@ -866,19 +886,7 @@ function supannLoadNomenclature($table) { return false; } $GLOBALS['supannNomenclatures']['SUPANN']['codePopulation'] = array(); - - function _detectCodesPopulations($populations, $prefix="") { - if (!$populations) { - return; - } - foreach($populations as $letter => $infos) { - $code = "$prefix$letter"; - if (isset($infos['label'])) - $GLOBALS['supannNomenclatures']['SUPANN']['codePopulation'][$code] = $infos['label']." ($code)"; - _detectCodesPopulations($infos['subpopulations'], $code); - } - } - _detectCodesPopulations($GLOBALS['supannPopulations']); + supannDetectCodesPopulations($GLOBALS['supannPopulations']); break; case 'etuDiplome': diff --git a/src/includes/class/class.LSattr_html_maildir.php b/src/includes/class/class.LSattr_html_maildir.php index d9292ab6..e71aa094 100644 --- a/src/includes/class/class.LSattr_html_maildir.php +++ b/src/includes/class/class.LSattr_html_maildir.php @@ -35,7 +35,7 @@ class LSattr_html_maildir extends LSattr_html { public function __construct($name, $config, &$attribute) { $attribute -> addObjectEvent('before_delete',$this,'beforeDelete'); $attribute -> addObjectEvent('after_delete',$this,'deleteMaildirByFTP'); - return parent :: __construct($name, $config, $attribute); + parent :: __construct($name, $config, $attribute); } public function doOnModify($action,$cur,$new) { diff --git a/src/includes/class/class.LSattr_html_select_list.php b/src/includes/class/class.LSattr_html_select_list.php index e42987b1..f83fbbab 100644 --- a/src/includes/class/class.LSattr_html_select_list.php +++ b/src/includes/class/class.LSattr_html_select_list.php @@ -309,7 +309,7 @@ class LSattr_html_select_list extends LSattr_html{ * @retval array Tableau associatif des valeurs possible de la liste avec en clé * la valeur des balises option et en valeur ce qui sera affiché. */ - protected function getLSattributePossibleValues($attr, $options ,$name ,&$ldapObject) { + protected static function getLSattributePossibleValues($attr, $options ,$name ,&$ldapObject) { $retInfos=array(); if (is_string($attr)) { if (isset($ldapObject->attrs[$attr]) && $ldapObject->attrs[$attr] instanceof LSattribute) { @@ -410,7 +410,7 @@ class LSattr_html_select_list extends LSattr_html{ ); } catch (Exception $er) { - self :: log_exception($er, strval($this)." -> _getPossibleValues(): exception occured running ".format_callable($get_possible_values)); + self :: log_exception($er, get_called_class()." -> _getPossibleValues(): exception occured running ".format_callable($get_possible_values)); $retInfos = null; } diff --git a/src/includes/class/class.LSattr_ldap_password.php b/src/includes/class/class.LSattr_ldap_password.php index 9fc0a617..cbc26def 100644 --- a/src/includes/class/class.LSattr_ldap_password.php +++ b/src/includes/class/class.LSattr_ldap_password.php @@ -188,7 +188,7 @@ class LSattr_ldap_password extends LSattr_ldap { if( function_exists( 'mhash' ) && function_exists( 'mhash_keygen_s2k' ) ) { mt_srand( (double) microtime() * 1000000 ); if (is_null($salt)) - $salt = mhash_keygen_s2k( MHASH_MD5, $password_clear, substr( pack( "h*", md5( mt_rand() ) ), 0, 8 ), 4 ); + $salt = mhash_keygen_s2k( MHASH_MD5, $clearPassword, substr( pack( "h*", md5( mt_rand() ) ), 0, 8 ), 4 ); return "{SMD5}".base64_encode( mhash( MHASH_MD5, $clearPassword.$salt ).$salt ); } else { diff --git a/src/includes/class/class.LSauthMethod.php b/src/includes/class/class.LSauthMethod.php index 3453b2ed..03dcb4a0 100644 --- a/src/includes/class/class.LSauthMethod.php +++ b/src/includes/class/class.LSauthMethod.php @@ -41,7 +41,6 @@ class LSauthMethod extends LSlog_staticLoggerClass { self :: log_debug(get_class($this)." :: __construct(): config file ($conf_file) loaded"); else self :: log_debug(get_class($this)." :: __construct(): config file ($conf_file) not found"); - return true; } /** @@ -69,7 +68,7 @@ class LSauthMethod extends LSlog_staticLoggerClass { self :: log_debug("No user found for provided username '".$this -> authData['username']."'"); return false; } - + if (count($authobjects) > 1) { self :: log_debug('Multiple users match with provided username: '.implode(', ', array_keys($authobjects))); LSerror :: addErrorCode('LSauth_02'); diff --git a/src/includes/class/class.LSauthMethod_CAS.php b/src/includes/class/class.LSauthMethod_CAS.php index b5791946..32bb080a 100644 --- a/src/includes/class/class.LSauthMethod_CAS.php +++ b/src/includes/class/class.LSauthMethod_CAS.php @@ -33,8 +33,7 @@ class LSauthMethod_CAS extends LSauthMethod { public function __construct() { LSauth :: disableLoginForm(); - if (!parent :: __construct()) - return; + parent :: __construct(); if (LSsession :: includeFile(PHP_CAS_PATH, true)) { if (defined('PHP_CAS_DEBUG_FILE')) { @@ -67,7 +66,7 @@ class LSauthMethod_CAS extends LSauthMethod { // Check CAS server SSL validation is now configured if (!$cas_server_ssl_validation_configured) { LSerror :: addErrorCode('LSauthMethod_CAS_02'); - return false; + return; } if (defined('LSAUTH_CAS_CURL_SSLVERION')) { @@ -82,12 +81,10 @@ class LSauthMethod_CAS extends LSauthMethod { // Set configured flag $this -> configured = true; - return true; } else { LSerror :: addErrorCode('LSauthMethod_CAS_01'); } - return false; } /** diff --git a/src/includes/class/class.LSauthMethod_HTTP.php b/src/includes/class/class.LSauthMethod_HTTP.php index f215f85b..ba0215c1 100644 --- a/src/includes/class/class.LSauthMethod_HTTP.php +++ b/src/includes/class/class.LSauthMethod_HTTP.php @@ -37,7 +37,6 @@ class LSauthMethod_HTTP extends LSauthMethod_basic { LSauth :: disableLoginForm(); if (!defined('LSAUTHMETHOD_HTTP_LOGOUT_REMOTE_URL')) LSauth :: disableLogoutBtn(); - return True; } /** diff --git a/src/includes/class/class.LSauthMethod_anonymous.php b/src/includes/class/class.LSauthMethod_anonymous.php index 7e34e534..48ef6bdb 100644 --- a/src/includes/class/class.LSauthMethod_anonymous.php +++ b/src/includes/class/class.LSauthMethod_anonymous.php @@ -34,8 +34,7 @@ class LSauthMethod_anonymous extends LSauthMethod { LSauth :: disableLoginForm(); LSauth :: disableSelfAccess(); - if (!parent :: __construct()) - return; + parent :: __construct(); if ( (!defined('LSAUTHMETHOD_ANONYMOUS_DISABLE_LOGOUT')) || (constant('LSAUTHMETHOD_ANONYMOUS_DISABLE_LOGOUT') === True)) { self :: log_debug('logout : '.constant('LSAUTHMETHOD_ANONYMOUS_DISABLE_LOGOUT')); @@ -46,7 +45,6 @@ class LSauthMethod_anonymous extends LSauthMethod { LSerror :: addErrorCode('LSauthMethod_anonymous_01'); return; } - return true; } /** diff --git a/src/includes/class/class.LSform.php b/src/includes/class/class.LSform.php index 48af467c..f2ff5041 100644 --- a/src/includes/class/class.LSform.php +++ b/src/includes/class/class.LSform.php @@ -55,6 +55,7 @@ class LSform extends LSlog_staticLoggerClass { var $api_mode = false; private $submited = false; + private $submit = null; /** * Constructeur @@ -528,7 +529,7 @@ class LSform extends LSlog_staticLoggerClass { } // Retrieve POST data of the element if( !($element -> getPostData($this -> _postData, $onlyIfPresent)) ) { - LSerror :: addErrorCode('LSform_02',$element_name); + LSerror :: addErrorCode('LSform_02',$elementName); return; } } diff --git a/src/includes/class/class.LSformElement.php b/src/includes/class/class.LSformElement.php index 4899f899..6f89afc3 100644 --- a/src/includes/class/class.LSformElement.php +++ b/src/includes/class/class.LSformElement.php @@ -36,6 +36,7 @@ class LSformElement extends LSlog_staticLoggerClass { var $label; var $params; var $values = array(); + var $form = null; var $_required = false; var $_freeze = false; var $attr_html; diff --git a/src/includes/class/class.LSformElement_maildir.php b/src/includes/class/class.LSformElement_maildir.php index e32ab525..ecf3c626 100644 --- a/src/includes/class/class.LSformElement_maildir.php +++ b/src/includes/class/class.LSformElement_maildir.php @@ -71,7 +71,7 @@ class LSformElement_maildir extends LSformElement_text { 'nodo' => _("Click to enable maildir creation/modification on user creation/modification.") ) ); - return parent :: getDisplay($return); + return parent :: getDisplay(); } /** diff --git a/src/includes/class/class.LSformElement_rss.php b/src/includes/class/class.LSformElement_rss.php index 485b9fb7..bcc996f4 100644 --- a/src/includes/class/class.LSformElement_rss.php +++ b/src/includes/class/class.LSformElement_rss.php @@ -50,7 +50,7 @@ class LSformElement_rss extends LSformElement_text { 'display' => _("Display RSS stack.") ) ); - return parent :: getDisplay($return); + return parent :: getDisplay(); } } diff --git a/src/includes/class/class.LSformElement_supannCompositeAttribute.php b/src/includes/class/class.LSformElement_supannCompositeAttribute.php index 4de05093..3d5e0da1 100644 --- a/src/includes/class/class.LSformElement_supannCompositeAttribute.php +++ b/src/includes/class/class.LSformElement_supannCompositeAttribute.php @@ -309,7 +309,7 @@ class LSformElement_supannCompositeAttribute extends LSformElement { break; default: - self :: error('Unrecognized component type "'.$this -> components[$c]['type'].'"'); + self :: log_error('Unrecognized component type "'.$this -> components[$c]['type'].'"'); } } self :: log_debug("translateComponentValue($c, $val): ".varDump($retval)); diff --git a/src/includes/class/class.LSformElement_supannEmpProfil.php b/src/includes/class/class.LSformElement_supannEmpProfil.php index 2f07c90a..89112566 100644 --- a/src/includes/class/class.LSformElement_supannEmpProfil.php +++ b/src/includes/class/class.LSformElement_supannEmpProfil.php @@ -84,7 +84,7 @@ class LSformElement_supannEmpProfil extends LSformElement_supannCompositeAttribu 'required' => false, ), ); - return parent :: __construct($form, $name, $label, $params, $attr_html); + parent :: __construct($form, $name, $label, $params, $attr_html); } } diff --git a/src/includes/class/class.LSformElement_supannEtuInscription.php b/src/includes/class/class.LSformElement_supannEtuInscription.php index 9b925f0b..70eef6c4 100644 --- a/src/includes/class/class.LSformElement_supannEtuInscription.php +++ b/src/includes/class/class.LSformElement_supannEtuInscription.php @@ -122,7 +122,7 @@ class LSformElement_supannEtuInscription extends LSformElement_supannCompositeAt 'required' => false, ), ); - return parent :: __construct($form, $name, $label, $params, $attr_html); + parent :: __construct($form, $name, $label, $params, $attr_html); } } diff --git a/src/includes/class/class.LSformElement_supannExtProfil.php b/src/includes/class/class.LSformElement_supannExtProfil.php index f055e313..995e4d88 100644 --- a/src/includes/class/class.LSformElement_supannExtProfil.php +++ b/src/includes/class/class.LSformElement_supannExtProfil.php @@ -83,7 +83,7 @@ class LSformElement_supannExtProfil extends LSformElement_supannCompositeAttribu 'required' => false, ), ); - return parent :: __construct($form, $name, $label, $params, $attr_html); + parent :: __construct($form, $name, $label, $params, $attr_html); } } diff --git a/src/includes/class/class.LSformElement_supannRessourceEtat.php b/src/includes/class/class.LSformElement_supannRessourceEtat.php index a6a7624c..3373e1d8 100644 --- a/src/includes/class/class.LSformElement_supannRessourceEtat.php +++ b/src/includes/class/class.LSformElement_supannRessourceEtat.php @@ -58,7 +58,7 @@ class LSformElement_supannRessourceEtat extends LSformElement_supannCompositeAtt 'required' => false, ), ); - return parent :: __construct($form, $name, $label, $params, $attr_html); + parent :: __construct($form, $name, $label, $params, $attr_html); } /** @@ -91,7 +91,7 @@ class LSformElement_supannRessourceEtat extends LSformElement_supannCompositeAtt if (!$value['ressource'] || !$value['etat']) return null; $ret = "{".$value['ressource']."}".$value['etat']; - if (isset($value['sous_etat']) && !is_empty($matches['sous_etat'])) + if (isset($value['sous_etat']) && !is_empty($value['sous_etat'])) $ret .= ":".$value['sous_etat']; return $ret; } diff --git a/src/includes/class/class.LSformElement_supannRessourceEtatDate.php b/src/includes/class/class.LSformElement_supannRessourceEtatDate.php index afca3040..042d6143 100644 --- a/src/includes/class/class.LSformElement_supannRessourceEtatDate.php +++ b/src/includes/class/class.LSformElement_supannRessourceEtatDate.php @@ -70,7 +70,7 @@ class LSformElement_supannRessourceEtatDate extends LSformElement_supannComposit 'required' => false, ), ); - return parent :: __construct($form, $name, $label, $params, $attr_html); + parent :: __construct($form, $name, $label, $params, $attr_html); } /** diff --git a/src/includes/class/class.LSformElement_supannRoleEntite.php b/src/includes/class/class.LSformElement_supannRoleEntite.php index 014fe955..8cc0d70b 100644 --- a/src/includes/class/class.LSformElement_supannRoleEntite.php +++ b/src/includes/class/class.LSformElement_supannRoleEntite.php @@ -54,7 +54,7 @@ class LSformElement_supannRoleEntite extends LSformElement_supannCompositeAttrib 'required' => false ) ); - return parent :: __construct($form, $name, $label, $params, $attr_html); + parent :: __construct($form, $name, $label, $params, $attr_html); } } diff --git a/src/includes/class/class.LSformElement_xmpp.php b/src/includes/class/class.LSformElement_xmpp.php index d47e8d34..e7d83264 100644 --- a/src/includes/class/class.LSformElement_xmpp.php +++ b/src/includes/class/class.LSformElement_xmpp.php @@ -50,7 +50,7 @@ class LSformElement_xmpp extends LSformElement_text { 'chat' => _("Chat with this person.") ) ); - return parent :: getDisplay($return); + return parent :: getDisplay(); } } diff --git a/src/includes/class/class.LSio.php b/src/includes/class/class.LSio.php index c39572be..1894ef17 100644 --- a/src/includes/class/class.LSio.php +++ b/src/includes/class/class.LSio.php @@ -290,7 +290,9 @@ class LSio extends LSlog_staticLoggerClass { $object = new $LSobject(); if (!$object -> loadData($dn)) { self :: log_debug('import(): Failed to load data of '.$dn); - $globalErrors[] = getFData(_("Failed to load existing object %{dn} from LDAP server. Can't update object.")); + $globalErrors[] = getFData( + _("Failed to load existing object %{dn} from LDAP server. Can't update object."), + $dn); } else { // Instanciate a modify form (in API mode) @@ -585,7 +587,7 @@ class LSio extends LSlog_staticLoggerClass { $ioFormat = $command_args[$i]; } else - LScli :: usage("Invalid $arg parameter."); + LScli :: usage("Invalid ".$command_args[$i]." parameter."); } } diff --git a/src/includes/class/class.LSioFormatCSV.php b/src/includes/class/class.LSioFormatCSV.php index 5adea46a..8b7f529a 100644 --- a/src/includes/class/class.LSioFormatCSV.php +++ b/src/includes/class/class.LSioFormatCSV.php @@ -33,6 +33,7 @@ class LSioFormatCSV extends LSioFormatDriver { private $enclosure = null; private $escape = null; private $length = null; + private $multiple_value_delimiter = null; private $rows = null; private $headers = null; diff --git a/src/includes/class/class.LSlang.php b/src/includes/class/class.LSlang.php index 7499204c..799893bc 100644 --- a/src/includes/class/class.LSlang.php +++ b/src/includes/class/class.LSlang.php @@ -231,10 +231,360 @@ if (php_sapi_name() != "cli") return true; * * @retval boolean True on success, false otherwise **/ - global $LSlang_cli_logger, $available_onlys, $available_withouts; +global $LSlang_cli_logger, $available_onlys, $available_withouts; - $available_onlys = array("config", "templates", "addons", "auth_methods", "includes"); - $available_withouts = array_merge($available_onlys, array("select-list")); +function _cli_relative2absolute_path($path) { + if ($path[0] == '/') + return $path; + global $curdir; + return realpath($curdir)."/".$path; +} + +function _cli_absolute2relative_path($path) { + if ($path[0] == '/') + $path = realpath($path); + if (substr($path, 0, strlen(LS_ROOT_DIR)) == LS_ROOT_DIR) + return substr($path, strlen(LS_ROOT_DIR)+1); + return $path; +} + +function _cli_interactive_ask($context, $msg) { + global $copyoriginalvalue, $interactive_exit; + + if ($interactive_exit) { + if ($copyoriginalvalue) + return $msg; + return true; + } + + // Format question + $empty_action = ($copyoriginalvalue?'copy original message':'pass'); + $question ="\"$msg\"\n\n => Please enter translated string"; + $question .= " (i"; + if (!$copyoriginalvalue) + $question .= "/c"; + $question .= "/q/? or leave empty to $empty_action): "; + + while (true) { + if ($context) + fwrite(STDERR, "\n# $context\n"); + fwrite(STDERR, $question); + $in = trim(fgets(STDIN)); + switch($in) { + case 'q': // Exit interactive mode + case 'Q': + $interactive_exit = true; + return True; + case 'i': // Ignore + case 'I': + return True; + case 'c': + case 'C': // Copy + if (!$copyoriginalvalue) + return $msg; + case '?': // Help message + fwrite(STDERR, "Available choices:\n"); + fwrite(STDERR, " - i: ignore this message\n"); + if (!$copyoriginalvalue) + fwrite(STDERR, " - c: copy original message\n"); + fwrite(STDERR, " - q: quit interactive mode and ignore all following untranslated messages\n"); + fwrite(STDERR, " - ?: Show this message\n"); + fwrite(STDERR, "Or leave empty to $empty_action.\n"); + break; + case "": // Empty + // On copy orignal value mode, return $msg + if ($copyoriginalvalue) + return $msg; + // Otherwise, leave translation empty + return ""; + default: + // Return user input + return $in; + } + } + // Supposed to never happen + return true; +} + +function _cli_add_str_to_translate($msg, $context=null) { + global $LSlang_cli_logger, $lang, $data, $translations, $interactive, $interactive_exit, $copyoriginalvalue, $format; + $LSlang_cli_logger -> trace("_cli_add_str_to_translate($msg, $context)"); + if ($msg == '') + return; + if (!is_null($lang) && _($msg) != "$msg") + return; + + // Message already exists ? + if (array_key_exists($msg, $data)) { + if ($context && !in_array($context, $data[$msg]['contexts'])) + $data[$msg]['contexts'][] = $context; + return True; + } + + // Handle translation + $translation = ""; + if (array_key_exists($msg, $translations)) { + $translation = $translations[$msg]; + } + elseif (!is_null($lang) && _($msg) != $msg) { + $translation = _($msg); + } + elseif ($interactive && $format != 'pot') { + $translation = _cli_interactive_ask($context, $msg); + if (!is_string($translation)) + return true; + } + $data[$msg] = array ( + 'translation' => $translation, + 'contexts' => ($context?array($context):array()), + ); +} + +function _cli_add_str_to_translate_from_LSconfig($pattern, $value='value', $excludes=array()) { + global $LSlang_cli_logger; + $LSlang_cli_logger -> trace("_cli_add_str_to_translate_from_LSconfig($pattern, array(".implode(',', $excludes)."))"); + $keys = LSconfig :: getMatchingKeys($pattern); + $LSlang_cli_logger -> trace("addFromLSconfig : ".count($keys)." matching key(s)"); + foreach ($keys as $key => $value) { + $LSlang_cli_logger -> trace("addFromLSconfig : $key = ".varDump($value)); + if ($value == 'key') { + // Get the last key parts as value and all other as key + $key_parts = explode('.', $key); + $value = $key_parts[count($key_parts)-1]; + $key = implode('.', array_slice($key_parts, 0, count($key_parts)-1)); + } + if (!in_array($value, $excludes) && is_string($value)) + _cli_add_str_to_translate($value, $key); + } +} + +function _cli_add_possible_values_from_LSconfig($context, $withouts, $level=0) { + global $LSlang_cli_logger; + $LSlang_cli_logger -> trace("_cli_add_possible_values_from_LSconfig($context)"); + if (in_array('select-list', $withouts)) + return true; + if (!LSconfig :: get("$context.translate_labels", True, "bool")) + return true; + foreach(LSconfig :: get("$context.possible_values", array()) as $pkey => $plabel) { + if (is_array($plabel)) { + // Sub possible values + // Check level + if ($level > 1) { + $LSlang_cli_logger -> warning( + "_cli_add_possible_values_from_LSconfig($context): Level to hight to handle sub possible values of $context.possible_values.$pkey" + ); + return true; + } + _cli_add_str_to_translate_from_LSconfig("$context.possible_values.$pkey.label"); + $LSlang_cli_logger -> trace("_cli_add_possible_values_from_LSconfig($context): handle sub possible values of $context.possible_values.$pkey"); + _cli_add_possible_values_from_LSconfig("$context.possible_values.$pkey", $withouts, $level+1); + } + else { + switch ($pkey) { + case 'OTHER_OBJECT': + $LSlang_cli_logger -> trace("_cli_add_possible_values_from_LSconfig($context): ignore $context.possible_values.$pkey (OTHER_OBJECT)"); + break; + case 'OTHER_ATTRIBUTE': + if (is_array($plabel)) { + if (isset($plabel['json_component_key'])) + _cli_add_str_to_translate_from_LSconfig("$context.possible_values.OTHER_ATTRIBUTE.json_component_label"); + else + _cli_add_str_to_translate_from_LSconfig("$context.possible_values.OTHER_ATTRIBUTE.*"); + } + else { + $LSlang_cli_logger -> warning("_cli_add_possible_values_from_LSconfig($context): invalid $context.possible_values.OTHER_ATTRIBUTE config => Must be an array."); + } + break; + default: + _cli_add_str_to_translate($plabel, "$context.possible_values.$pkey"); + break; + } + } + } +} + +function _cli_parse_template_file($file) { + global $LSlang_cli_logger; + $LSlang_cli_logger -> debug("Looking for string to translate in '$file' template file"); + $count = 0; + foreach(file($file) as $line) { + $count ++; + if (preg_match_all('/\{ *tr +msg=["\']([^\}]+)["\'] *\}/',$line,$matches)) { + foreach($matches[1] as $t) { + $t = preg_replace('/[\'"]\|escape\:.*$/', '', $t); + $LSlang_cli_logger -> trace(" - \"$t\" # Line $count"); + _cli_add_str_to_translate($t, _cli_absolute2relative_path($file).":$count"); + } + } + } + $LSlang_cli_logger -> trace("_cli_parse_template_file($file) : done."); +} + +function _cli_find_and_parse_template_file($dir) { + if (is_dir($dir)) { + if ($dh = opendir($dir)) { + while (($file = readdir($dh)) !== false) { + if ($file=='.' || $file=='..') continue; + if (is_dir($dir.'/'.$file)) { + _cli_find_and_parse_template_file($dir.'/'.$file); + } + elseif (is_file($dir."/".$file) && preg_match('/\.tpl$/',$file)) { + _cli_parse_template_file($dir.'/'.$file); + } + } + closedir($dh); + } + } +} + +function _cli_parse_php_file($file) { + global $LSlang_cli_logger; + $LSlang_cli_logger -> debug("Looking for string to translate in '$file' PHP file"); + $count = 0; + $quote=''; + $res=''; + foreach(file($file) as $line) { + $count++; + $LSlang_cli_logger -> trace("Handle line #$count of '$file' PHP file"); + $offset=0; + while ($pos = strpos($line,'__(',$offset)) { + $LSlang_cli_logger -> trace("$file:$count: detect keyword at position #$pos ('$line')"); + for ($i=$pos+3;$i $key_data) { + if ($copyoriginalvalue && $key_data['translation'] == "") { + $val = $key; + } + else + $val = $key_data['translation']; + $key=str_replace('"','\\"',$key); + $val=str_replace('"','\\"',$val); + foreach ($key_data['contexts'] as $context) + fwrite($fd, "\n# $context"); + if ($additionalfileformat) { + fwrite($fd, "\n\$GLOBALS['LSlang'][\"$key\"] = \"$val\";\n"); + } + else { + fwrite($fd, "\n\"$key\" =>\n \"$val\",\n"); + } + } + + // Handle keep unused mode + if ($keep_unused) { + $unused_msgs = array(); + foreach ($translations as $msg => $trans) + if (!array_key_exists($msg, $data)) + $unused_msgs[$msg] = $trans; + if ($unused_msgs) { + fwrite($fd, "\n\n"); + fwrite($fd, "######################################################################\n"); + fwrite($fd, "# Unused translations keeped #\n"); + fwrite($fd, "######################################################################\n"); + foreach($unused_msgs as $key => $val) { + $key=str_replace('"','\\"',$key); + $val=str_replace('"','\\"',$val); + if ($additionalfileformat) { + fwrite($fd, "\n\$GLOBALS['LSlang'][\"$key\"] = \"$val\";\n"); + } + else { + fwrite($fd, "\n\"$key\" =>\n \"$val\",\n"); + } + } + } + } + + if (!$additionalfileformat) fwrite($fd, "\n);\n"); +} + +function _cli_clean_for_pot_file($val) { + $val = str_replace('"', '\\"', $val); + return str_replace("\n", "\\n", $val); +} + +function _cli_output_pot($fd) { + global $LSlang_cli_logger, $data, $copyoriginalvalue; + foreach($data as $key => $key_data) { + if ($copyoriginalvalue && $key_data['translation'] == "") { + $val = $key; + } + else + $val = $key_data['translation']; + foreach ($key_data['contexts'] as $context) + fwrite($fd, "#: $context\n"); + $key = _cli_clean_for_pot_file($key); + $val = _cli_clean_for_pot_file($val); + fwrite($fd, "msgid \"$key\"\nmsgstr \"$val\"\n\n"); + } +} + +$available_onlys = array("config", "templates", "addons", "auth_methods", "includes"); +$available_withouts = array_merge($available_onlys, array("select-list")); function cli_generate_lang_file($command_args) { // Use global variables to share it with sub-functions global $LSlang_cli_logger, $available_onlys, $available_withouts, $data, $translations, $interactive, @@ -273,21 +623,6 @@ function cli_generate_lang_file($command_args) { $curdir = getcwd(); chdir(dirname(__FILE__).'/../'); - function relative2absolute_path($path) { - if ($path[0] == '/') - return $path; - global $curdir; - return realpath($curdir)."/".$path; - } - - function absolute2relative_path($path) { - if ($path[0] == '/') - $path = realpath($path); - if (substr($path, 0, strlen(LS_ROOT_DIR)) == LS_ROOT_DIR) - return substr($path, strlen(LS_ROOT_DIR)+1); - return $path; - } - for ($i=0; $i < count($command_args); $i++) { switch ($command_args[$i]) { case '--without': @@ -377,7 +712,7 @@ function cli_generate_lang_file($command_args) { break; default: - $path = relative2absolute_path($command_args[$i]); + $path = _cli_relative2absolute_path($command_args[$i]); if (is_file($path)) $load_files[] = $path; else @@ -385,115 +720,7 @@ function cli_generate_lang_file($command_args) { } } - function interactive_ask($context, $msg) { - global $copyoriginalvalue, $interactive_exit; - if ($interactive_exit) { - if ($copyoriginalvalue) - return $msg; - return true; - } - - // Format question - $empty_action = ($copyoriginalvalue?'copy original message':'pass'); - $question ="\"$msg\"\n\n => Please enter translated string"; - $question .= " (i"; - if (!$copyoriginalvalue) - $question .= "/c"; - $question .= "/q/? or leave empty to $empty_action): "; - - while (true) { - if ($context) - fwrite(STDERR, "\n# $context\n"); - fwrite(STDERR, $question); - $in = trim(fgets(STDIN)); - switch($in) { - case 'q': // Exit interactive mode - case 'Q': - $interactive_exit = true; - return True; - case 'i': // Ignore - case 'I': - return True; - case 'c': - case 'C': // Copy - if (!$copyoriginalvalue) - return $msg; - case '?': // Help message - fwrite(STDERR, "Available choices:\n"); - fwrite(STDERR, " - i: ignore this message\n"); - if (!$copyoriginalvalue) - fwrite(STDERR, " - c: copy original message\n"); - fwrite(STDERR, " - q: quit interactive mode and ignore all following untranslated messages\n"); - fwrite(STDERR, " - ?: Show this message\n"); - fwrite(STDERR, "Or leave empty to $empty_action.\n"); - break; - case "": // Empty - // On copy orignal value mode, return $msg - if ($copyoriginalvalue) - return $msg; - // Otherwise, leave translation empty - return ""; - default: - // Return user input - return $in; - } - } - // Supposed to never happen - return true; - } - - function add($msg, $context=null) { - global $LSlang_cli_logger, $lang, $data, $translations, $interactive, $interactive_exit, $copyoriginalvalue, $format; - $LSlang_cli_logger -> trace("add($msg, $context)"); - if ($msg == '') - return; - if (!is_null($lang) && _($msg) != "$msg") - return; - - // Message already exists ? - if (array_key_exists($msg, $data)) { - if ($context && !in_array($context, $data[$msg]['contexts'])) - $data[$msg]['contexts'][] = $context; - return True; - } - - // Handle translation - $translation = ""; - if (array_key_exists($msg, $translations)) { - $translation = $translations[$msg]; - } - elseif (!is_null($lang) && _($msg) != $msg) { - $translation = _($msg); - } - elseif ($interactive && $format != 'pot') { - $translation = interactive_ask($context, $msg); - if (!is_string($translation)) - return true; - } - $data[$msg] = array ( - 'translation' => $translation, - 'contexts' => ($context?array($context):array()), - ); - } - - function addFromLSconfig($pattern, $value='value', $excludes=array()) { - global $LSlang_cli_logger; - $LSlang_cli_logger -> trace("addFromLSconfig($pattern, array(".implode(',', $excludes)."))"); - $keys = LSconfig :: getMatchingKeys($pattern); - $LSlang_cli_logger -> trace("addFromLSconfig : ".count($keys)." matching key(s)"); - foreach ($keys as $key => $value) { - $LSlang_cli_logger -> trace("addFromLSconfig : $key = ".varDump($value)); - if ($value == 'key') { - // Get the last key parts as value and all other as key - $key_parts = explode('.', $key); - $value = $key_parts[count($key_parts)-1]; - $key = implode('.', array_slice($key_parts, 0, count($key_parts)-1)); - } - if (!in_array($value, $excludes) && is_string($value)) - add($value, $key); - } - } // In fix-utf8 mode, load ForceUT8/Encoding lib if ($fix_utf8) @@ -524,51 +751,6 @@ function cli_generate_lang_file($command_args) { } } - function addPossibleValuesFromLSconfig($context, $withouts, $level=0) { - global $LSlang_cli_logger; - $LSlang_cli_logger -> trace("addPossibleValuesFromLSconfig($context)"); - if (in_array('select-list', $withouts)) - return true; - if (!LSconfig :: get("$context.translate_labels", True, "bool")) - return true; - foreach(LSconfig :: get("$context.possible_values", array()) as $pkey => $plabel) { - if (is_array($plabel)) { - // Sub possible values - // Check level - if ($level > 1) { - $LSlang_cli_logger -> warning( - "addPossibleValuesFromLSconfig($context): Level to hight to handle sub possible values of $context.possible_values.$pkey" - ); - return true; - } - addFromLSconfig("$context.possible_values.$pkey.label"); - $LSlang_cli_logger -> trace("addPossibleValuesFromLSconfig($context): handle sub possible values of $context.possible_values.$pkey"); - addPossibleValuesFromLSconfig("$context.possible_values.$pkey", $withouts, $level+1); - } - else { - switch ($pkey) { - case 'OTHER_OBJECT': - $LSlang_cli_logger -> trace("addPossibleValuesFromLSconfig($context): ignore $context.possible_values.$pkey (OTHER_OBJECT)"); - break; - case 'OTHER_ATTRIBUTE': - if (is_array($plabel)) { - if (isset($plabel['json_component_key'])) - addFromLSconfig("$context.possible_values.OTHER_ATTRIBUTE.json_component_label"); - else - addFromLSconfig("$context.possible_values.OTHER_ATTRIBUTE.*"); - } - else { - $LSlang_cli_logger -> warning("addPossibleValuesFromLSconfig($context): invalid $context.possible_values.OTHER_ATTRIBUTE config => Must be an array."); - } - break; - default: - add($plabel, "$context.possible_values.$pkey"); - break; - } - } - } - } - /* * Manage configuration parameters */ @@ -578,14 +760,14 @@ function cli_generate_lang_file($command_args) { $LSlang_cli_logger -> info("Looking for string to translate configuration of LDAP servers"); foreach(LSconfig :: keys('ldap_servers') as $ldap_server_id) { $LSlang_cli_logger -> debug("Looking for string to translate configuration of LDAP server #$ldap_server_id"); - addFromLSconfig("ldap_servers.$ldap_server_id.name"); - addFromLSconfig("ldap_servers.$ldap_server_id.subDnLabel"); - addFromLSconfig("ldap_servers.$ldap_server_id.recoverPassword.recoveryHashMail.subject"); - addFromLSconfig("ldap_servers.$ldap_server_id.recoverPassword.recoveryHashMail.msg"); - addFromLSconfig("ldap_servers.$ldap_server_id.recoverPassword.newPasswordMail.subject"); - addFromLSconfig("ldap_servers.$ldap_server_id.recoverPassword.newPasswordMail.msg"); - addFromLSconfig("ldap_servers.$ldap_server_id.subDn.*", 'key', array("LSobject")); - addFromLSconfig("ldap_servers.$ldap_server_id.LSprofiles.*.label"); + _cli_add_str_to_translate_from_LSconfig("ldap_servers.$ldap_server_id.name"); + _cli_add_str_to_translate_from_LSconfig("ldap_servers.$ldap_server_id.subDnLabel"); + _cli_add_str_to_translate_from_LSconfig("ldap_servers.$ldap_server_id.recoverPassword.recoveryHashMail.subject"); + _cli_add_str_to_translate_from_LSconfig("ldap_servers.$ldap_server_id.recoverPassword.recoveryHashMail.msg"); + _cli_add_str_to_translate_from_LSconfig("ldap_servers.$ldap_server_id.recoverPassword.newPasswordMail.subject"); + _cli_add_str_to_translate_from_LSconfig("ldap_servers.$ldap_server_id.recoverPassword.newPasswordMail.msg"); + _cli_add_str_to_translate_from_LSconfig("ldap_servers.$ldap_server_id.subDn.*", 'key', array("LSobject")); + _cli_add_str_to_translate_from_LSconfig("ldap_servers.$ldap_server_id.LSprofiles.*.label"); // LSaccess foreach (LSconfig :: get("ldap_servers.$ldap_server_id.LSaccess", array()) as $LSobject) { @@ -606,76 +788,76 @@ function cli_generate_lang_file($command_args) { // LSobject foreach($objects as $obj) { $LSlang_cli_logger -> info("Looking for string to translate configuration of object type $obj"); - addFromLSconfig("LSobjects.$obj.label"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.label"); // LSrelation - addFromLSconfig("LSobjects.$obj.LSrelation.*.label"); - addFromLSconfig("LSobjects.$obj.LSrelation.*.emptyText"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.LSrelation.*.label"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.LSrelation.*.emptyText"); // Custom Actions - addFromLSconfig("LSobjects.$obj.customActions.*.label"); - addFromLSconfig("LSobjects.$obj.customActions.*.helpInfo"); - addFromLSconfig("LSobjects.$obj.customActions.*.question_format"); - addFromLSconfig("LSobjects.$obj.customActions.*.onSuccessMsgFormat"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.customActions.*.label"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.customActions.*.helpInfo"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.customActions.*.question_format"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.customActions.*.onSuccessMsgFormat"); // LSform - addFromLSconfig("LSobjects.$obj.LSform.layout.*.label"); - addFromLSconfig("LSobjects.$obj.LSform.dataEntryForm.*.label"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.LSform.layout.*.label"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.LSform.dataEntryForm.*.label"); // LSsearch - addFromLSconfig("LSobjects.$obj.LSsearch.predefinedFilters.*"); - addFromLSconfig("LSobjects.$obj.LSsearch.extraDisplayedColumns.*.label"); - addFromLSconfig("LSobjects.$obj.LSsearch.extraDisplayedColumns.*.LSformat"); - addFromLSconfig("LSobjects.$obj.LSsearch.extraDisplayedColumns.*.alternativeLSformats.*"); - addFromLSconfig("LSobjects.$obj.LSsearch.extraDisplayedColumns.*.formaterLSformat"); - addFromLSconfig("LSobjects.$obj.LSsearch.customActions.*.label"); - addFromLSconfig("LSobjects.$obj.LSsearch.customActions.*.question_format"); - addFromLSconfig("LSobjects.$obj.LSsearch.customActions.*.onSuccessMsgFormat"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.LSsearch.predefinedFilters.*"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.LSsearch.extraDisplayedColumns.*.label"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.LSsearch.extraDisplayedColumns.*.LSformat"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.LSsearch.extraDisplayedColumns.*.alternativeLSformats.*"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.LSsearch.extraDisplayedColumns.*.formaterLSformat"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.LSsearch.customActions.*.label"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.LSsearch.customActions.*.question_format"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.LSsearch.customActions.*.onSuccessMsgFormat"); // Attributes foreach(LSconfig :: keys("LSobjects.$obj.attrs") as $attr) { - addFromLSconfig("LSobjects.$obj.attrs.$attr.label"); - addFromLSconfig("LSobjects.$obj.attrs.$attr.help_info"); - addFromLSconfig("LSobjects.$obj.attrs.$attr.no_value_label"); - addFromLSconfig("LSobjects.$obj.attrs.$attr.check_data.*.msg"); - addFromLSconfig("LSobjects.$obj.attrs.$attr.validation.*.msg"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.attrs.$attr.label"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.attrs.$attr.help_info"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.attrs.$attr.no_value_label"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.attrs.$attr.check_data.*.msg"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.attrs.$attr.validation.*.msg"); // HTML Options $html_type = LSconfig :: get("LSobjects.$obj.attrs.$attr.html_type"); switch($html_type) { case 'boolean': - addFromLSconfig("LSobjects.$obj.attrs.$attr.html_options.true_label"); - addFromLSconfig("LSobjects.$obj.attrs.$attr.html_options.false_label"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.attrs.$attr.html_options.true_label"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.attrs.$attr.html_options.false_label"); break; case 'jsonCompositeAttribute': $components = LSconfig :: keys("LSobjects.$obj.attrs.$attr.html_options.components"); foreach($components as $c) { - addFromLSconfig("LSobjects.$obj.attrs.$attr.html_options.components.$c.label"); - addFromLSconfig("LSobjects.$obj.attrs.$attr.html_options.components.$c.help_info"); - addFromLSconfig("LSobjects.$obj.attrs.$attr.html_options.components.$c.check_data.*.msg"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.attrs.$attr.html_options.components.$c.label"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.attrs.$attr.html_options.components.$c.help_info"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.attrs.$attr.html_options.components.$c.check_data.*.msg"); if (LSconfig :: get("LSobjects.$obj.attrs.$attr.html_options.components.$c.type") == 'select_list') - addPossibleValuesFromLSconfig("LSobjects.$obj.attrs.$attr.html_options.components.$c.options", $withouts); + _cli_add_possible_values_from_LSconfig("LSobjects.$obj.attrs.$attr.html_options.components.$c.options", $withouts); } break; case 'labeledValue': if (LSconfig :: get("LSobjects.$obj.attrs.$attr.html_options.translate_labels", True, "bool")) - addFromLSconfig("LSobjects.$obj.attrs.$attr.html_options.labels.*"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.attrs.$attr.html_options.labels.*"); break; case 'password': - addFromLSconfig("LSobjects.$obj.attrs.$attr.html_options.mail.subject"); - addFromLSconfig("LSobjects.$obj.attrs.$attr.html_options.mail.msg"); - addFromLSconfig("LSobjects.$obj.attrs.$attr.html_options.confirmChangeQuestion"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.attrs.$attr.html_options.mail.subject"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.attrs.$attr.html_options.mail.msg"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.attrs.$attr.html_options.confirmChangeQuestion"); break; case 'select_list': case 'select_box': - addPossibleValuesFromLSconfig("LSobjects.$obj.attrs.$attr.html_options", $withouts); + _cli_add_possible_values_from_LSconfig("LSobjects.$obj.attrs.$attr.html_options", $withouts); break; case 'valueWithUnit': - addFromLSconfig("LSobjects.$obj.attrs.$attr.html_options.units.*"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.attrs.$attr.html_options.units.*"); break; case 'date': - addFromLSconfig("LSobjects.$obj.attrs.$attr.html_options.special_values.*"); + _cli_add_str_to_translate_from_LSconfig("LSobjects.$obj.attrs.$attr.html_options.special_values.*"); break; } } @@ -686,151 +868,39 @@ function cli_generate_lang_file($command_args) { * Manage template file */ if (!in_array('templates', $withouts) && (!$only || $only == 'templates')) { - function parse_template_file($file) { - global $LSlang_cli_logger; - $LSlang_cli_logger -> debug("Looking for string to translate in '$file' template file"); - $count = 0; - foreach(file($file) as $line) { - $count ++; - if (preg_match_all('/\{ *tr +msg=["\']([^\}]+)["\'] *\}/',$line,$matches)) { - foreach($matches[1] as $t) { - $t = preg_replace('/[\'"]\|escape\:.*$/', '', $t); - $LSlang_cli_logger -> trace(" - \"$t\" # Line $count"); - add($t, absolute2relative_path($file).":$count"); - } - } - } - $LSlang_cli_logger -> trace("parse_template_file($file) : done."); - } - - function find_and_parse_template_file($dir) { - if (is_dir($dir)) { - if ($dh = opendir($dir)) { - while (($file = readdir($dh)) !== false) { - if ($file=='.' || $file=='..') continue; - if (is_dir($dir.'/'.$file)) { - find_and_parse_template_file($dir.'/'.$file); - } - elseif (is_file($dir."/".$file) && preg_match('/\.tpl$/',$file)) { - parse_template_file($dir.'/'.$file); - } - } - closedir($dh); - } - } - } $LSlang_cli_logger -> info("Looking for string to translate in templates file"); - if ($include_upstream) find_and_parse_template_file(LS_ROOT_DIR.'/'.LS_TEMPLATES_DIR); - find_and_parse_template_file(LS_ROOT_DIR.'/'.LS_LOCAL_DIR.LS_TEMPLATES_DIR); + if ($include_upstream) _cli_find_and_parse_template_file(LS_ROOT_DIR.'/'.LS_TEMPLATES_DIR); + _cli_find_and_parse_template_file(LS_ROOT_DIR.'/'.LS_LOCAL_DIR.LS_TEMPLATES_DIR); } /* * Manage custom PHP code/config files */ - function parse_php_file($file) { - global $LSlang_cli_logger; - $LSlang_cli_logger -> debug("Looking for string to translate in '$file' PHP file"); - $count = 0; - $quote=''; - $res=''; - foreach(file($file) as $line) { - $count++; - $LSlang_cli_logger -> trace("Handle line #$count of '$file' PHP file"); - $offset=0; - while ($pos = strpos($line,'__(',$offset)) { - $LSlang_cli_logger -> trace("$file:$count: detect keyword at position #$pos ('$line')"); - for ($i=$pos+3;$i info("Looking for string to translate in LSaddons PHP code"); - if ($include_upstream) find_and_parse_php_file(LS_ROOT_DIR.'/'.LS_ADDONS_DIR, '/^LSaddons\.(.+)\.php$/'); - find_and_parse_php_file(LS_ROOT_DIR.'/'.LS_LOCAL_DIR.LS_ADDONS_DIR, '/^LSaddons\.(.+)\.php$/'); + if ($include_upstream) _cli_find_and_parse_php_file(LS_ROOT_DIR.'/'.LS_ADDONS_DIR, '/^LSaddons\.(.+)\.php$/'); + _cli_find_and_parse_php_file(LS_ROOT_DIR.'/'.LS_LOCAL_DIR.LS_ADDONS_DIR, '/^LSaddons\.(.+)\.php$/'); $LSlang_cli_logger -> info("Looking for string to translate in LSaddons configuration files"); - if ($include_upstream) find_and_parse_php_file(LS_ROOT_DIR.'/'.LS_CONF_DIR.'/LSaddons', '/^config\.LSaddons\.(.+)\.php$$/'); - find_and_parse_php_file(LS_ROOT_DIR.'/'.LS_LOCAL_DIR.LS_CONF_DIR.'/LSaddons', '/^config\.LSaddons\.(.+)\.php$$/'); + if ($include_upstream) _cli_find_and_parse_php_file(LS_ROOT_DIR.'/'.LS_CONF_DIR.'/LSaddons', '/^config\.LSaddons\.(.+)\.php$$/'); + _cli_find_and_parse_php_file(LS_ROOT_DIR.'/'.LS_LOCAL_DIR.LS_CONF_DIR.'/LSaddons', '/^config\.LSaddons\.(.+)\.php$$/'); } - /* - * Manage auth methods files - */ + // Manage auth methods files if (!in_array('auth_methods', $withouts) && (!$only || $only == 'auth_methods')) { $LSlang_cli_logger -> info("Looking for string to translate in LSauthMethods configuration files"); - if ($include_upstream) find_and_parse_php_file(LS_ROOT_DIR.'/'.LS_CONF_DIR.'/LSauth', '/^config\.(.+)\.php$$/'); - find_and_parse_php_file(LS_ROOT_DIR.'/'.LS_LOCAL_DIR.LS_CONF_DIR.'/LSauth', '/^config\.(.+)\.php$$/'); + if ($include_upstream) _cli_find_and_parse_php_file(LS_ROOT_DIR.'/'.LS_CONF_DIR.'/LSauth', '/^config\.(.+)\.php$$/'); + _cli_find_and_parse_php_file(LS_ROOT_DIR.'/'.LS_LOCAL_DIR.LS_CONF_DIR.'/LSauth', '/^config\.(.+)\.php$$/'); } // Sort resulting strings @@ -839,81 +909,10 @@ function cli_generate_lang_file($command_args) { /* * Handle output file format */ - function output_php($fd) { - global $LSlang_cli_logger, $additionalfileformat, $data, $copyoriginalvalue, $keep_unused, $translations; - fwrite($fd, " $key_data) { - if ($copyoriginalvalue && $key_data['translation'] == "") { - $val = $key; - } - else - $val = $key_data['translation']; - $key=str_replace('"','\\"',$key); - $val=str_replace('"','\\"',$val); - foreach ($key_data['contexts'] as $context) - fwrite($fd, "\n# $context"); - if ($additionalfileformat) { - fwrite($fd, "\n\$GLOBALS['LSlang'][\"$key\"] = \"$val\";\n"); - } - else { - fwrite($fd, "\n\"$key\" =>\n \"$val\",\n"); - } - } - - // Handle keep unused mode - if ($keep_unused) { - $unused_msgs = array(); - foreach ($translations as $msg => $trans) - if (!array_key_exists($msg, $data)) - $unused_msgs[$msg] = $trans; - if ($unused_msgs) { - fwrite($fd, "\n\n"); - fwrite($fd, "######################################################################\n"); - fwrite($fd, "# Unused translations keeped #\n"); - fwrite($fd, "######################################################################\n"); - foreach($unused_msgs as $key => $val) { - $key=str_replace('"','\\"',$key); - $val=str_replace('"','\\"',$val); - if ($additionalfileformat) { - fwrite($fd, "\n\$GLOBALS['LSlang'][\"$key\"] = \"$val\";\n"); - } - else { - fwrite($fd, "\n\"$key\" =>\n \"$val\",\n"); - } - } - } - } - - if (!$additionalfileformat) fwrite($fd, "\n);\n"); - } - - function clean_for_pot_file($val) { - $val = str_replace('"', '\\"', $val); - return str_replace("\n", "\\n", $val); - } - - function output_pot($fd) { - global $LSlang_cli_logger, $data, $copyoriginalvalue; - foreach($data as $key => $key_data) { - if ($copyoriginalvalue && $key_data['translation'] == "") { - $val = $key; - } - else - $val = $key_data['translation']; - foreach ($key_data['contexts'] as $context) - fwrite($fd, "#: $context\n"); - $key = clean_for_pot_file($key); - $val = clean_for_pot_file($val); - fwrite($fd, "msgid \"$key\"\nmsgstr \"$val\"\n\n"); - } - } // Determine where to write result if ($output) { - $output = relative2absolute_path($output); + $output = _cli_relative2absolute_path($output); $LSlang_cli_logger -> info("Write result in output file ($output)"); try { $LSlang_cli_logger -> debug("Open output file ($output)"); @@ -935,11 +934,11 @@ function cli_generate_lang_file($command_args) { $LSlang_cli_logger -> debug("Output format : $format"); switch($format) { case 'pot': - output_pot($fd); + _cli_output_pot($fd); break; case 'php': default: - output_php($fd); + _cli_output_php($fd); break; } diff --git a/src/includes/class/class.LSldapObject.php b/src/includes/class/class.LSldapObject.php index 6296fafd..8d66e03e 100644 --- a/src/includes/class/class.LSldapObject.php +++ b/src/includes/class/class.LSldapObject.php @@ -2329,7 +2329,7 @@ class LSldapObject extends LSlog_staticLoggerClass { } if ($confirm) { - $obj -> _cli_show($raw_values); + $obj -> _cli_show(); // Sure ? if (!LScli :: confirm("\nAre you sure you want to delete this object?")) return True; diff --git a/src/includes/class/class.LSlog_handler.php b/src/includes/class/class.LSlog_handler.php index 5e52e6af..448e26d6 100644 --- a/src/includes/class/class.LSlog_handler.php +++ b/src/includes/class/class.LSlog_handler.php @@ -237,7 +237,7 @@ class LSlog_handler extends LSlog_staticLoggerClass { if (isset(LSsession :: $ldapServer['name'])) return LSsession :: $ldapServer['name']; else - return "#".LSsession :: $ldapServerId; + return "#".LSsession :: get('ldap_server_id'); } return "Not connected"; } diff --git a/src/includes/class/class.LSsearch.php b/src/includes/class/class.LSsearch.php index e4238e0d..5263489a 100644 --- a/src/includes/class/class.LSsearch.php +++ b/src/includes/class/class.LSsearch.php @@ -135,7 +135,7 @@ class LSsearch extends LSlog_staticLoggerClass { foreach($this -> config['predefinedFilters'] as $filter => $label) { if(!LSldap::isValidFilter($filter)) { LSerror::addErrorCode('LSsearch_15',array('label' => $label, 'filter' => $filter, 'type' => $this -> LSobject)); - unset($this -> config['predefinedFilters'][$key]); + unset($this -> config['predefinedFilters'][$filter]); } } } @@ -1049,7 +1049,7 @@ class LSsearch extends LSlog_staticLoggerClass { } if (!$searchParams) return false; - if ($searchParams['filter'] instanceof Net_LDAP_Filter) { + if ($searchParams['filter'] instanceof Net_LDAP2_Filter) { $searchParams['filter'] = $searchParams['filter'] -> asString(); } $to_hash = print_r($searchParams, true); diff --git a/src/includes/class/class.LSsession.php b/src/includes/class/class.LSsession.php index 3f3847a4..09e2b16b 100644 --- a/src/includes/class/class.LSsession.php +++ b/src/includes/class/class.LSsession.php @@ -140,6 +140,8 @@ class LSsession { return self :: getEmailSender(); case 'api_mode': return boolval(self :: $api_mode); + case 'ldap_server_id': + return boolval(self :: $ldapServerId); } return null; } @@ -2414,7 +2416,7 @@ class LSsession { * @param string $authorized The authorized maximum right * @return boolean */ - public function checkRight($requested, $authorized) { + public static function checkRight($requested, $authorized) { if ($requested == $authorized) return true; if ($requested == 'r' && $authorized == 'w') @@ -3161,7 +3163,7 @@ class LSsession { 'LSsession_21', array( 'func' => $func -> getName(), - 'addon' => $addon, + 'addon' => $LSaddon, 'view' => $viewId, ) ); @@ -3172,7 +3174,7 @@ class LSsession { 'LSsession_23', array( 'func' => $viewFunction, - 'addon' => $addon, + 'addon' => $LSaddon, 'view' => $viewId, ) ); diff --git a/src/includes/functions.php b/src/includes/functions.php index c0a7d11a..f722e378 100644 --- a/src/includes/functions.php +++ b/src/includes/functions.php @@ -788,7 +788,7 @@ function dateTime2LdapDate($datetime, $timezone=null, $format=null) { $datetime -> setTimezone(timezone_open(is_null($timezone)?'UTC':$timezone)); } if (is_null($format)) - $format = ($naive?'YmdHis':'YmdHisO'); + $format = ($timezone == 'naive'?'YmdHis':'YmdHisO'); $datetime_string = $datetime -> format($format); // Replace +0000 or -0000 end by Z diff --git a/src/includes/routes.php b/src/includes/routes.php index bcd269d9..dcce2ed6 100644 --- a/src/includes/routes.php +++ b/src/includes/routes.php @@ -1775,7 +1775,7 @@ function handle_api_LSobject_import($request) { $data['updateIfExists'], $data['justTry'] ); - LSlog :: debug("LSio::importFromPostData(): result = ".varDump($result)); + LSlog :: debug("LSio::importFromPostData(): result = ".varDump($data)); } LSsession :: displayAjaxReturn($data); @@ -1946,7 +1946,7 @@ function handle_api_LSobject_remove($request) { $data['success'] = true; } else { - LSerror :: addErrorCode('LSldapObject_15', $objectname); + LSerror :: addErrorCode('LSldapObject_15', $data['name']); } LSsession :: displayAjaxReturn($data); } @@ -1972,7 +1972,7 @@ function handle_api_LSobject_relation($request) { // Handle relation URL parameter $relationName = $request -> relation; if (!is_array($object -> getConfig("LSrelation.$relationName"))) { - LSlog :: log_error("LSobject $LSobject have no relation '$relationName'."); + LSlog :: error("LSobject $LSobject have no relation '$relationName'."); LSsession :: displayAjaxReturn(); return false; }