| Total Complexity | 1928 |
| Total Lines | 8013 |
| Duplicated Lines | 0 % |
| Changes | 0 | ||
Complex classes like AlDolUtils often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use AlDolUtils, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 39 | class AlDolUtils |
||
| 40 | {
|
||
| 41 | |||
| 42 | /** |
||
| 43 | * Function to return value of a static property when class |
||
| 44 | * name is dynamically defined (not hard coded). |
||
| 45 | * This is because $myclass::$myvar works from PHP 5.3.0+ only |
||
| 46 | * |
||
| 47 | * @param string $class Class name |
||
| 48 | * @param string $member Name of property |
||
| 49 | * @return mixed Return value of static property |
||
| 50 | * @deprecated Dolibarr now requires 5.3.0+, use $class::$property syntax |
||
| 51 | * @see https://php.net/manual/language.oop5.static.php |
||
| 52 | */ |
||
| 53 | static function getStaticMember($class, $member) |
||
| 54 | {
|
||
| 55 | AlDolUtils::dol_syslog(__FUNCTION__ . " is deprecated", LOG_WARNING); |
||
| 56 | |||
| 57 | // This part is deprecated. Uncomment if for php 5.2.*, and comment next isset class::member |
||
| 58 | /* if (version_compare(phpversion(), '5.3.0', '<')) |
||
| 59 | {
|
||
| 60 | if (is_object($class)) $class = get_class($class); |
||
| 61 | $classObj = new ReflectionClass($class); |
||
| 62 | $result = null; |
||
| 63 | |||
| 64 | $found=0; |
||
| 65 | foreach($classObj->getStaticProperties() as $prop => $value) |
||
| 66 | {
|
||
| 67 | if ($prop == $member) |
||
| 68 | {
|
||
| 69 | $result = $value; |
||
| 70 | $found++; |
||
| 71 | break; |
||
| 72 | } |
||
| 73 | } |
||
| 74 | |||
| 75 | if ($found) return $result; |
||
| 76 | } */ |
||
| 77 | |||
| 78 | if (isset($class::$member)) |
||
|
|
|||
| 79 | return $class::$member; |
||
| 80 | dol_print_error('', 'Try to get a static member "' . $member . '" in class "' . $class . '" that does not exists or is not static.');
|
||
| 81 | return null; |
||
| 82 | } |
||
| 83 | |||
| 84 | /** |
||
| 85 | * Return a DoliDB instance (database handler). |
||
| 86 | * |
||
| 87 | * @param string $type Type of database (mysql, pgsql...) |
||
| 88 | * @param string $host Address of database server |
||
| 89 | * @param string $user Nom de l'utilisateur autorise |
||
| 90 | * @param string $pass Mot de passe |
||
| 91 | * @param string $name Nom de la database |
||
| 92 | * @param int $port Port of database server |
||
| 93 | * @return DoliDB A DoliDB instance |
||
| 94 | */ |
||
| 95 | static function getDoliDBInstance($type, $host, $user, $pass, $name, $port) |
||
| 96 | {
|
||
| 97 | require_once DOL_BASE_PATH . "/core/db/" . $type . '.class.php'; |
||
| 98 | |||
| 99 | $class = 'DoliDB' . ucfirst($type); |
||
| 100 | $dolidb = new $class($type, $host, $user, $pass, $name, $port); |
||
| 101 | return $dolidb; |
||
| 102 | } |
||
| 103 | |||
| 104 | /** |
||
| 105 | * Get list of entity id to use. |
||
| 106 | * |
||
| 107 | * @param string $element Current element |
||
| 108 | * 'societe', 'socpeople', 'actioncomm', 'agenda', 'resource', |
||
| 109 | * 'product', 'productprice', 'stock', |
||
| 110 | * 'propal', 'supplier_proposal', 'invoice', 'facture_fourn', 'payment_various', |
||
| 111 | * 'categorie', 'bank_account', 'bank_account', 'adherent', 'user', |
||
| 112 | * 'commande', 'commande_fournisseur', 'expedition', 'intervention', 'survey', |
||
| 113 | * 'contract', 'tax', 'expensereport', 'holiday', 'multicurrency', 'project', |
||
| 114 | * 'email_template', 'event', 'donation' |
||
| 115 | * 'c_paiement', 'c_payment_term', ... |
||
| 116 | * @param int $shared 0=Return id of current entity only, |
||
| 117 | * 1=Return id of current entity + shared entities (default) |
||
| 118 | * @param object $currentobject Current object if needed |
||
| 119 | * @return mixed Entity id(s) to use |
||
| 120 | */ |
||
| 121 | static function getEntity($element, $shared = 1, $currentobject = null) |
||
| 122 | {
|
||
| 123 | //// global Globals::$conf, $mc; |
||
| 124 | |||
| 125 | if (is_object(Globals::$mc)) {
|
||
| 126 | return Globals::$mc->getEntity($element, $shared, $currentobject); |
||
| 127 | } else {
|
||
| 128 | $out = ''; |
||
| 129 | $addzero = array('user', 'usergroup', 'c_email_templates', 'email_template', 'default_values');
|
||
| 130 | if (in_array($element, $addzero)) |
||
| 131 | $out .= '0,'; |
||
| 132 | $out .= Globals::$conf->entity; |
||
| 133 | return $out; |
||
| 134 | } |
||
| 135 | } |
||
| 136 | |||
| 137 | /** |
||
| 138 | * Return information about user browser |
||
| 139 | * |
||
| 140 | * Returns array with the following format: |
||
| 141 | * array( |
||
| 142 | * 'browsername' => Browser name (firefox|chrome|iceweasel|epiphany|safari|opera|ie|unknown) |
||
| 143 | * 'browserversion' => Browser version. Empty if unknown |
||
| 144 | * 'browseros' => Set with mobile OS (android|blackberry|ios|palm|symbian|webos|maemo|windows|unknown) |
||
| 145 | * 'layout' => (tablet|phone|classic) |
||
| 146 | * 'phone' => empty if not mobile, (android|blackberry|ios|palm|unknown) if mobile |
||
| 147 | * 'tablet' => true/false |
||
| 148 | * ) |
||
| 149 | * |
||
| 150 | * @param string $user_agent Content of $_SERVER["HTTP_USER_AGENT"] variable |
||
| 151 | * @return array Check function documentation |
||
| 152 | */ |
||
| 153 | static function getBrowserInfo($user_agent) |
||
| 154 | {
|
||
| 155 | //include_once BASE_PATH . '/vendor/mobiledetect/mobiledetectlib/Mobile_Detect.php'; |
||
| 156 | |||
| 157 | $name = 'unknown'; |
||
| 158 | $version = ''; |
||
| 159 | $os = 'unknown'; |
||
| 160 | $phone = ''; |
||
| 161 | |||
| 162 | $detectmobile = new Mobile_Detect(null, $user_agent); |
||
| 163 | $tablet = $detectmobile->isTablet(); |
||
| 164 | |||
| 165 | if ($detectmobile->isMobile()) {
|
||
| 166 | |||
| 167 | $phone = 'unknown'; |
||
| 168 | |||
| 169 | // If phone/smartphone, we set phone os name. |
||
| 170 | if ($detectmobile->is('AndroidOS')) {
|
||
| 171 | $os = $phone = 'android'; |
||
| 172 | } elseif ($detectmobile->is('BlackBerryOS')) {
|
||
| 173 | $os = $phone = 'blackberry'; |
||
| 174 | } elseif ($detectmobile->is('iOS')) {
|
||
| 175 | $os = 'ios'; |
||
| 176 | $phone = 'iphone'; |
||
| 177 | } elseif ($detectmobile->is('PalmOS')) {
|
||
| 178 | $os = $phone = 'palm'; |
||
| 179 | } elseif ($detectmobile->is('SymbianOS')) {
|
||
| 180 | $os = 'symbian'; |
||
| 181 | } elseif ($detectmobile->is('webOS')) {
|
||
| 182 | $os = 'webos'; |
||
| 183 | } elseif ($detectmobile->is('MaemoOS')) {
|
||
| 184 | $os = 'maemo'; |
||
| 185 | } elseif ($detectmobile->is('WindowsMobileOS') || $detectmobile->is('WindowsPhoneOS')) {
|
||
| 186 | $os = 'windows'; |
||
| 187 | } |
||
| 188 | } |
||
| 189 | |||
| 190 | // OS |
||
| 191 | if (preg_match('/linux/i', $user_agent)) {
|
||
| 192 | $os = 'linux'; |
||
| 193 | } elseif (preg_match('/macintosh/i', $user_agent)) {
|
||
| 194 | $os = 'macintosh'; |
||
| 195 | } elseif (preg_match('/windows/i', $user_agent)) {
|
||
| 196 | $os = 'windows'; |
||
| 197 | } |
||
| 198 | |||
| 199 | // Name |
||
| 200 | if (preg_match('/firefox(\/|\s)([\d\.]*)/i', $user_agent, $reg)) {
|
||
| 201 | $name = 'firefox'; |
||
| 202 | $version = $reg[2]; |
||
| 203 | } elseif (preg_match('/edge(\/|\s)([\d\.]*)/i', $user_agent, $reg)) {
|
||
| 204 | $name = 'edge'; |
||
| 205 | $version = $reg[2]; |
||
| 206 | } elseif (preg_match('/chrome(\/|\s)([\d\.]+)/i', $user_agent, $reg)) {
|
||
| 207 | $name = 'chrome'; |
||
| 208 | $version = $reg[2]; |
||
| 209 | } // we can have 'chrome (Mozilla...) chrome x.y' in one string |
||
| 210 | elseif (preg_match('/chrome/i', $user_agent, $reg)) {
|
||
| 211 | $name = 'chrome'; |
||
| 212 | } elseif (preg_match('/iceweasel/i', $user_agent)) {
|
||
| 213 | $name = 'iceweasel'; |
||
| 214 | } elseif (preg_match('/epiphany/i', $user_agent)) {
|
||
| 215 | $name = 'epiphany'; |
||
| 216 | } elseif (preg_match('/safari(\/|\s)([\d\.]*)/i', $user_agent, $reg)) {
|
||
| 217 | $name = 'safari'; |
||
| 218 | $version = $reg[2]; |
||
| 219 | } // Safari is often present in string for mobile but its not. |
||
| 220 | elseif (preg_match('/opera(\/|\s)([\d\.]*)/i', $user_agent, $reg)) {
|
||
| 221 | $name = 'opera'; |
||
| 222 | $version = $reg[2]; |
||
| 223 | } elseif (preg_match('/(MSIE\s([0-9]+\.[0-9]))|.*(Trident\/[0-9]+.[0-9];.*rv:([0-9]+\.[0-9]+))/i', $user_agent, $reg)) {
|
||
| 224 | $name = 'ie'; |
||
| 225 | $version = end($reg); |
||
| 226 | } // MS products at end |
||
| 227 | elseif (preg_match('/(Windows NT\s([0-9]+\.[0-9])).*(Trident\/[0-9]+.[0-9];.*rv:([0-9]+\.[0-9]+))/i', $user_agent, $reg)) {
|
||
| 228 | $name = 'ie'; |
||
| 229 | $version = end($reg); |
||
| 230 | } // MS products at end |
||
| 231 | elseif (preg_match('/l(i|y)n(x|ks)(\(|\/|\s)*([\d\.]+)/i', $user_agent, $reg)) {
|
||
| 232 | $name = 'lynxlinks'; |
||
| 233 | $version = $reg[4]; |
||
| 234 | } |
||
| 235 | |||
| 236 | if ($tablet) {
|
||
| 237 | $layout = 'tablet'; |
||
| 238 | } elseif ($phone) {
|
||
| 239 | $layout = 'phone'; |
||
| 240 | } else {
|
||
| 241 | $layout = 'classic'; |
||
| 242 | } |
||
| 243 | |||
| 244 | return array( |
||
| 245 | 'browsername' => $name, |
||
| 246 | 'browserversion' => $version, |
||
| 247 | 'browseros' => $os, |
||
| 248 | 'layout' => $layout, |
||
| 249 | 'phone' => $phone, |
||
| 250 | 'tablet' => $tablet |
||
| 251 | ); |
||
| 252 | } |
||
| 253 | |||
| 254 | /** |
||
| 255 | * Function called at end of web php process |
||
| 256 | * |
||
| 257 | * @return void |
||
| 258 | */ |
||
| 259 | static function dol_shutdown() |
||
| 260 | {
|
||
| 261 | // global Globals::$conf, $user, Globals::$langs, $db; |
||
| 262 | $disconnectdone = false; |
||
| 263 | $depth = 0; |
||
| 264 | if (is_object($db) && !empty($db->connected)) {
|
||
| 265 | $depth = $db->transaction_opened; |
||
| 266 | $disconnectdone = $db->close(); |
||
| 267 | } |
||
| 268 | AlDolUtils::dol_syslog("--- End access to " . $_SERVER["PHP_SELF"] . (($disconnectdone && $depth) ? ' (Warn: db disconnection forced, transaction depth was ' . $depth . ')' : ''), (($disconnectdone && $depth) ? LOG_WARNING : LOG_INFO));
|
||
| 269 | } |
||
| 270 | |||
| 271 | /** |
||
| 272 | * Return true if we are in a context of submitting a parameter |
||
| 273 | * |
||
| 274 | * @param string $paramname Name or parameter to test |
||
| 275 | * @return boolean True if we have just submit a POST or GET request with the parameter provided (even if param is empty) |
||
| 276 | */ |
||
| 277 | static function GETPOSTISSET($paramname) |
||
| 278 | {
|
||
| 279 | return (isset($_POST[$paramname]) || isset($_GET[$paramname])); |
||
| 280 | } |
||
| 281 | |||
| 282 | /** |
||
| 283 | * Return value of a param into GET or POST supervariable. |
||
| 284 | * Use the property $user->default_values[path]['creatform'] and/or $user->default_values[path]['filters'] and/or $user->default_values[path]['sortorder'] |
||
| 285 | * Note: The property $user->default_values is loaded by main.php when loading the user. |
||
| 286 | * |
||
| 287 | * @param string $paramname Name of parameter to found |
||
| 288 | * @param string $check Type of check |
||
| 289 | * ''=no check (deprecated) |
||
| 290 | * 'none'=no check (only for param that should have very rich content) |
||
| 291 | * 'int'=check it's numeric (integer or float) |
||
| 292 | * 'intcomma'=check it's integer+comma ('1,2,3,4...')
|
||
| 293 | * 'alpha'=check it's text and sign |
||
| 294 | * 'aZ'=check it's a-z only |
||
| 295 | * 'aZ09'=check it's simple alpha string (recommended for keys) |
||
| 296 | * 'array'=check it's array |
||
| 297 | * 'san_alpha'=Use filter_var with FILTER_SANITIZE_STRING (do not use this for free text string) |
||
| 298 | * 'nohtml', 'alphanohtml'=check there is no html content |
||
| 299 | * 'custom'= custom filter specify $filter and $options) |
||
| 300 | * @param int $method Type of method (0 = get then post, 1 = only get, 2 = only post, 3 = post then get, 4 = post then get then cookie) |
||
| 301 | * @param int $filter Filter to apply when $check is set to 'custom'. (See http://php.net/manual/en/filter.filters.php for détails) |
||
| 302 | * @param mixed $options Options to pass to filter_var when $check is set to 'custom' |
||
| 303 | * @param string $noreplace Force disable of replacement of __xxx__ strings. |
||
| 304 | * @return string|string[] Value found (string or array), or '' if check fails |
||
| 305 | */ |
||
| 306 | static function GETPOST($paramname, $check = 'none', $method = 0, $filter = null, $options = null, $noreplace = 0) |
||
| 307 | {
|
||
| 308 | // global $mysoc, $user, Globals::$conf; |
||
| 309 | |||
| 310 | if (empty($paramname)) {
|
||
| 311 | return 'BadFirstParameterForDolUtils::GETPOST'; |
||
| 312 | } |
||
| 313 | if (empty($check)) {
|
||
| 314 | AlDolUtils::dol_syslog("Deprecated use of AlDolUtils::GETPOST, called with 1st param = " . $paramname . " and 2nd param is '', when calling page " . $_SERVER["PHP_SELF"], LOG_WARNING);
|
||
| 315 | // Enable this line to know who call the AlDolUtils::GETPOST with '' $check parameter. |
||
| 316 | //var_dump(debug_backtrace()[0]); |
||
| 317 | } |
||
| 318 | |||
| 319 | switch ($method) {
|
||
| 320 | case 1: |
||
| 321 | $out = isset($_GET[$paramname]) ? $_GET[$paramname] : ''; |
||
| 322 | break; |
||
| 323 | case 2: |
||
| 324 | $out = isset($_POST[$paramname]) ? $_POST[$paramname] : ''; |
||
| 325 | break; |
||
| 326 | case 3: |
||
| 327 | $out = isset($_POST[$paramname]) ? $_POST[$paramname] : (isset($_GET[$paramname]) ? $_GET[$paramname] : ''); |
||
| 328 | break; |
||
| 329 | case 4: |
||
| 330 | $out = isset($_POST[$paramname]) ? $_POST[$paramname] : (isset($_GET[$paramname]) ? $_GET[$paramname] : (isset($_COOKIE[$paramname]) ? $_COOKIE[$paramname] : '')); |
||
| 331 | break; |
||
| 332 | default: |
||
| 333 | if (!empty($method)) {
|
||
| 334 | return 'BadThirdParameterForDolUtils::GETPOST'; |
||
| 335 | } |
||
| 336 | $out = isset($_GET[$paramname]) ? $_GET[$paramname] : (isset($_POST[$paramname]) ? $_POST[$paramname] : ''); |
||
| 337 | } |
||
| 338 | |||
| 339 | if (empty($method) || $method == 3 || $method == 4) {
|
||
| 340 | $relativepathstring = $_SERVER["PHP_SELF"]; |
||
| 341 | // Clean $relativepathstring |
||
| 342 | if (constant('DOL_BASE_URI')) {
|
||
| 343 | $relativepathstring = preg_replace('/^' . preg_quote(constant('DOL_BASE_URI'), '/') . '/', '', $relativepathstring);
|
||
| 344 | } |
||
| 345 | $relativepathstring = preg_replace('/^\//', '', $relativepathstring);
|
||
| 346 | $relativepathstring = preg_replace('/^custom\//', '', $relativepathstring);
|
||
| 347 | //var_dump($relativepathstring); |
||
| 348 | //var_dump($user->default_values); |
||
| 349 | // Code for search criteria persistence. |
||
| 350 | // Retrieve values if restore_lastsearch_values |
||
| 351 | if (!empty($_GET['restore_lastsearch_values'])) { // Use $_GET here and not AlDolUtils::GETPOST
|
||
| 352 | if (!empty($_SESSION['lastsearch_values_' . $relativepathstring])) { // If there is saved values
|
||
| 353 | $tmp = json_decode($_SESSION['lastsearch_values_' . $relativepathstring], true); |
||
| 354 | if (is_array($tmp)) {
|
||
| 355 | foreach ($tmp as $key => $val) {
|
||
| 356 | if ($key == $paramname) { // We are on the requested parameter
|
||
| 357 | $out = $val; |
||
| 358 | break; |
||
| 359 | } |
||
| 360 | } |
||
| 361 | } |
||
| 362 | } |
||
| 363 | // If there is saved contextpage, page or limit |
||
| 364 | if ($paramname == 'contextpage' && !empty($_SESSION['lastsearch_contextpage_' . $relativepathstring])) {
|
||
| 365 | $out = $_SESSION['lastsearch_contextpage_' . $relativepathstring]; |
||
| 366 | } elseif ($paramname == 'page' && !empty($_SESSION['lastsearch_page_' . $relativepathstring])) {
|
||
| 367 | $out = $_SESSION['lastsearch_page_' . $relativepathstring]; |
||
| 368 | } elseif ($paramname == 'limit' && !empty($_SESSION['lastsearch_limit_' . $relativepathstring])) {
|
||
| 369 | $out = $_SESSION['lastsearch_limit_' . $relativepathstring]; |
||
| 370 | } |
||
| 371 | } |
||
| 372 | // Else, retreive default values if we are not doing a sort |
||
| 373 | else {
|
||
| 374 | if (!isset($_GET['sortfield'])) { // If we did a click on a field to sort, we do no apply default values. Same if option MAIN_ENABLE_DEFAULT_VALUES is not set
|
||
| 375 | if (!empty($_GET['action']) && $_GET['action'] == 'create' && !isset($_GET[$paramname]) && !isset($_POST[$paramname])) {
|
||
| 376 | // Search default value from $object->field |
||
| 377 | // global $object; |
||
| 378 | if (isset($object) && is_object($object) && isset($object->fields[$paramname]['default'])) {
|
||
| 379 | $out = $object->fields[$paramname]['default']; |
||
| 380 | } |
||
| 381 | } |
||
| 382 | if (!empty(Globals::$conf->global->MAIN_ENABLE_DEFAULT_VALUES)) {
|
||
| 383 | if (!empty($_GET['action']) && $_GET['action'] == 'create' && !isset($_GET[$paramname]) && !isset($_POST[$paramname])) {
|
||
| 384 | // Now search in setup to overwrite default values |
||
| 385 | if (!empty($user->default_values)) { // $user->default_values defined from menu 'Setup - Default values'
|
||
| 386 | if (isset($user->default_values[$relativepathstring]['createform'])) {
|
||
| 387 | foreach ($user->default_values[$relativepathstring]['createform'] as $defkey => $defval) {
|
||
| 388 | $qualified = 0; |
||
| 389 | if ($defkey != '_noquery_') {
|
||
| 390 | $tmpqueryarraytohave = explode('&', $defkey);
|
||
| 391 | $tmpqueryarraywehave = explode('&', dol_string_nohtmltag($_SERVER['QUERY_STRING']));
|
||
| 392 | $foundintru = 0; |
||
| 393 | foreach ($tmpqueryarraytohave as $tmpquerytohave) {
|
||
| 394 | if (!in_array($tmpquerytohave, $tmpqueryarraywehave)) |
||
| 395 | $foundintru = 1; |
||
| 396 | } |
||
| 397 | if (!$foundintru) |
||
| 398 | $qualified = 1; |
||
| 399 | //var_dump($defkey.'-'.$qualified); |
||
| 400 | } else |
||
| 401 | $qualified = 1; |
||
| 402 | |||
| 403 | if ($qualified) {
|
||
| 404 | //var_dump($user->default_values[$relativepathstring][$defkey]['createform']); |
||
| 405 | if (isset($user->default_values[$relativepathstring]['createform'][$defkey][$paramname])) {
|
||
| 406 | $out = $user->default_values[$relativepathstring]['createform'][$defkey][$paramname]; |
||
| 407 | break; |
||
| 408 | } |
||
| 409 | } |
||
| 410 | } |
||
| 411 | } |
||
| 412 | } |
||
| 413 | } |
||
| 414 | // Management of default search_filters and sort order |
||
| 415 | //elseif (preg_match('/list.php$/', $_SERVER["PHP_SELF"]) && ! empty($paramname) && ! isset($_GET[$paramname]) && ! isset($_POST[$paramname]))
|
||
| 416 | elseif (!empty($paramname) && !isset($_GET[$paramname]) && !isset($_POST[$paramname])) {
|
||
| 417 | if (!empty($user->default_values)) { // $user->default_values defined from menu 'Setup - Default values'
|
||
| 418 | //var_dump($user->default_values[$relativepathstring]); |
||
| 419 | if ($paramname == 'sortfield' || $paramname == 'sortorder') { // Sorted on which fields ? ASC or DESC ?
|
||
| 420 | if (isset($user->default_values[$relativepathstring]['sortorder'])) { // Even if paramname is sortfield, data are stored into ['sortorder...']
|
||
| 421 | foreach ($user->default_values[$relativepathstring]['sortorder'] as $defkey => $defval) {
|
||
| 422 | $qualified = 0; |
||
| 423 | if ($defkey != '_noquery_') {
|
||
| 424 | $tmpqueryarraytohave = explode('&', $defkey);
|
||
| 425 | $tmpqueryarraywehave = explode('&', dol_string_nohtmltag($_SERVER['QUERY_STRING']));
|
||
| 426 | $foundintru = 0; |
||
| 427 | foreach ($tmpqueryarraytohave as $tmpquerytohave) {
|
||
| 428 | if (!in_array($tmpquerytohave, $tmpqueryarraywehave)) |
||
| 429 | $foundintru = 1; |
||
| 430 | } |
||
| 431 | if (!$foundintru) |
||
| 432 | $qualified = 1; |
||
| 433 | //var_dump($defkey.'-'.$qualified); |
||
| 434 | } else |
||
| 435 | $qualified = 1; |
||
| 436 | |||
| 437 | if ($qualified) {
|
||
| 438 | $forbidden_chars_to_replace = array(" ", "'", "/", "\\", ":", "*", "?", "\"", "<", ">", "|", "[", "]", ";", "="); // we accept _, -, . and ,
|
||
| 439 | foreach ($user->default_values[$relativepathstring]['sortorder'][$defkey] as $key => $val) {
|
||
| 440 | if ($out) |
||
| 441 | $out .= ', '; |
||
| 442 | if ($paramname == 'sortfield') {
|
||
| 443 | $out .= dol_string_nospecial($key, '', $forbidden_chars_to_replace); |
||
| 444 | } |
||
| 445 | if ($paramname == 'sortorder') {
|
||
| 446 | $out .= dol_string_nospecial($val, '', $forbidden_chars_to_replace); |
||
| 447 | } |
||
| 448 | } |
||
| 449 | //break; // No break for sortfield and sortorder so we can cumulate fields (is it realy usefull ?) |
||
| 450 | } |
||
| 451 | } |
||
| 452 | } |
||
| 453 | } elseif (isset($user->default_values[$relativepathstring]['filters'])) {
|
||
| 454 | foreach ($user->default_values[$relativepathstring]['filters'] as $defkey => $defval) { // $defkey is a querystring like 'a=b&c=d', $defval is key of user
|
||
| 455 | $qualified = 0; |
||
| 456 | if ($defkey != '_noquery_') {
|
||
| 457 | $tmpqueryarraytohave = explode('&', $defkey);
|
||
| 458 | $tmpqueryarraywehave = explode('&', dol_string_nohtmltag($_SERVER['QUERY_STRING']));
|
||
| 459 | $foundintru = 0; |
||
| 460 | foreach ($tmpqueryarraytohave as $tmpquerytohave) {
|
||
| 461 | if (!in_array($tmpquerytohave, $tmpqueryarraywehave)) |
||
| 462 | $foundintru = 1; |
||
| 463 | } |
||
| 464 | if (!$foundintru) |
||
| 465 | $qualified = 1; |
||
| 466 | //var_dump($defkey.'-'.$qualified); |
||
| 467 | } else |
||
| 468 | $qualified = 1; |
||
| 469 | |||
| 470 | if ($qualified) {
|
||
| 471 | if (isset($_POST['sall']) || isset($_POST['search_all']) || isset($_GET['sall']) || isset($_GET['search_all'])) {
|
||
| 472 | // We made a search from quick search menu, do we still use default filter ? |
||
| 473 | if (empty(Globals::$conf->global->MAIN_DISABLE_DEFAULT_FILTER_FOR_QUICK_SEARCH)) {
|
||
| 474 | $forbidden_chars_to_replace = array(" ", "'", "/", "\\", ":", "*", "?", "\"", "<", ">", "|", "[", "]", ";", "="); // we accept _, -, . and ,
|
||
| 475 | $out = dol_string_nospecial($user->default_values[$relativepathstring]['filters'][$defkey][$paramname], '', $forbidden_chars_to_replace); |
||
| 476 | } |
||
| 477 | } else {
|
||
| 478 | $forbidden_chars_to_replace = array(" ", "'", "/", "\\", ":", "*", "?", "\"", "<", ">", "|", "[", "]", ";", "="); // we accept _, -, . and ,
|
||
| 479 | $out = dol_string_nospecial($user->default_values[$relativepathstring]['filters'][$defkey][$paramname], '', $forbidden_chars_to_replace); |
||
| 480 | } |
||
| 481 | break; |
||
| 482 | } |
||
| 483 | } |
||
| 484 | } |
||
| 485 | } |
||
| 486 | } |
||
| 487 | } |
||
| 488 | } |
||
| 489 | } |
||
| 490 | } |
||
| 491 | |||
| 492 | // Substitution variables for AlDolUtils::GETPOST (used to get final url with variable parameters or final default value with variable paramaters) |
||
| 493 | // Example of variables: __DAY__, __MONTH__, __YEAR__, __MYCOMPANY_COUNTRY_ID__, __USER_ID__, ... |
||
| 494 | // We do this only if var is a GET. If it is a POST, may be we want to post the text with vars as the setup text. |
||
| 495 | if (!is_array($out) && empty($_POST[$paramname]) && empty($noreplace)) {
|
||
| 496 | $maxloop = 20; |
||
| 497 | $loopnb = 0; // Protection against infinite loop |
||
| 498 | while (preg_match('/__([A-Z0-9]+_?[A-Z0-9]+)__/i', $out, $reg) && ($loopnb < $maxloop)) { // Detect '__ABCDEF__' as key 'ABCDEF' and '__ABC_DEF__' as key 'ABC_DEF'. Detection is also correct when 2 vars are side by side.
|
||
| 499 | $loopnb++; |
||
| 500 | $newout = ''; |
||
| 501 | |||
| 502 | if ($reg[1] == 'DAY') {
|
||
| 503 | $tmp = dol_getdate(dol_now(), true); |
||
| 504 | $newout = $tmp['mday']; |
||
| 505 | } elseif ($reg[1] == 'MONTH') {
|
||
| 506 | $tmp = dol_getdate(dol_now(), true); |
||
| 507 | $newout = $tmp['mon']; |
||
| 508 | } elseif ($reg[1] == 'YEAR') {
|
||
| 509 | $tmp = dol_getdate(dol_now(), true); |
||
| 510 | $newout = $tmp['year']; |
||
| 511 | } elseif ($reg[1] == 'PREVIOUS_DAY') {
|
||
| 512 | $tmp = dol_getdate(dol_now(), true); |
||
| 513 | $tmp2 = dol_get_prev_day($tmp['mday'], $tmp['mon'], $tmp['year']); |
||
| 514 | $newout = $tmp2['day']; |
||
| 515 | } elseif ($reg[1] == 'PREVIOUS_MONTH') {
|
||
| 516 | $tmp = dol_getdate(dol_now(), true); |
||
| 517 | $tmp2 = dol_get_prev_month($tmp['mon'], $tmp['year']); |
||
| 518 | $newout = $tmp2['month']; |
||
| 519 | } elseif ($reg[1] == 'PREVIOUS_YEAR') {
|
||
| 520 | $tmp = dol_getdate(dol_now(), true); |
||
| 521 | $newout = ($tmp['year'] - 1); |
||
| 522 | } elseif ($reg[1] == 'NEXT_DAY') {
|
||
| 523 | $tmp = dol_getdate(dol_now(), true); |
||
| 524 | $tmp2 = dol_get_next_day($tmp['mday'], $tmp['mon'], $tmp['year']); |
||
| 525 | $newout = $tmp2['day']; |
||
| 526 | } elseif ($reg[1] == 'NEXT_MONTH') {
|
||
| 527 | $tmp = dol_getdate(dol_now(), true); |
||
| 528 | $tmp2 = dol_get_next_month($tmp['mon'], $tmp['year']); |
||
| 529 | $newout = $tmp2['month']; |
||
| 530 | } elseif ($reg[1] == 'NEXT_YEAR') {
|
||
| 531 | $tmp = dol_getdate(dol_now(), true); |
||
| 532 | $newout = ($tmp['year'] + 1); |
||
| 533 | } elseif ($reg[1] == 'MYCOMPANY_COUNTRY_ID' || $reg[1] == 'MYCOUNTRY_ID' || $reg[1] == 'MYCOUNTRYID') {
|
||
| 534 | $newout = $mysoc->country_id; |
||
| 535 | } elseif ($reg[1] == 'USER_ID' || $reg[1] == 'USERID') {
|
||
| 536 | $newout = $user->id; |
||
| 537 | } elseif ($reg[1] == 'USER_SUPERVISOR_ID' || $reg[1] == 'SUPERVISOR_ID' || $reg[1] == 'SUPERVISORID') {
|
||
| 538 | $newout = $user->fk_user; |
||
| 539 | } elseif ($reg[1] == 'ENTITY_ID' || $reg[1] == 'ENTITYID') {
|
||
| 540 | $newout = Globals::$conf->entity; |
||
| 541 | } else {
|
||
| 542 | $newout = ''; // Key not found, we replace with empty string |
||
| 543 | } |
||
| 544 | //var_dump('__'.$reg[1].'__ -> '.$newout);
|
||
| 545 | $out = preg_replace('/__' . preg_quote($reg[1], '/') . '__/', $newout, $out);
|
||
| 546 | } |
||
| 547 | } |
||
| 548 | |||
| 549 | // Check is done after replacement |
||
| 550 | switch ($check) {
|
||
| 551 | case 'none': |
||
| 552 | break; |
||
| 553 | case 'int': // Check param is a numeric value (integer but also float or hexadecimal) |
||
| 554 | if (!is_numeric($out)) {
|
||
| 555 | $out = ''; |
||
| 556 | } |
||
| 557 | break; |
||
| 558 | case 'intcomma': |
||
| 559 | if (preg_match('/[^0-9,-]+/i', $out))
|
||
| 560 | $out = ''; |
||
| 561 | break; |
||
| 562 | case 'alpha': |
||
| 563 | if (!is_array($out)) {
|
||
| 564 | $out = trim($out); |
||
| 565 | // '"' is dangerous because param in url can close the href= or src= and add javascript functions. |
||
| 566 | // '../' is dangerous because it allows dir transversals |
||
| 567 | if (preg_match('/"/', $out))
|
||
| 568 | $out = ''; |
||
| 569 | else if (preg_match('/\.\.\//', $out))
|
||
| 570 | $out = ''; |
||
| 571 | } |
||
| 572 | break; |
||
| 573 | case 'san_alpha': |
||
| 574 | $out = filter_var($out, FILTER_SANITIZE_STRING); |
||
| 575 | break; |
||
| 576 | case 'aZ': |
||
| 577 | if (!is_array($out)) {
|
||
| 578 | $out = trim($out); |
||
| 579 | if (preg_match('/[^a-z]+/i', $out))
|
||
| 580 | $out = ''; |
||
| 581 | } |
||
| 582 | break; |
||
| 583 | case 'aZ09': |
||
| 584 | if (!is_array($out)) {
|
||
| 585 | $out = trim($out); |
||
| 586 | if (preg_match('/[^a-z0-9_\-\.]+/i', $out))
|
||
| 587 | $out = ''; |
||
| 588 | } |
||
| 589 | break; |
||
| 590 | case 'aZ09comma': // great to sanitize sortfield or sortorder params that can be t.abc,t.def_gh |
||
| 591 | if (!is_array($out)) {
|
||
| 592 | $out = trim($out); |
||
| 593 | if (preg_match('/[^a-z0-9_\-\.,]+/i', $out))
|
||
| 594 | $out = ''; |
||
| 595 | } |
||
| 596 | break; |
||
| 597 | case 'array': |
||
| 598 | if (!is_array($out) || empty($out)) |
||
| 599 | $out = array(); |
||
| 600 | break; |
||
| 601 | case 'nohtml': // Recommended for most scalar parameters |
||
| 602 | $out = dol_string_nohtmltag($out, 0); |
||
| 603 | break; |
||
| 604 | case 'alphanohtml': // Recommended for search parameters |
||
| 605 | if (!is_array($out)) {
|
||
| 606 | $out = trim($out); |
||
| 607 | // '"' is dangerous because param in url can close the href= or src= and add javascript functions. |
||
| 608 | // '../' is dangerous because it allows dir transversals |
||
| 609 | if (preg_match('/"/', $out))
|
||
| 610 | $out = ''; |
||
| 611 | else if (preg_match('/\.\.\//', $out))
|
||
| 612 | $out = ''; |
||
| 613 | $out = dol_string_nohtmltag($out); |
||
| 614 | } |
||
| 615 | break; |
||
| 616 | case 'custom': |
||
| 617 | if (empty($filter)) |
||
| 618 | return 'BadFourthParameterForDolUtils::GETPOST'; |
||
| 619 | $out = filter_var($out, $filter, $options); |
||
| 620 | break; |
||
| 621 | } |
||
| 622 | |||
| 623 | // Code for search criteria persistence. |
||
| 624 | // Save data into session if key start with 'search_' or is 'smonth', 'syear', 'month', 'year' |
||
| 625 | if (empty($method) || $method == 3 || $method == 4) {
|
||
| 626 | if (preg_match('/^search_/', $paramname) || in_array($paramname, array('sortorder', 'sortfield'))) {
|
||
| 627 | //var_dump($paramname.' - '.$out.' '.$user->default_values[$relativepathstring]['filters'][$paramname]); |
||
| 628 | // We save search key only if $out not empty that means: |
||
| 629 | // - posted value not empty, or |
||
| 630 | // - if posted value is empty and a default value exists that is not empty (it means we did a filter to an empty value when default was not). |
||
| 631 | |||
| 632 | if ($out != '') { // $out = '0' or 'abc', it is a search criteria to keep
|
||
| 633 | $user->lastsearch_values_tmp[$relativepathstring][$paramname] = $out; |
||
| 634 | } |
||
| 635 | } |
||
| 636 | } |
||
| 637 | |||
| 638 | return $out; |
||
| 639 | } |
||
| 640 | |||
| 641 | /** |
||
| 642 | * Return a prefix to use for this Dolibarr instance, for session/cookie names or email id. |
||
| 643 | * The prefix for session is unique in a web context only and is unique for instance and avoid conflict |
||
| 644 | * between multi-instances, even when having two instances with one root dir or two instances in virtual servers. |
||
| 645 | * The prefix for email is unique if MAIL_PREFIX_FOR_EMAIL_ID is set to a value, otherwise value may be same than other instance. |
||
| 646 | * |
||
| 647 | * @param string $mode '' (prefix for session name) or 'email' (prefix for email id) |
||
| 648 | * @return string A calculated prefix |
||
| 649 | */ |
||
| 650 | static function dol_getprefix($mode = '') |
||
| 651 | {
|
||
| 652 | // If prefix is for email |
||
| 653 | if ($mode == 'email') {
|
||
| 654 | if (empty(Globals::$conf->global->MAIL_PREFIX_FOR_EMAIL_ID)) {
|
||
| 655 | return AlSecurity::dol_hash(DOL_DOCUMENT_ROOT . DOL_BASE_URI); |
||
| 656 | } |
||
| 657 | // If MAIL_PREFIX_FOR_EMAIL_ID is set (a value initialized with a random value is recommended) |
||
| 658 | if (Globals::$conf->global->MAIL_PREFIX_FOR_EMAIL_ID != 'SERVER_NAME') {
|
||
| 659 | return Globals::$conf->global->MAIL_PREFIX_FOR_EMAIL_ID; |
||
| 660 | } |
||
| 661 | if (isset($_SERVER["SERVER_NAME"])) {
|
||
| 662 | return $_SERVER["SERVER_NAME"]; |
||
| 663 | } |
||
| 664 | |||
| 665 | return AlSecurity::dol_hash(DOL_DOCUMENT_ROOT . DOL_BASE_URI); |
||
| 666 | } |
||
| 667 | |||
| 668 | if (isset($_SERVER["SERVER_NAME"]) && isset($_SERVER["DOCUMENT_ROOT"])) {
|
||
| 669 | return AlSecurity::dol_hash($_SERVER["SERVER_NAME"] . $_SERVER["DOCUMENT_ROOT"] . DOL_DOCUMENT_ROOT . DOL_BASE_URI); |
||
| 670 | |||
| 671 | // Use this for a "readable" cookie name |
||
| 672 | //return dol_sanitizeFileName($_SERVER["SERVER_NAME"].$_SERVER["DOCUMENT_ROOT"].DOL_DOCUMENT_ROOT.DOL_BASE_URI); |
||
| 673 | } |
||
| 674 | return AlSecurity::dol_hash(DOL_DOCUMENT_ROOT . DOL_BASE_URI); |
||
| 675 | } |
||
| 676 | |||
| 677 | /** |
||
| 678 | * Make an include_once using default root and alternate root if it fails. |
||
| 679 | * To link to a core file, use include(DOL_DOCUMENT_ROOT.'/pathtofile') |
||
| 680 | * To link to a module file from a module file, use include './mymodulefile'; |
||
| 681 | * To link to a module file from a core file, then this function can be used (call by hook / trigger / speciales pages) |
||
| 682 | * |
||
| 683 | * @param string $relpath Relative path to file (Ie: mydir/myfile, ../myfile, ...) |
||
| 684 | * @param string $classname Class name (deprecated) |
||
| 685 | * @return bool True if load is a success, False if it fails |
||
| 686 | */ |
||
| 687 | static function dol_include_once($relpath, $classname = '') |
||
| 688 | {
|
||
| 689 | // global Globals::$conf, Globals::$langs, $user, $mysoc; // Do not remove this. They must be defined for files we include. Other globals var must be retreived with $GLOBALS['var'] |
||
| 690 | |||
| 691 | $fullpath = dol_buildpath($relpath); |
||
| 692 | |||
| 693 | if (!file_exists($fullpath)) {
|
||
| 694 | AlDolUtils::dol_syslog('functions::dol_include_once Tried to load unexisting file: ' . $relpath, LOG_ERR);
|
||
| 695 | return false; |
||
| 696 | } |
||
| 697 | |||
| 698 | if (!empty($classname) && !class_exists($classname)) {
|
||
| 699 | return include $fullpath; |
||
| 700 | } else {
|
||
| 701 | return include_once $fullpath; |
||
| 702 | } |
||
| 703 | } |
||
| 704 | |||
| 705 | /** |
||
| 706 | * Return path of url or filesystem. Can check into alternate dir or alternate dir + main dir depending on value of $returnemptyifnotfound. |
||
| 707 | * |
||
| 708 | * @param string $path Relative path to file (if mode=0) or relative url (if mode=1). Ie: mydir/myfile, ../myfile |
||
| 709 | * @param int $type 0=Used for a Filesystem path, 1=Used for an URL path (output relative), 2=Used for an URL path (output full path using same host that current url), 3=Used for an URL path (output full path using host defined into $dolibarr_main_url_root of conf file) |
||
| 710 | * @param int $returnemptyifnotfound 0:If $type==0 and if file was not found into alternate dir, return default path into main dir (no test on it) |
||
| 711 | * 1:If $type==0 and if file was not found into alternate dir, return empty string |
||
| 712 | * 2:If $type==0 and if file was not found into alternate dir, test into main dir, return default path if found, empty string if not found |
||
| 713 | * @return string Full filesystem path (if path=0), Full url path (if mode=1) |
||
| 714 | */ |
||
| 715 | static function dol_buildpath($path, $type = 0, $returnemptyifnotfound = 0) |
||
| 716 | {
|
||
| 717 | // global Globals::$conf; |
||
| 718 | |||
| 719 | $path = preg_replace('/^\//', '', $path);
|
||
| 720 | |||
| 721 | if ($type == 0 /* empty($type) */) { // For a filesystem path
|
||
| 722 | //$res = DOL_BASE_PATH . '' . $path; // Standard default path |
||
| 723 | $res = DOL_BASE_PATH . '/' . $path; // Standard default path |
||
| 724 | if (isset(Globals::$conf->file->dol_document_root)) {
|
||
| 725 | foreach (Globals::$conf->file->dol_document_root as $key => $dirroot) { // ex: array(["main"]=>"/home/main/htdocs", ["alt0"]=>"/home/dirmod/htdocs", ...)
|
||
| 726 | if ($key == 'main') {
|
||
| 727 | continue; |
||
| 728 | } |
||
| 729 | if (file_exists($dirroot . '/' . $path)) {
|
||
| 730 | $res = $dirroot . '/' . $path; |
||
| 731 | return $res; |
||
| 732 | } |
||
| 733 | } |
||
| 734 | } |
||
| 735 | if ($returnemptyifnotfound) { // Not found into alternate dir
|
||
| 736 | if ($returnemptyifnotfound == 1 || !file_exists($res)) |
||
| 737 | return ''; |
||
| 738 | } |
||
| 739 | } |
||
| 740 | else { // For an url path
|
||
| 741 | // We try to get local path of file on filesystem from url |
||
| 742 | // Note that trying to know if a file on disk exist by forging path on disk from url |
||
| 743 | // works only for some web server and some setup. This is bugged when |
||
| 744 | // using proxy, rewriting, virtual path, etc... |
||
| 745 | $res = ''; |
||
| 746 | if ($type == 1) {
|
||
| 747 | $res = /* DOL_BASE_URI */ DOL_BASE_URI . '/' . $path; // Standard value |
||
| 748 | } |
||
| 749 | if ($type == 2) {
|
||
| 750 | $res = /* DOL_MAIN_URL_ROOT */ DOL_BASE_PATH . '/' . $path; // Standard value |
||
| 751 | } |
||
| 752 | if ($type == 3) {
|
||
| 753 | $res = DOL_BASE_URI . '/' . $path; |
||
| 754 | } |
||
| 755 | |||
| 756 | foreach (Globals::$conf->file->dol_document_root as $key => $dirroot) { // ex: array(["main"]=>"/home/main/htdocs", ["alt0"]=>"/home/dirmod/htdocs", ...)
|
||
| 757 | if ($key == 'main') {
|
||
| 758 | if ($type == 3) {
|
||
| 759 | // global $dolibarr_main_url_root; |
||
| 760 | // Define $urlwithroot |
||
| 761 | // $urlwithouturlroot = preg_replace('/' . preg_quote(DOL_BASE_URI, '/') . '$/i', '', trim($dolibarr_main_url_root));
|
||
| 762 | $urlwithouturlroot = preg_replace('/' . preg_quote(DOL_BASE_URI, '/') . '$/i', '', trim(DOL_BASE_URI));
|
||
| 763 | |||
| 764 | $urlwithroot = $urlwithouturlroot . DOL_BASE_URI; // This is to use external domain name found into config file |
||
| 765 | //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current |
||
| 766 | |||
| 767 | $res = (preg_match('/^http/i', Globals::$conf->file->dol_url_root[$key]) ? '' : $urlwithroot) . '/' . $path; // Test on start with http is for old conf syntax
|
||
| 768 | } |
||
| 769 | continue; |
||
| 770 | } |
||
| 771 | preg_match('/^([^\?]+(\.css\.php|\.css|\.js\.php|\.js|\.png|\.jpg|\.php)?)/i', $path, $regs); // Take part before '?'
|
||
| 772 | if (!empty($regs[1])) {
|
||
| 773 | //print $key.'-'.$dirroot.'/'.$path.'-'.Globals::$conf->file->dol_url_root[$type].'<br>'."\n"; |
||
| 774 | if (file_exists($dirroot . '/' . $regs[1])) {
|
||
| 775 | if ($type == 1) {
|
||
| 776 | $res = (preg_match('/^http/i', Globals::$conf->file->dol_url_root[$key]) ? '' : DOL_BASE_URI) . Globals::$conf->file->dol_url_root[$key] . '/' . $path;
|
||
| 777 | } |
||
| 778 | if ($type == 2) {
|
||
| 779 | $res = (preg_match('/^http/i', Globals::$conf->file->dol_url_root[$key]) ? '' : DOL_MAIN_URL_ROOT) . Globals::$conf->file->dol_url_root[$key] . '/' . $path;
|
||
| 780 | } |
||
| 781 | if ($type == 3) {
|
||
| 782 | // global $dolibarr_main_url_root; |
||
| 783 | // Define $urlwithroot |
||
| 784 | $urlwithouturlroot = preg_replace('/' . preg_quote(DOL_BASE_URI, '/') . '$/i', '', trim($dolibarr_main_url_root));
|
||
| 785 | $urlwithroot = $urlwithouturlroot . DOL_BASE_URI; // This is to use external domain name found into config file |
||
| 786 | //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current |
||
| 787 | |||
| 788 | $res = (preg_match('/^http/i', Globals::$conf->file->dol_url_root[$key]) ? '' : $urlwithroot) . Globals::$conf->file->dol_url_root[$key] . '/' . $path; // Test on start with http is for old conf syntax
|
||
| 789 | } |
||
| 790 | break; |
||
| 791 | } |
||
| 792 | } |
||
| 793 | } |
||
| 794 | } |
||
| 795 | |||
| 796 | return $res; |
||
| 797 | } |
||
| 798 | |||
| 799 | /** |
||
| 800 | * Create a clone of instance of object (new instance with same value for properties) |
||
| 801 | * With native = 0: Property that are reference are also new object (true clone). This means $this->db is not valid. |
||
| 802 | * With native = 1: Use PHP clone. Property that are reference are same pointer. This means $this->db is still valid. |
||
| 803 | * |
||
| 804 | * @param object $object Object to clone |
||
| 805 | * @param int $native Native method or true method |
||
| 806 | * @return object Object clone |
||
| 807 | * @see https://php.net/manual/language.oop5.cloning.php |
||
| 808 | */ |
||
| 809 | static function dol_clone($object, $native = 0) |
||
| 810 | {
|
||
| 811 | //DolUtils::dol_syslog(__FUNCTION__ . " is deprecated", LOG_WARNING); |
||
| 812 | |||
| 813 | if (empty($native)) {
|
||
| 814 | $myclone = unserialize(serialize($object)); |
||
| 815 | } else {
|
||
| 816 | $myclone = clone $object; // PHP clone is a shallow copy only, not a real clone, so properties of references will keep references (refer to the same target/variable) |
||
| 817 | } |
||
| 818 | |||
| 819 | return $myclone; |
||
| 820 | } |
||
| 821 | |||
| 822 | /** |
||
| 823 | * Optimize a size for some browsers (phone, smarphone, ...) |
||
| 824 | * |
||
| 825 | * @param int $size Size we want |
||
| 826 | * @param string $type Type of optimizing: |
||
| 827 | * '' = function used to define a size for truncation |
||
| 828 | * 'width' = function is used to define a width |
||
| 829 | * @return int New size after optimizing |
||
| 830 | */ |
||
| 831 | static function dol_size($size, $type = '') |
||
| 832 | {
|
||
| 833 | //global Globals::$conf; |
||
| 834 | if (empty(Globals::$conf->dol_optimize_smallscreen)) |
||
| 835 | return $size; |
||
| 836 | if ($type == 'width' && $size > 250) |
||
| 837 | return 250; |
||
| 838 | else |
||
| 839 | return 10; |
||
| 840 | } |
||
| 841 | |||
| 842 | /** |
||
| 843 | * Clean a string to use it as a file name |
||
| 844 | * |
||
| 845 | * @param string $str String to clean |
||
| 846 | * @param string $newstr String to replace bad chars with |
||
| 847 | * @param int $unaccent 1=Remove also accent (default), 0 do not remove them |
||
| 848 | * @return string String cleaned (a-zA-Z_) |
||
| 849 | * |
||
| 850 | * @see dol_string_nospecial, dol_string_unaccent, dol_sanitizePathName |
||
| 851 | */ |
||
| 852 | static function dol_sanitizeFileName($str, $newstr = '_', $unaccent = 1) |
||
| 853 | {
|
||
| 854 | $filesystem_forbidden_chars = array('<', '>', '/', '\\', '?', '*', '|', '"', '°');
|
||
| 855 | return dol_string_nospecial($unaccent ? dol_string_unaccent($str) : $str, $newstr, $filesystem_forbidden_chars); |
||
| 856 | } |
||
| 857 | |||
| 858 | /** |
||
| 859 | * Clean a string to use it as a path name |
||
| 860 | * |
||
| 861 | * @param string $str String to clean |
||
| 862 | * @param string $newstr String to replace bad chars with |
||
| 863 | * @param int $unaccent 1=Remove also accent (default), 0 do not remove them |
||
| 864 | * @return string String cleaned (a-zA-Z_) |
||
| 865 | * |
||
| 866 | * @see dol_string_nospecial, dol_string_unaccent, dol_sanitizeFileName |
||
| 867 | */ |
||
| 868 | static function dol_sanitizePathName($str, $newstr = '_', $unaccent = 1) |
||
| 869 | {
|
||
| 870 | $filesystem_forbidden_chars = array('<', '>', '?', '*', '|', '"', '°');
|
||
| 871 | return dol_string_nospecial($unaccent ? dol_string_unaccent($str) : $str, $newstr, $filesystem_forbidden_chars); |
||
| 872 | } |
||
| 873 | |||
| 874 | /** |
||
| 875 | * Clean a string from all accent characters to be used as ref, login or by dol_sanitizeFileName |
||
| 876 | * |
||
| 877 | * @param string $str String to clean |
||
| 878 | * @return string Cleaned string |
||
| 879 | * |
||
| 880 | * @see dol_sanitizeFilename, dol_string_nospecial |
||
| 881 | */ |
||
| 882 | static function dol_string_unaccent($str) |
||
| 883 | {
|
||
| 884 | if (utf8_check($str)) {
|
||
| 885 | // See http://www.utf8-chartable.de/ |
||
| 886 | $string = rawurlencode($str); |
||
| 887 | $replacements = array( |
||
| 888 | '%C3%80' => 'A', '%C3%81' => 'A', '%C3%82' => 'A', '%C3%83' => 'A', '%C3%84' => 'A', '%C3%85' => 'A', |
||
| 889 | '%C3%88' => 'E', '%C3%89' => 'E', '%C3%8A' => 'E', '%C3%8B' => 'E', |
||
| 890 | '%C3%8C' => 'I', '%C3%8D' => 'I', '%C3%8E' => 'I', '%C3%8F' => 'I', |
||
| 891 | '%C3%92' => 'O', '%C3%93' => 'O', '%C3%94' => 'O', '%C3%95' => 'O', '%C3%96' => 'O', |
||
| 892 | '%C3%99' => 'U', '%C3%9A' => 'U', '%C3%9B' => 'U', '%C3%9C' => 'U', |
||
| 893 | '%C3%A0' => 'a', '%C3%A1' => 'a', '%C3%A2' => 'a', '%C3%A3' => 'a', '%C3%A4' => 'a', '%C3%A5' => 'a', |
||
| 894 | '%C3%A7' => 'c', |
||
| 895 | '%C3%A8' => 'e', '%C3%A9' => 'e', '%C3%AA' => 'e', '%C3%AB' => 'e', |
||
| 896 | '%C3%AC' => 'i', '%C3%AD' => 'i', '%C3%AE' => 'i', '%C3%AF' => 'i', |
||
| 897 | '%C3%B1' => 'n', |
||
| 898 | '%C3%B2' => 'o', '%C3%B3' => 'o', '%C3%B4' => 'o', '%C3%B5' => 'o', '%C3%B6' => 'o', |
||
| 899 | '%C3%B9' => 'u', '%C3%BA' => 'u', '%C3%BB' => 'u', '%C3%BC' => 'u', |
||
| 900 | '%C3%BF' => 'y' |
||
| 901 | ); |
||
| 902 | $string = strtr($string, $replacements); |
||
| 903 | return rawurldecode($string); |
||
| 904 | } else {
|
||
| 905 | // See http://www.ascii-code.com/ |
||
| 906 | $string = strtr( |
||
| 907 | $str, "\xC0\xC1\xC2\xC3\xC4\xC5\xC7 |
||
| 908 | \xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1 |
||
| 909 | \xD2\xD3\xD4\xD5\xD8\xD9\xDA\xDB\xDD |
||
| 910 | \xE0\xE1\xE2\xE3\xE4\xE5\xE7\xE8\xE9\xEA\xEB |
||
| 911 | \xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF8 |
||
| 912 | \xF9\xFA\xFB\xFC\xFD\xFF", "AAAAAAC |
||
| 913 | EEEEIIIIDN |
||
| 914 | OOOOOUUUY |
||
| 915 | aaaaaaceeee |
||
| 916 | iiiidnooooo |
||
| 917 | uuuuyy" |
||
| 918 | ); |
||
| 919 | $string = strtr($string, array("\xC4" => "Ae", "\xC6" => "AE", "\xD6" => "Oe", "\xDC" => "Ue", "\xDE" => "TH", "\xDF" => "ss", "\xE4" => "ae", "\xE6" => "ae", "\xF6" => "oe", "\xFC" => "ue", "\xFE" => "th"));
|
||
| 920 | return $string; |
||
| 921 | } |
||
| 922 | } |
||
| 923 | |||
| 924 | /** |
||
| 925 | * Clean a string from all punctuation characters to use it as a ref or login. |
||
| 926 | * This is a more complete static function than dol_sanitizeFileName. |
||
| 927 | * |
||
| 928 | * @param string $str String to clean |
||
| 929 | * @param string $newstr String to replace forbidden chars with |
||
| 930 | * @param array $badcharstoreplace List of forbidden characters |
||
| 931 | * @return string Cleaned string |
||
| 932 | * |
||
| 933 | * @see dol_sanitizeFilename, dol_string_unaccent |
||
| 934 | */ |
||
| 935 | static function dol_string_nospecial($str, $newstr = '_', $badcharstoreplace = '') |
||
| 936 | {
|
||
| 937 | $forbidden_chars_to_replace = array(" ", "'", "/", "\\", ":", "*", "?", "\"", "<", ">", "|", "[", "]", ",", ";", "=", '°'); // more complete than dol_sanitizeFileName
|
||
| 938 | $forbidden_chars_to_remove = array(); |
||
| 939 | if (is_array($badcharstoreplace)) |
||
| 940 | $forbidden_chars_to_replace = $badcharstoreplace; |
||
| 941 | //$forbidden_chars_to_remove=array("(",")");
|
||
| 942 | |||
| 943 | return str_replace($forbidden_chars_to_replace, $newstr, str_replace($forbidden_chars_to_remove, "", $str)); |
||
| 944 | } |
||
| 945 | |||
| 946 | /** |
||
| 947 | * Encode string for xml usage |
||
| 948 | * |
||
| 949 | * @param string $string String to encode |
||
| 950 | * @return string String encoded |
||
| 951 | */ |
||
| 952 | static function dolEscapeXML($string) |
||
| 953 | {
|
||
| 954 | return strtr($string, array('\'' => ''', '"' => '"', '&' => '&', '<' => '<', '>' => '>'));
|
||
| 955 | } |
||
| 956 | |||
| 957 | /** |
||
| 958 | * Returns text escaped for inclusion into javascript code |
||
| 959 | * |
||
| 960 | * @param string $stringtoescape String to escape |
||
| 961 | * @param int $mode 0=Escape also ' and " into ', 1=Escape ' but not " for usage into 'string', 2=Escape " but not ' for usage into "string", 3=Escape ' and " with \ |
||
| 962 | * @param int $noescapebackslashn 0=Escape also \n. 1=Do not escape \n. |
||
| 963 | * @return string Escaped string. Both ' and " are escaped into ' if they are escaped. |
||
| 964 | */ |
||
| 965 | static function dol_escape_js($stringtoescape, $mode = 0, $noescapebackslashn = 0) |
||
| 966 | {
|
||
| 967 | // escape quotes and backslashes, newlines, etc. |
||
| 968 | $substitjs = array("'" => "\\'", "\r" => '\\r');
|
||
| 969 | //$substitjs['</']='<\/'; // We removed this. Should be useless. |
||
| 970 | if (empty($noescapebackslashn)) {
|
||
| 971 | $substitjs["\n"] = '\\n'; |
||
| 972 | $substitjs['\\'] = '\\\\'; |
||
| 973 | } |
||
| 974 | if (empty($mode)) {
|
||
| 975 | $substitjs["'"] = "\\'"; |
||
| 976 | $substitjs['"'] = "\\'"; |
||
| 977 | } else if ($mode == 1) |
||
| 978 | $substitjs["'"] = "\\'"; |
||
| 979 | else if ($mode == 2) {
|
||
| 980 | $substitjs['"'] = '\\"'; |
||
| 981 | } else if ($mode == 3) {
|
||
| 982 | $substitjs["'"] = "\\'"; |
||
| 983 | $substitjs['"'] = "\\\""; |
||
| 984 | } |
||
| 985 | return strtr($stringtoescape, $substitjs); |
||
| 986 | } |
||
| 987 | |||
| 988 | /** |
||
| 989 | * Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields. |
||
| 990 | * |
||
| 991 | * @param string $stringtoescape String to escape |
||
| 992 | * @param int $keepb 1=Preserve b tags (otherwise, remove them) |
||
| 993 | * @param int $keepn 1=Preserve \r\n strings (otherwise, replace them with escaped value) |
||
| 994 | * @return string Escaped string |
||
| 995 | * @see dol_string_nohtmltag, dol_string_nospecial, dol_string_unaccent |
||
| 996 | */ |
||
| 997 | static function dol_escape_htmltag($stringtoescape, $keepb = 0, $keepn = 0) |
||
| 998 | {
|
||
| 999 | // escape quotes and backslashes, newlines, etc. |
||
| 1000 | $tmp = html_entity_decode($stringtoescape, ENT_COMPAT, 'UTF-8'); // TODO Use htmlspecialchars_decode instead, that make only required change for html tags |
||
| 1001 | if (!$keepb) |
||
| 1002 | $tmp = strtr($tmp, array("<b>" => '', '</b>' => ''));
|
||
| 1003 | if (!$keepn) |
||
| 1004 | $tmp = strtr($tmp, array("\r" => '\\r', "\n" => '\\n'));
|
||
| 1005 | return htmlentities($tmp, ENT_COMPAT, 'UTF-8'); // TODO Use htmlspecialchars instead, that make only required change for html tags |
||
| 1006 | } |
||
| 1007 | |||
| 1008 | /** |
||
| 1009 | * Convert a string to lower. Never use strtolower because it does not works with UTF8 strings. |
||
| 1010 | * |
||
| 1011 | * @param string $utf8_string String to encode |
||
| 1012 | * @return string String converted |
||
| 1013 | */ |
||
| 1014 | static function dol_strtolower($utf8_string) |
||
| 1015 | {
|
||
| 1016 | return mb_strtolower($utf8_string, "UTF-8"); |
||
| 1017 | } |
||
| 1018 | |||
| 1019 | /** |
||
| 1020 | * Convert a string to upper. Never use strtolower because it does not works with UTF8 strings. |
||
| 1021 | * |
||
| 1022 | * @param string $utf8_string String to encode |
||
| 1023 | * @return string String converted |
||
| 1024 | */ |
||
| 1025 | static function dol_strtoupper($utf8_string) |
||
| 1026 | {
|
||
| 1027 | return mb_strtoupper($utf8_string, "UTF-8"); |
||
| 1028 | } |
||
| 1029 | |||
| 1030 | /** |
||
| 1031 | * Write log message into outputs. Possible outputs can be: |
||
| 1032 | * SYSLOG_HANDLERS = ["mod_syslog_file"] file name is then defined by SYSLOG_FILE |
||
| 1033 | * SYSLOG_HANDLERS = ["mod_syslog_syslog"] facility is then defined by SYSLOG_FACILITY |
||
| 1034 | * Warning, syslog functions are bugged on Windows, generating memory protection faults. To solve |
||
| 1035 | * this, use logging to files instead of syslog (see setup of module). |
||
| 1036 | * Note: If constant 'SYSLOG_FILE_NO_ERROR' defined, we never output any error message when writing to log fails. |
||
| 1037 | * Note: You can get log message into html sources by adding parameter &logtohtml=1 (constant MAIN_LOGTOHTML must be set) |
||
| 1038 | * This static function works only if syslog module is enabled. |
||
| 1039 | * This must not use any call to other static function calling AlDolUtils::dol_syslog (avoid infinite loop). |
||
| 1040 | * |
||
| 1041 | * @param string $message Line to log. ''=Show nothing |
||
| 1042 | * @param int $level Log level |
||
| 1043 | * On Windows LOG_ERR=4, LOG_WARNING=5, LOG_NOTICE=LOG_INFO=6, LOG_DEBUG=6 si define_syslog_variables ou PHP 5.3+, 7 si dolibarr |
||
| 1044 | * On Linux LOG_ERR=3, LOG_WARNING=4, LOG_INFO=6, LOG_DEBUG=7 |
||
| 1045 | * @param int $ident 1=Increase ident of 1, -1=Decrease ident of 1 |
||
| 1046 | * @param string $suffixinfilename When output is a file, append this suffix into default log filename. |
||
| 1047 | * @param string $restricttologhandler Output log only for this log handler |
||
| 1048 | * @return void |
||
| 1049 | */ |
||
| 1050 | static function dol_syslog($message, $level = LOG_INFO, $ident = 0, $suffixinfilename = '', $restricttologhandler = '') |
||
| 1051 | {
|
||
| 1052 | // global Globals::$conf, $user; |
||
| 1053 | // If syslog module enabled |
||
| 1054 | if (empty(Globals::$conf->syslog->enabled)) |
||
| 1055 | return; |
||
| 1056 | |||
| 1057 | if ($ident < 0) {
|
||
| 1058 | foreach (Globals::$conf->loghandlers as $loghandlerinstance) {
|
||
| 1059 | $loghandlerinstance->setIdent($ident); |
||
| 1060 | } |
||
| 1061 | } |
||
| 1062 | |||
| 1063 | if (!empty($message)) {
|
||
| 1064 | // Test log level |
||
| 1065 | $logLevels = array(LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG); |
||
| 1066 | if (!in_array($level, $logLevels, true)) {
|
||
| 1067 | throw new Exception('Incorrect log level');
|
||
| 1068 | } |
||
| 1069 | if ($level > Globals::$conf->global->SYSLOG_LEVEL) |
||
| 1070 | return; |
||
| 1071 | |||
| 1072 | $message = preg_replace('/password=\'[^\']*\'/', 'password=\'hidden\'', $message); // protection to avoid to have value of password in log
|
||
| 1073 | // If adding log inside HTML page is required |
||
| 1074 | if (!empty($_REQUEST['logtohtml']) && (!empty(Globals::$conf->global->MAIN_ENABLE_LOG_TO_HTML) || !empty(Globals::$conf->global->MAIN_LOGTOHTML))) { // MAIN_LOGTOHTML kept for backward compatibility
|
||
| 1075 | Globals::$conf->logbuffer[] = AlDolUtils::dol_print_date(time(), "%Y-%m-%d %H:%M:%S") . " " . $message; |
||
| 1076 | } |
||
| 1077 | |||
| 1078 | //TODO: Remove this. MAIN_ENABLE_LOG_INLINE_HTML should be deprecated and use a log handler dedicated to HTML output |
||
| 1079 | // If html log tag enabled and url parameter log defined, we show output log on HTML comments |
||
| 1080 | if (!empty(Globals::$conf->global->MAIN_ENABLE_LOG_INLINE_HTML) && !empty($_GET["log"])) {
|
||
| 1081 | print "\n\n<!-- Log start\n"; |
||
| 1082 | print $message . "\n"; |
||
| 1083 | print "Log end -->\n"; |
||
| 1084 | } |
||
| 1085 | |||
| 1086 | $data = array( |
||
| 1087 | 'message' => $message, |
||
| 1088 | 'script' => (isset($_SERVER['PHP_SELF']) ? basename($_SERVER['PHP_SELF'], '.php') : false), |
||
| 1089 | 'level' => $level, |
||
| 1090 | 'user' => ((is_object($user) && $user->id) ? $user->login : false), |
||
| 1091 | 'ip' => false |
||
| 1092 | ); |
||
| 1093 | |||
| 1094 | // This is when server run behind a reverse proxy |
||
| 1095 | if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) |
||
| 1096 | $data['ip'] = $_SERVER['HTTP_X_FORWARDED_FOR'] . (empty($_SERVER["REMOTE_ADDR"]) ? '' : '->' . $_SERVER['REMOTE_ADDR']); |
||
| 1097 | // This is when server run normally on a server |
||
| 1098 | else if (!empty($_SERVER["REMOTE_ADDR"])) |
||
| 1099 | $data['ip'] = $_SERVER['REMOTE_ADDR']; |
||
| 1100 | // This is when PHP session is ran inside a web server but not inside a client request (example: init code of apache) |
||
| 1101 | else if (!empty($_SERVER['SERVER_ADDR'])) |
||
| 1102 | $data['ip'] = $_SERVER['SERVER_ADDR']; |
||
| 1103 | // This is when PHP session is ran outside a web server, like from Windows command line (Not always defined, but useful if OS defined it). |
||
| 1104 | else if (!empty($_SERVER['COMPUTERNAME'])) |
||
| 1105 | $data['ip'] = $_SERVER['COMPUTERNAME'] . (empty($_SERVER['USERNAME']) ? '' : '@' . $_SERVER['USERNAME']); |
||
| 1106 | // This is when PHP session is ran outside a web server, like from Linux command line (Not always defined, but usefull if OS defined it). |
||
| 1107 | else if (!empty($_SERVER['LOGNAME'])) |
||
| 1108 | $data['ip'] = '???@' . $_SERVER['LOGNAME']; |
||
| 1109 | // Loop on each log handler and send output |
||
| 1110 | foreach (Globals::$conf->loghandlers as $loghandlerinstance) {
|
||
| 1111 | if ($restricttologhandler && $loghandlerinstance->code != $restricttologhandler) |
||
| 1112 | continue; |
||
| 1113 | $loghandlerinstance->export($data, $suffixinfilename); |
||
| 1114 | } |
||
| 1115 | unset($data); |
||
| 1116 | } |
||
| 1117 | |||
| 1118 | if ($ident > 0) {
|
||
| 1119 | foreach (Globals::$conf->loghandlers as $loghandlerinstance) {
|
||
| 1120 | $loghandlerinstance->setIdent($ident); |
||
| 1121 | } |
||
| 1122 | } |
||
| 1123 | } |
||
| 1124 | |||
| 1125 | /** |
||
| 1126 | * Show tab header of a card |
||
| 1127 | * |
||
| 1128 | * @param array $links Array of tabs. Currently initialized by calling a static function xxx_admin_prepare_head |
||
| 1129 | * @param string $active Active tab name (document', 'info', 'ldap', ....) |
||
| 1130 | * @param string $title Title |
||
| 1131 | * @param int $notab -1 or 0=Add tab header, 1=no tab header. If you set this to 1, using dol_fiche_end() to close tab is not required. |
||
| 1132 | * @param string $picto Add a picto on tab title |
||
| 1133 | * @param int $pictoisfullpath If 1, image path is a full path. If you set this to 1, you can use url returned by dol_buildpath('/mymodyle/img/myimg.png',1) for $picto.
|
||
| 1134 | * @param string $morehtmlright Add more html content on right of tabs title |
||
| 1135 | * @param string $morecss More Css |
||
| 1136 | * @return void |
||
| 1137 | */ |
||
| 1138 | static function dol_fiche_head($links = array(), $active = '0', $title = '', $notab = 0, $picto = '', $pictoisfullpath = 0, $morehtmlright = '', $morecss = '') |
||
| 1139 | {
|
||
| 1140 | print dol_get_fiche_head($links, $active, $title, $notab, $picto, $pictoisfullpath, $morehtmlright, $morecss); |
||
| 1141 | } |
||
| 1142 | |||
| 1143 | /** |
||
| 1144 | * Show tab header of a card |
||
| 1145 | * |
||
| 1146 | * @param array $links Array of tabs |
||
| 1147 | * @param string $active Active tab name |
||
| 1148 | * @param string $title Title |
||
| 1149 | * @param int $notab -1 or 0=Add tab header, 1=no tab header. If you set this to 1, using dol_fiche_end() to close tab is not required. |
||
| 1150 | * @param string $picto Add a picto on tab title |
||
| 1151 | * @param int $pictoisfullpath If 1, image path is a full path. If you set this to 1, you can use url returned by dol_buildpath('/mymodyle/img/myimg.png',1) for $picto.
|
||
| 1152 | * @param string $morehtmlright Add more html content on right of tabs title |
||
| 1153 | * @param string $morecss More Css |
||
| 1154 | * @return string |
||
| 1155 | */ |
||
| 1156 | static function dol_get_fiche_head($links = array(), $active = '', $title = '', $notab = 0, $picto = '', $pictoisfullpath = 0, $morehtmlright = '', $morecss = '') |
||
| 1157 | {
|
||
| 1158 | // global Globals::$conf, Globals::$langs, Globals::$hookManager; |
||
| 1159 | |||
| 1160 | $out = "\n" . '<div class="tabs" data-role="controlgroup" data-type="horizontal">' . "\n"; |
||
| 1161 | |||
| 1162 | if ($morehtmlright) {
|
||
| 1163 | $out .= '<div class="inline-block floatright tabsElem">' . $morehtmlright . '</div>'; // Output right area first so when space is missing, text is in front of tabs and not under. |
||
| 1164 | } |
||
| 1165 | |||
| 1166 | // Show title |
||
| 1167 | $showtitle = 1; |
||
| 1168 | if (!empty(Globals::$conf->dol_optimize_smallscreen)) |
||
| 1169 | $showtitle = 0; |
||
| 1170 | if (!empty($title) && $showtitle) {
|
||
| 1171 | $limittitle = 30; |
||
| 1172 | $out .= '<a class="tabTitle">'; |
||
| 1173 | if ($picto) |
||
| 1174 | $out .= img_picto($title, ($pictoisfullpath ? '' : 'object_') . $picto, '', $pictoisfullpath) . ' '; |
||
| 1175 | $out .= '<span class="tabTitleText">' . dol_trunc($title, $limittitle) . '</span>'; |
||
| 1176 | $out .= '</a>'; |
||
| 1177 | } |
||
| 1178 | |||
| 1179 | // Define max of key (max may be higher than sizeof because of hole due to module disabling some tabs). |
||
| 1180 | $maxkey = -1; |
||
| 1181 | if (is_array($links) && !empty($links)) {
|
||
| 1182 | $keys = array_keys($links); |
||
| 1183 | if (count($keys)) |
||
| 1184 | $maxkey = max($keys); |
||
| 1185 | } |
||
| 1186 | |||
| 1187 | if (!empty(Globals::$conf->dol_optimize_smallscreen)) |
||
| 1188 | Globals::$conf->global->MAIN_MAXTABS_IN_CARD = 2; |
||
| 1189 | |||
| 1190 | // Show tabs |
||
| 1191 | $bactive = false; |
||
| 1192 | // if =0 we don't use the feature |
||
| 1193 | $limittoshow = (empty(Globals::$conf->global->MAIN_MAXTABS_IN_CARD) ? 99 : Globals::$conf->global->MAIN_MAXTABS_IN_CARD); |
||
| 1194 | $displaytab = 0; |
||
| 1195 | $nbintab = 0; |
||
| 1196 | $popuptab = 0; |
||
| 1197 | $outmore = ''; |
||
| 1198 | for ($i = 0; $i <= $maxkey; $i++) {
|
||
| 1199 | if ((is_numeric($active) && $i == $active) || (!empty($links[$i][2]) && !is_numeric($active) && $active == $links[$i][2])) {
|
||
| 1200 | // If active tab is already present |
||
| 1201 | if ($i >= $limittoshow) |
||
| 1202 | $limittoshow--; |
||
| 1203 | } |
||
| 1204 | } |
||
| 1205 | |||
| 1206 | for ($i = 0; $i <= $maxkey; $i++) {
|
||
| 1207 | if ((is_numeric($active) && $i == $active) || (!empty($links[$i][2]) && !is_numeric($active) && $active == $links[$i][2])) {
|
||
| 1208 | $isactive = true; |
||
| 1209 | $bactive = true; |
||
| 1210 | } else {
|
||
| 1211 | $isactive = false; |
||
| 1212 | } |
||
| 1213 | |||
| 1214 | if ($i < $limittoshow || $isactive) {
|
||
| 1215 | $out .= '<div class="inline-block tabsElem' . ($isactive ? ' tabsElemActive' : '') . ((!$isactive && !empty(Globals::$conf->global->MAIN_HIDE_INACTIVETAB_ON_PRINT)) ? ' hideonprint' : '') . '"><!-- id tab = ' . (empty($links[$i][2]) ? '' : $links[$i][2]) . ' -->'; |
||
| 1216 | if (isset($links[$i][2]) && $links[$i][2] == 'image') {
|
||
| 1217 | if (!empty($links[$i][0])) {
|
||
| 1218 | $out .= '<a class="tabimage' . ($morecss ? ' ' . $morecss : '') . '" href="' . $links[$i][0] . '">' . $links[$i][1] . '</a>' . "\n"; |
||
| 1219 | } else {
|
||
| 1220 | $out .= '<span class="tabspan">' . $links[$i][1] . '</span>' . "\n"; |
||
| 1221 | } |
||
| 1222 | } else if (!empty($links[$i][1])) {
|
||
| 1223 | //print "x $i $active ".$links[$i][2]." z"; |
||
| 1224 | if ($isactive) {
|
||
| 1225 | $out .= '<a' . (!empty($links[$i][2]) ? ' id="' . $links[$i][2] . '"' : '') . ' class="tabactive tab inline-block' . ($morecss ? ' ' . $morecss : '') . '" href="' . $links[$i][0] . '">'; |
||
| 1226 | $out .= $links[$i][1]; |
||
| 1227 | $out .= '</a>' . "\n"; |
||
| 1228 | } else {
|
||
| 1229 | $out .= '<a' . (!empty($links[$i][2]) ? ' id="' . $links[$i][2] . '"' : '') . ' class="tabunactive tab inline-block' . ($morecss ? ' ' . $morecss : '') . '" href="' . $links[$i][0] . '">'; |
||
| 1230 | $out .= $links[$i][1]; |
||
| 1231 | $out .= '</a>' . "\n"; |
||
| 1232 | } |
||
| 1233 | } |
||
| 1234 | $out .= '</div>'; |
||
| 1235 | } else {
|
||
| 1236 | // The popup with the other tabs |
||
| 1237 | if (!$popuptab) {
|
||
| 1238 | $popuptab = 1; |
||
| 1239 | $outmore .= '<div class="popuptabset wordwrap">'; // The css used to hide/show popup |
||
| 1240 | } |
||
| 1241 | $outmore .= '<div class="popuptab wordwrap" style="display:inherit;">'; |
||
| 1242 | if (isset($links[$i][2]) && $links[$i][2] == 'image') {
|
||
| 1243 | if (!empty($links[$i][0])) |
||
| 1244 | $outmore .= '<a class="tabimage' . ($morecss ? ' ' . $morecss : '') . '" href="' . $links[$i][0] . '">' . $links[$i][1] . '</a>' . "\n"; |
||
| 1245 | else |
||
| 1246 | $outmore .= '<span class="tabspan">' . $links[$i][1] . '</span>' . "\n"; |
||
| 1247 | } |
||
| 1248 | else if (!empty($links[$i][1])) {
|
||
| 1249 | $outmore .= '<a' . (!empty($links[$i][2]) ? ' id="' . $links[$i][2] . '"' : '') . ' class="wordwrap inline-block' . ($morecss ? ' ' . $morecss : '') . '" href="' . $links[$i][0] . '">'; |
||
| 1250 | $outmore .= preg_replace('/([a-z])\/([a-z])/i', '\\1 / \\2', $links[$i][1]); // Replace x/y with x / y to allow wrap on long composed texts.
|
||
| 1251 | $outmore .= '</a>' . "\n"; |
||
| 1252 | } |
||
| 1253 | $outmore .= '</div>'; |
||
| 1254 | |||
| 1255 | $nbintab++; |
||
| 1256 | } |
||
| 1257 | $displaytab = $i; |
||
| 1258 | } |
||
| 1259 | if ($popuptab) |
||
| 1260 | $outmore .= '</div>'; |
||
| 1261 | |||
| 1262 | if ($displaytab > $limittoshow) {
|
||
| 1263 | $left = (Globals::$langs->trans("DIRECTION") == 'rtl' ? 'right' : 'left');
|
||
| 1264 | $right = (Globals::$langs->trans("DIRECTION") == 'rtl' ? 'left' : 'right');
|
||
| 1265 | |||
| 1266 | $tabsname = str_replace("@", "", $picto);
|
||
| 1267 | $out .= '<div id="moretabs' . $tabsname . '" class="inline-block tabsElem">'; |
||
| 1268 | $out .= '<a href="#" class="tab moretab inline-block tabunactive reposition">' . Globals::$langs->trans("More") . '... (' . $nbintab . ')</a>';
|
||
| 1269 | $out .= '<div id="moretabsList' . $tabsname . '" style="position: absolute; ' . $left . ': -999em; text-align: ' . $left . '; margin:0px; padding:2px">'; |
||
| 1270 | $out .= $outmore; |
||
| 1271 | $out .= '</div>'; |
||
| 1272 | $out .= '<div></div>'; |
||
| 1273 | $out .= "</div>\n"; |
||
| 1274 | |||
| 1275 | $out .= "<script>"; |
||
| 1276 | $out .= "$('#moretabs" . $tabsname . "').mouseenter( function() { console.log('mouseenter " . $left . "'); $('#moretabsList" . $tabsname . "').css('" . $left . "','auto');});";
|
||
| 1277 | $out .= "$('#moretabs" . $tabsname . "').mouseleave( function() { console.log('mouseleave " . $left . "'); $('#moretabsList" . $tabsname . "').css('" . $left . "','-999em');});";
|
||
| 1278 | $out .= "</script>"; |
||
| 1279 | } |
||
| 1280 | |||
| 1281 | $out .= "</div>\n"; |
||
| 1282 | |||
| 1283 | if (!$notab || $notab == -1) |
||
| 1284 | $out .= "\n" . '<div class="tabBar' . ($notab == -1 ? '' : ' tabBarWithBottom') . '">' . "\n"; |
||
| 1285 | |||
| 1286 | $parameters = array('tabname' => $active, 'out' => $out);
|
||
| 1287 | $reshook = Globals::$hookManager->executeHooks('printTabsHead', $parameters); // This hook usage is called just before output the head of tabs. Take also a look at "completeTabsHead"
|
||
| 1288 | if ($reshook > 0) {
|
||
| 1289 | $out = Globals::$hookManager->resPrint; |
||
| 1290 | } |
||
| 1291 | |||
| 1292 | return $out; |
||
| 1293 | } |
||
| 1294 | |||
| 1295 | /** |
||
| 1296 | * Show tab footer of a card |
||
| 1297 | * |
||
| 1298 | * @param int $notab -1 or 0=Add tab footer, 1=no tab footer |
||
| 1299 | * @return void |
||
| 1300 | */ |
||
| 1301 | static function dol_fiche_end($notab = 0) |
||
| 1302 | {
|
||
| 1303 | print dol_get_fiche_end($notab); |
||
| 1304 | } |
||
| 1305 | |||
| 1306 | /** |
||
| 1307 | * Return tab footer of a card |
||
| 1308 | * |
||
| 1309 | * @param int $notab -1 or 0=Add tab footer, 1=no tab footer |
||
| 1310 | * @return string |
||
| 1311 | */ |
||
| 1312 | static function dol_get_fiche_end($notab = 0) |
||
| 1313 | {
|
||
| 1314 | if (!$notab || $notab == -1) |
||
| 1315 | return "\n</div>\n"; |
||
| 1316 | else |
||
| 1317 | return ''; |
||
| 1318 | } |
||
| 1319 | |||
| 1320 | /** |
||
| 1321 | * Show tab footer of a card. |
||
| 1322 | * Note: $object->next_prev_filter can be set to restrict select to find next or previous record by $form->showrefnav. |
||
| 1323 | * |
||
| 1324 | * @param Object $object Object to show |
||
| 1325 | * @param string $paramid Name of parameter to use to name the id into the URL next/previous link |
||
| 1326 | * @param string $morehtml More html content to output just before the nav bar |
||
| 1327 | * @param int $shownav Show Condition (navigation is shown if value is 1) |
||
| 1328 | * @param string $fieldid Nom du champ en base a utiliser pour select next et previous (we make the select max and min on this field). Use 'none' for no prev/next search. |
||
| 1329 | * @param string $fieldref Nom du champ objet ref (object->ref) a utiliser pour select next et previous |
||
| 1330 | * @param string $morehtmlref More html to show after ref |
||
| 1331 | * @param string $moreparam More param to add in nav link url. |
||
| 1332 | * @param int $nodbprefix Do not include DB prefix to forge table name |
||
| 1333 | * @param string $morehtmlleft More html code to show before ref |
||
| 1334 | * @param string $morehtmlstatus More html code to show under navigation arrows |
||
| 1335 | * @param int $onlybanner Put this to 1, if the card will contains only a banner (this add css 'arearefnobottom' on div) |
||
| 1336 | * @param string $morehtmlright More html code to show before navigation arrows |
||
| 1337 | * @return void |
||
| 1338 | */ |
||
| 1339 | static function dol_banner_tab($object, $paramid, $morehtml = '', $shownav = 1, $fieldid = 'rowid', $fieldref = 'ref', $morehtmlref = '', $moreparam = '', $nodbprefix = 0, $morehtmlleft = '', $morehtmlstatus = '', $onlybanner = 0, $morehtmlright = '') |
||
| 1340 | {
|
||
| 1341 | // global Globals::$conf, $form, $user, Globals::$langs; |
||
| 1342 | |||
| 1343 | $error = 0; |
||
| 1344 | |||
| 1345 | $maxvisiblephotos = 1; |
||
| 1346 | $showimage = 1; |
||
| 1347 | $entity = (empty($object->entity) ? Globals::$conf->entity : $object->entity); |
||
| 1348 | $showbarcode = empty(Globals::$conf->barcode->enabled) ? 0 : ($object->barcode ? 1 : 0); |
||
| 1349 | if (!empty(Globals::$conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->barcode->lire_advance)) |
||
| 1350 | $showbarcode = 0; |
||
| 1351 | $modulepart = 'unknown'; |
||
| 1352 | |||
| 1353 | if ($object->element == 'societe') {
|
||
| 1354 | $modulepart = 'societe'; |
||
| 1355 | } |
||
| 1356 | if ($object->element == 'contact') {
|
||
| 1357 | $modulepart = 'contact'; |
||
| 1358 | } |
||
| 1359 | if ($object->element == 'member') {
|
||
| 1360 | $modulepart = 'memberphoto'; |
||
| 1361 | } |
||
| 1362 | if ($object->element == 'user') {
|
||
| 1363 | $modulepart = 'userphoto'; |
||
| 1364 | } |
||
| 1365 | if ($object->element == 'product') {
|
||
| 1366 | $modulepart = 'product'; |
||
| 1367 | } |
||
| 1368 | |||
| 1369 | if (class_exists("Imagick")) {
|
||
| 1370 | if ($object->element == 'propal') {
|
||
| 1371 | $modulepart = 'propal'; |
||
| 1372 | } |
||
| 1373 | if ($object->element == 'commande') {
|
||
| 1374 | $modulepart = 'commande'; |
||
| 1375 | } |
||
| 1376 | if ($object->element == 'facture') {
|
||
| 1377 | $modulepart = 'facture'; |
||
| 1378 | } |
||
| 1379 | if ($object->element == 'fichinter') {
|
||
| 1380 | $modulepart = 'ficheinter'; |
||
| 1381 | } |
||
| 1382 | if ($object->element == 'contrat') {
|
||
| 1383 | $modulepart = 'contract'; |
||
| 1384 | } |
||
| 1385 | if ($object->element == 'supplier_proposal') {
|
||
| 1386 | $modulepart = 'supplier_proposal'; |
||
| 1387 | } |
||
| 1388 | if ($object->element == 'order_supplier') {
|
||
| 1389 | $modulepart = 'supplier_order'; |
||
| 1390 | } |
||
| 1391 | if ($object->element == 'invoice_supplier') {
|
||
| 1392 | $modulepart = 'supplier_invoice'; |
||
| 1393 | } |
||
| 1394 | if ($object->element == 'expensereport') {
|
||
| 1395 | $modulepart = 'expensereport'; |
||
| 1396 | } |
||
| 1397 | } |
||
| 1398 | |||
| 1399 | if ($object->element == 'product') {
|
||
| 1400 | $width = 80; |
||
| 1401 | $cssclass = 'photoref'; |
||
| 1402 | $showimage = $object->is_photo_available(Globals::$conf->product->multidir_output[$entity]); |
||
| 1403 | $maxvisiblephotos = (isset(Globals::$conf->global->PRODUCT_MAX_VISIBLE_PHOTO) ? Globals::$conf->global->PRODUCT_MAX_VISIBLE_PHOTO : 5); |
||
| 1404 | if (Globals::$conf->browser->layout == 'phone') {
|
||
| 1405 | $maxvisiblephotos = 1; |
||
| 1406 | } |
||
| 1407 | if ($showimage) {
|
||
| 1408 | $morehtmlleft .= '<div class="floatleft inline-block valignmiddle divphotoref">' . $object->show_photos('product', Globals::$conf->product->multidir_output[$entity], 'small', $maxvisiblephotos, 0, 0, 0, $width, 0) . '</div>';
|
||
| 1409 | } else {
|
||
| 1410 | if (!empty(Globals::$conf->global->PRODUCT_NODISPLAYIFNOPHOTO)) {
|
||
| 1411 | $nophoto = ''; |
||
| 1412 | $morehtmlleft .= '<div class="floatleft inline-block valignmiddle divphotoref"></div>'; |
||
| 1413 | } |
||
| 1414 | //elseif (Globals::$conf->browser->layout != 'phone') { // Show no photo link
|
||
| 1415 | $nophoto = '/public/theme/common/nophoto.png'; |
||
| 1416 | // $morehtmlleft .= '<div class="floatleft inline-block valignmiddle divphotoref"><img class="photo' . $modulepart . ($cssclass ? ' ' . $cssclass : '') . '" alt="No photo" border="0"' . ($width ? ' width="' . $width . '"' : '') . ' src="' . DOL_BASE_URI . $nophoto . '"></div>'; |
||
| 1417 | $morehtmlleft .= '<div class="floatleft inline-block valignmiddle divphotoref"><img class="photo' . $modulepart . ($cssclass ? ' ' . $cssclass : '') . '" alt="No photo" border="0"' . ($width ? ' width="' . $width . '"' : '') . ' src="' . DOL_BASE_URI . $nophoto . '"></div>'; |
||
| 1418 | //} |
||
| 1419 | } |
||
| 1420 | } elseif ($object->element == 'ticket') {
|
||
| 1421 | $width = 80; |
||
| 1422 | $cssclass = 'photoref'; |
||
| 1423 | $showimage = $object->is_photo_available(Globals::$conf->ticket->multidir_output[$entity] . '/' . $object->track_id); |
||
| 1424 | $maxvisiblephotos = (isset(Globals::$conf->global->TICKETSUP_MAX_VISIBLE_PHOTO) ? Globals::$conf->global->TICKETSUP_MAX_VISIBLE_PHOTO : 2); |
||
| 1425 | if (Globals::$conf->browser->layout == 'phone') {
|
||
| 1426 | $maxvisiblephotos = 1; |
||
| 1427 | } |
||
| 1428 | if ($showimage) {
|
||
| 1429 | $morehtmlleft .= '<div class="floatleft inline-block valignmiddle divphotoref">' . $object->show_photos('ticket', Globals::$conf->ticket->multidir_output[$entity], 'small', $maxvisiblephotos, 0, 0, 0, $width, 0) . '</div>';
|
||
| 1430 | } else {
|
||
| 1431 | if (!empty(Globals::$conf->global->TICKETSUP_NODISPLAYIFNOPHOTO)) {
|
||
| 1432 | $nophoto = ''; |
||
| 1433 | $morehtmlleft .= '<div class="floatleft inline-block valignmiddle divphotoref"></div>'; |
||
| 1434 | } |
||
| 1435 | //elseif (Globals::$conf->browser->layout != 'phone') { // Show no photo link
|
||
| 1436 | $nophoto = '/public/theme/common/nophoto.png'; |
||
| 1437 | //$morehtmlleft .= '<div class="floatleft inline-block valignmiddle divphotoref"><img class="photo' . $modulepart . ($cssclass ? ' ' . $cssclass : '') . '" alt="No photo" border="0"' . ($width ? ' width="' . $width . '"' : '') . ' src="' . DOL_BASE_URI . $nophoto . '"></div>'; |
||
| 1438 | $morehtmlleft .= '<div class="floatleft inline-block valignmiddle divphotoref"><img class="photo' . $modulepart . ($cssclass ? ' ' . $cssclass : '') . '" alt="No photo" border="0"' . ($width ? ' width="' . $width . '"' : '') . ' src="' . DOL_BASE_URI . $nophoto . '"></div>'; |
||
| 1439 | //} |
||
| 1440 | } |
||
| 1441 | } else {
|
||
| 1442 | if ($showimage) {
|
||
| 1443 | if ($modulepart != 'unknown') {
|
||
| 1444 | $phototoshow = ''; |
||
| 1445 | // Check if a preview file is available |
||
| 1446 | if (in_array($modulepart, array('propal', 'commande', 'facture', 'ficheinter', 'contract', 'supplier_order', 'supplier_proposal', 'supplier_invoice', 'expensereport')) && class_exists("Imagick")) {
|
||
| 1447 | $objectref = dol_sanitizeFileName($object->ref); |
||
| 1448 | $dir_output = (empty(Globals::$conf->$modulepart->multidir_output[$entity]) ? Globals::$conf->$modulepart->dir_output : Globals::$conf->$modulepart->multidir_output[$entity]) . "/"; |
||
| 1449 | if (in_array($modulepart, array('invoice_supplier', 'supplier_invoice'))) {
|
||
| 1450 | $subdir = get_exdir($object->id, 2, 0, 1, $object, $modulepart); |
||
| 1451 | $subdir .= ((!empty($subdir) && !preg_match('/\/$/', $subdir)) ? '/' : '') . $objectref; // the objectref dir is not included into get_exdir when used with level=2, so we add it at end
|
||
| 1452 | } else {
|
||
| 1453 | $subdir = get_exdir($object->id, 0, 0, 1, $object, $modulepart); |
||
| 1454 | } |
||
| 1455 | if (empty($subdir)) |
||
| 1456 | $subdir = 'errorgettingsubdirofobject'; // Protection to avoid to return empty path |
||
| 1457 | |||
| 1458 | $filepath = $dir_output . $subdir . "/"; |
||
| 1459 | |||
| 1460 | $file = $filepath . $objectref . ".pdf"; |
||
| 1461 | $relativepath = $subdir . '/' . $objectref . '.pdf'; |
||
| 1462 | |||
| 1463 | // Define path to preview pdf file (preview precompiled "file.ext" are "file.ext_preview.png") |
||
| 1464 | $fileimage = $file . '_preview.png'; // If PDF has 1 page |
||
| 1465 | $fileimagebis = $file . '_preview-0.png'; // If PDF has more than one page |
||
| 1466 | $relativepathimage = $relativepath . '_preview.png'; |
||
| 1467 | |||
| 1468 | // Si fichier PDF existe |
||
| 1469 | if (file_exists($file)) {
|
||
| 1470 | $encfile = urlencode($file); |
||
| 1471 | // Conversion du PDF en image png si fichier png non existant |
||
| 1472 | if ((!file_exists($fileimage) || (filemtime($fileimage) < filemtime($file))) && (!file_exists($fileimagebis) || (filemtime($fileimagebis) < filemtime($file))) |
||
| 1473 | ) {
|
||
| 1474 | if (empty(Globals::$conf->global->MAIN_DISABLE_PDF_THUMBS)) { // If you experienc trouble with pdf thumb generation and imagick, you can disable here.
|
||
| 1475 | include_once DOL_BASE_PATH . '/core/lib/files.lib.php'; |
||
| 1476 | $ret = dol_convert_file($file, 'png', $fileimage); |
||
| 1477 | if ($ret < 0) |
||
| 1478 | $error++; |
||
| 1479 | } |
||
| 1480 | } |
||
| 1481 | |||
| 1482 | $heightforphotref = 70; |
||
| 1483 | if (!empty(Globals::$conf->dol_optimize_smallscreen)) |
||
| 1484 | $heightforphotref = 60; |
||
| 1485 | // Si fichier png PDF d'1 page trouve |
||
| 1486 | if (file_exists($fileimage)) {
|
||
| 1487 | $phototoshow = '<div class="floatleft inline-block valignmiddle divphotoref"><div class="photoref">'; |
||
| 1488 | $phototoshow .= '<img height="' . $heightforphotref . '" class="photo photowithmargin photowithborder" src="' . DOL_BASE_URI . '/viewimage.php?modulepart=apercu' . $modulepart . '&file=' . urlencode($relativepathimage) . '">'; |
||
| 1489 | $phototoshow .= '</div></div>'; |
||
| 1490 | } |
||
| 1491 | // Si fichier png PDF de plus d'1 page trouve |
||
| 1492 | elseif (file_exists($fileimagebis)) {
|
||
| 1493 | $preview = preg_replace('/\.png/', '', $relativepathimage) . "-0.png";
|
||
| 1494 | $phototoshow = '<div class="floatleft inline-block valignmiddle divphotoref"><div class="photoref">'; |
||
| 1495 | $phototoshow .= '<img height="' . $heightforphotref . '" class="photo photowithmargin photowithborder" src="' . DOL_BASE_URI . '/viewimage.php?modulepart=apercu' . $modulepart . '&file=' . urlencode($preview) . '"><p>'; |
||
| 1496 | $phototoshow .= '</div></div>'; |
||
| 1497 | } |
||
| 1498 | } |
||
| 1499 | } else if (!$phototoshow) {
|
||
| 1500 | $phototoshow = $form->showphoto($modulepart, $object, 0, 0, 0, 'photoref', 'small', 1, 0, $maxvisiblephotos); |
||
| 1501 | } |
||
| 1502 | |||
| 1503 | if ($phototoshow) {
|
||
| 1504 | $morehtmlleft .= '<div class="floatleft inline-block valignmiddle divphotoref">'; |
||
| 1505 | $morehtmlleft .= $phototoshow; |
||
| 1506 | $morehtmlleft .= '</div>'; |
||
| 1507 | } |
||
| 1508 | } |
||
| 1509 | |||
| 1510 | if (!$phototoshow) { // Show No photo link (picto of pbject)
|
||
| 1511 | $morehtmlleft .= '<div class="floatleft inline-block valignmiddle divphotoref">'; |
||
| 1512 | if ($object->element == 'action') {
|
||
| 1513 | $width = 80; |
||
| 1514 | $cssclass = 'photorefcenter'; |
||
| 1515 | $nophoto = img_picto('', 'title_agenda', '', false, 1);
|
||
| 1516 | } else {
|
||
| 1517 | $width = 14; |
||
| 1518 | $cssclass = 'photorefcenter'; |
||
| 1519 | $picto = $object->picto; |
||
| 1520 | if ($object->element == 'project' && !$object->public) |
||
| 1521 | $picto = 'project'; // instead of projectpub |
||
| 1522 | $nophoto = img_picto('', 'object_' . $picto, '', false, 1);
|
||
| 1523 | } |
||
| 1524 | $morehtmlleft .= '<!-- No photo to show -->'; |
||
| 1525 | $morehtmlleft .= '<div class="floatleft inline-block valignmiddle divphotoref"><div class="photoref"><img class="photo' . $modulepart . ($cssclass ? ' ' . $cssclass : '') . '" alt="No photo" border="0"' . ($width ? ' width="' . $width . '"' : '') . ' src="' . $nophoto . '"></div></div>'; |
||
| 1526 | |||
| 1527 | $morehtmlleft .= '</div>'; |
||
| 1528 | } |
||
| 1529 | } |
||
| 1530 | } |
||
| 1531 | |||
| 1532 | if ($showbarcode) |
||
| 1533 | $morehtmlleft .= '<div class="floatleft inline-block valignmiddle divphotoref">' . $form->showbarcode($object) . '</div>'; |
||
| 1534 | |||
| 1535 | if ($object->element == 'societe') {
|
||
| 1536 | if (!empty(Globals::$conf->use_javascript_ajax) && $user->rights->societe->creer && !empty(Globals::$conf->global->MAIN_DIRECT_STATUS_UPDATE)) {
|
||
| 1537 | $morehtmlstatus .= ajax_object_onoff($object, 'status', 'status', 'InActivity', 'ActivityCeased'); |
||
| 1538 | } else {
|
||
| 1539 | $morehtmlstatus .= $object->getLibStatut(6); |
||
| 1540 | } |
||
| 1541 | } elseif ($object->element == 'product') {
|
||
| 1542 | //$morehtmlstatus.=Globals::$langs->trans("Status").' ('.Globals::$langs->trans("Sell").') ';
|
||
| 1543 | if (!empty(Globals::$conf->use_javascript_ajax) && $user->rights->produit->creer && !empty(Globals::$conf->global->MAIN_DIRECT_STATUS_UPDATE)) {
|
||
| 1544 | $morehtmlstatus .= ajax_object_onoff($object, 'status', 'tosell', 'ProductStatusOnSell', 'ProductStatusNotOnSell'); |
||
| 1545 | } else {
|
||
| 1546 | $morehtmlstatus .= '<span class="statusrefsell">' . $object->getLibStatut(5, 0) . '</span>'; |
||
| 1547 | } |
||
| 1548 | $morehtmlstatus .= ' '; |
||
| 1549 | //$morehtmlstatus.=Globals::$langs->trans("Status").' ('.Globals::$langs->trans("Buy").') ';
|
||
| 1550 | if (!empty(Globals::$conf->use_javascript_ajax) && $user->rights->produit->creer && !empty(Globals::$conf->global->MAIN_DIRECT_STATUS_UPDATE)) {
|
||
| 1551 | $morehtmlstatus .= ajax_object_onoff($object, 'status_buy', 'tobuy', 'ProductStatusOnBuy', 'ProductStatusNotOnBuy'); |
||
| 1552 | } else {
|
||
| 1553 | $morehtmlstatus .= '<span class="statusrefbuy">' . $object->getLibStatut(5, 1) . '</span>'; |
||
| 1554 | } |
||
| 1555 | } elseif (in_array($object->element, array('facture', 'invoice', 'invoice_supplier', 'chargesociales', 'loan'))) {
|
||
| 1556 | $tmptxt = $object->getLibStatut(6, $object->totalpaye); |
||
| 1557 | if (empty($tmptxt) || $tmptxt == $object->getLibStatut(3) || Globals::$conf->browser->layout == 'phone') |
||
| 1558 | $tmptxt = $object->getLibStatut(5, $object->totalpaye); |
||
| 1559 | $morehtmlstatus .= $tmptxt; |
||
| 1560 | } |
||
| 1561 | elseif ($object->element == 'contrat' || $object->element == 'contract') {
|
||
| 1562 | if ($object->statut == 0) |
||
| 1563 | $morehtmlstatus .= $object->getLibStatut(5); |
||
| 1564 | else |
||
| 1565 | $morehtmlstatus .= $object->getLibStatut(4); |
||
| 1566 | } |
||
| 1567 | elseif ($object->element == 'facturerec') {
|
||
| 1568 | if ($object->frequency == 0) |
||
| 1569 | $morehtmlstatus .= $object->getLibStatut(2); |
||
| 1570 | else |
||
| 1571 | $morehtmlstatus .= $object->getLibStatut(5); |
||
| 1572 | } |
||
| 1573 | elseif ($object->element == 'project_task') {
|
||
| 1574 | $object->fk_statut = 1; |
||
| 1575 | if ($object->progress > 0) |
||
| 1576 | $object->fk_statut = 2; |
||
| 1577 | if ($object->progress >= 100) |
||
| 1578 | $object->fk_statut = 3; |
||
| 1579 | $tmptxt = $object->getLibStatut(5); |
||
| 1580 | $morehtmlstatus .= $tmptxt; // No status on task |
||
| 1581 | } |
||
| 1582 | else { // Generic case
|
||
| 1583 | $tmptxt = $object->getLibStatut(6); |
||
| 1584 | if (empty($tmptxt) || $tmptxt == $object->getLibStatut(3) || Globals::$conf->browser->layout == 'phone') |
||
| 1585 | $tmptxt = $object->getLibStatut(5); |
||
| 1586 | $morehtmlstatus .= $tmptxt; |
||
| 1587 | } |
||
| 1588 | |||
| 1589 | // Add if object was dispatched "into accountancy" |
||
| 1590 | if (!empty(Globals::$conf->accounting->enabled) && in_array($object->element, array('bank', 'facture', 'invoice', 'invoice_supplier', 'expensereport'))) {
|
||
| 1591 | if (method_exists($object, 'getVentilExportCompta')) {
|
||
| 1592 | $accounted = $object->getVentilExportCompta(); |
||
| 1593 | Globals::$langs->load("accountancy");
|
||
| 1594 | $morehtmlstatus .= '</div><div class="statusref statusrefbis">' . ($accounted > 0 ? Globals::$langs->trans("Accounted") : Globals::$langs->trans("NotYetAccounted"));
|
||
| 1595 | } |
||
| 1596 | } |
||
| 1597 | |||
| 1598 | // Add alias for thirdparty |
||
| 1599 | if (!empty($object->name_alias)) |
||
| 1600 | $morehtmlref .= '<div class="refidno">' . $object->name_alias . '</div>'; |
||
| 1601 | |||
| 1602 | // Add label |
||
| 1603 | if ($object->element == 'product' || $object->element == 'bank_account' || $object->element == 'project_task') {
|
||
| 1604 | if (!empty($object->label)) |
||
| 1605 | $morehtmlref .= '<div class="refidno">' . $object->label . '</div>'; |
||
| 1606 | } |
||
| 1607 | |||
| 1608 | if (method_exists($object, 'getBannerAddress') && $object->element != 'product' && $object->element != 'bookmark' && $object->element != 'ecm_directories' && $object->element != 'ecm_files') {
|
||
| 1609 | $morehtmlref .= '<div class="refidno">'; |
||
| 1610 | $morehtmlref .= $object->getBannerAddress('refaddress', $object);
|
||
| 1611 | $morehtmlref .= '</div>'; |
||
| 1612 | } |
||
| 1613 | if (!empty(Globals::$conf->global->MAIN_SHOW_TECHNICAL_ID) && in_array($object->element, array('societe', 'contact', 'member', 'product'))) {
|
||
| 1614 | $morehtmlref .= '<div style="clear: both;"></div><div class="refidno">'; |
||
| 1615 | $morehtmlref .= Globals::$langs->trans("TechnicalID") . ': ' . $object->id;
|
||
| 1616 | $morehtmlref .= '</div>'; |
||
| 1617 | } |
||
| 1618 | |||
| 1619 | print '<div class="' . ($onlybanner ? 'arearefnobottom ' : 'arearef ') . 'heightref valignmiddle" width="100%">'; |
||
| 1620 | print $form->showrefnav($object, $paramid, $morehtml, $shownav, $fieldid, $fieldref, $morehtmlref, $moreparam, $nodbprefix, $morehtmlleft, $morehtmlstatus, $morehtmlright); |
||
| 1621 | print '</div>'; |
||
| 1622 | print '<div class="underrefbanner clearboth"></div>'; |
||
| 1623 | } |
||
| 1624 | |||
| 1625 | /** |
||
| 1626 | * Show a string with the label tag dedicated to the HTML edit field. |
||
| 1627 | * |
||
| 1628 | * @param string $langkey Translation key |
||
| 1629 | * @param string $fieldkey Key of the html select field the text refers to |
||
| 1630 | * @param int $fieldrequired 1=Field is mandatory |
||
| 1631 | * @return string |
||
| 1632 | * @deprecated Form::editfieldkey |
||
| 1633 | */ |
||
| 1634 | static function fieldLabel($langkey, $fieldkey, $fieldrequired = 0) |
||
| 1635 | {
|
||
| 1636 | // global Globals::$conf, Globals::$langs; |
||
| 1637 | $ret = ''; |
||
| 1638 | if ($fieldrequired) |
||
| 1639 | $ret .= '<span class="fieldrequired">'; |
||
| 1640 | if ((Globals::$conf->dol_use_jmobile != 4)) |
||
| 1641 | $ret .= '<label for="' . $fieldkey . '">'; |
||
| 1642 | $ret .= Globals::$langs->trans($langkey); |
||
| 1643 | if ((Globals::$conf->dol_use_jmobile != 4)) |
||
| 1644 | $ret .= '</label>'; |
||
| 1645 | if ($fieldrequired) |
||
| 1646 | $ret .= '</span>'; |
||
| 1647 | return $ret; |
||
| 1648 | } |
||
| 1649 | |||
| 1650 | /** |
||
| 1651 | * Return string to add class property on html element with pair/impair. |
||
| 1652 | * |
||
| 1653 | * @param string $var 0 or 1 |
||
| 1654 | * @param string $moreclass More class to add |
||
| 1655 | * @return string String to add class onto HTML element |
||
| 1656 | */ |
||
| 1657 | static function dol_bc($var, $moreclass = '') |
||
| 1658 | {
|
||
| 1659 | // global $bc; |
||
| 1660 | $ret = ' ' . $bc[$var]; |
||
| 1661 | if ($moreclass) |
||
| 1662 | $ret = preg_replace('/class=\"/', 'class="' . $moreclass . ' ', $ret);
|
||
| 1663 | return $ret; |
||
| 1664 | } |
||
| 1665 | |||
| 1666 | /** |
||
| 1667 | * Return a formated address (part address/zip/town/state) according to country rules |
||
| 1668 | * |
||
| 1669 | * @param Object $object A company or contact object |
||
| 1670 | * @param int $withcountry 1=Add country into address string |
||
| 1671 | * @param string $sep Separator to use to build string |
||
| 1672 | * @param Translate $outputlangs Object lang that contains language for text translation. |
||
| 1673 | * @param int $mode 0=Standard output, 1=Remove address |
||
| 1674 | * @return string Formated string |
||
| 1675 | * @see dol_print_address |
||
| 1676 | */ |
||
| 1677 | static function dol_format_address($object, $withcountry = 0, $sep = "\n", $outputlangs = '', $mode = 0) |
||
| 1678 | {
|
||
| 1679 | // global Globals::$conf, Globals::$langs; |
||
| 1680 | |||
| 1681 | $ret = ''; |
||
| 1682 | $countriesusingstate = array('AU', 'CA', 'US', 'IN', 'GB', 'ES', 'UK', 'TR'); // See also MAIN_FORCE_STATE_INTO_ADDRESS
|
||
| 1683 | // Address |
||
| 1684 | if (empty($mode)) {
|
||
| 1685 | $ret .= $object->address; |
||
| 1686 | } |
||
| 1687 | // Zip/Town/State |
||
| 1688 | if (in_array($object->country_code, array('AU', 'CA', 'US')) || !empty(Globals::$conf->global->MAIN_FORCE_STATE_INTO_ADDRESS)) { // US: title firstname name \n address lines \n town, state, zip \n country
|
||
| 1689 | $ret .= ($ret ? $sep : '' ) . $object->town; |
||
| 1690 | if ($object->state) {
|
||
| 1691 | $ret .= ($ret ? ", " : '') . $object->state; |
||
| 1692 | } |
||
| 1693 | if ($object->zip) |
||
| 1694 | $ret .= ($ret ? ", " : '') . $object->zip; |
||
| 1695 | } |
||
| 1696 | else if (in_array($object->country_code, array('GB', 'UK'))) { // UK: title firstname name \n address lines \n town state \n zip \n country
|
||
| 1697 | $ret .= ($ret ? $sep : '' ) . $object->town; |
||
| 1698 | if ($object->state) {
|
||
| 1699 | $ret .= ($ret ? ", " : '') . $object->state; |
||
| 1700 | } |
||
| 1701 | if ($object->zip) |
||
| 1702 | $ret .= ($ret ? $sep : '' ) . $object->zip; |
||
| 1703 | } |
||
| 1704 | else if (in_array($object->country_code, array('ES', 'TR'))) { // ES: title firstname name \n address lines \n zip town \n state \n country
|
||
| 1705 | $ret .= ($ret ? $sep : '' ) . $object->zip; |
||
| 1706 | $ret .= ($object->town ? (($object->zip ? ' ' : '') . $object->town) : ''); |
||
| 1707 | if ($object->state) {
|
||
| 1708 | $ret .= "\n" . $object->state; |
||
| 1709 | } |
||
| 1710 | } else if (in_array($object->country_code, array('IT'))) { // IT: tile firstname name\n address lines \n zip (Code Departement) \n country
|
||
| 1711 | $ret .= ($ret ? $sep : '' ) . $object->zip; |
||
| 1712 | $ret .= ($object->town ? (($object->zip ? ' ' : '') . $object->town) : ''); |
||
| 1713 | $ret .= ($object->departement_id ? (' (' . ($object->departement_id) . ')') : '');
|
||
| 1714 | } else { // Other: title firstname name \n address lines \n zip town \n country
|
||
| 1715 | $ret .= $object->zip ? (($ret ? $sep : '' ) . $object->zip) : ''; |
||
| 1716 | $ret .= ($object->town ? (($object->zip ? ' ' : ($ret ? $sep : '' )) . $object->town) : ''); |
||
| 1717 | if ($object->state && in_array($object->country_code, $countriesusingstate)) {
|
||
| 1718 | $ret .= ($ret ? ", " : '') . $object->state; |
||
| 1719 | } |
||
| 1720 | } |
||
| 1721 | if (!is_object($outputlangs)) |
||
| 1722 | $outputlangs = Globals::$langs; |
||
| 1723 | if ($withcountry) {
|
||
| 1724 | Globals::$langs->load("dict");
|
||
| 1725 | $ret .= ($object->country_code ? ($ret ? $sep : '') . $outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country" . $object->country_code)) : '');
|
||
| 1726 | } |
||
| 1727 | |||
| 1728 | return $ret; |
||
| 1729 | } |
||
| 1730 | |||
| 1731 | /** |
||
| 1732 | * Format a string. |
||
| 1733 | * |
||
| 1734 | * @param string $fmt Format of strftime static function (http://php.net/manual/fr/function.strftime.php) |
||
| 1735 | * @param int $ts Timesamp (If is_gmt is true, timestamp is already includes timezone and daylight saving offset, if is_gmt is false, timestamp is a GMT timestamp and we must compensate with server PHP TZ) |
||
| 1736 | * @param int $is_gmt See comment of timestamp parameter |
||
| 1737 | * @return string A formatted string |
||
| 1738 | */ |
||
| 1739 | static function dol_strftime($fmt, $ts = false, $is_gmt = false) |
||
| 1740 | {
|
||
| 1741 | if ((abs($ts) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range
|
||
| 1742 | return ($is_gmt) ? @gmstrftime($fmt, $ts) : @strftime($fmt, $ts); |
||
| 1743 | } else |
||
| 1744 | return 'Error date into a not supported range'; |
||
| 1745 | } |
||
| 1746 | |||
| 1747 | /** |
||
| 1748 | * Output date in a string format according to outputlangs (or langs if not defined). |
||
| 1749 | * Return charset is always UTF-8, except if encodetoouput is defined. In this case charset is output charset |
||
| 1750 | * |
||
| 1751 | * @param int $time GM Timestamps date |
||
| 1752 | * @param string $format Output date format (tag of strftime function) |
||
| 1753 | * "%d %b %Y", |
||
| 1754 | * "%d/%m/%Y %H:%M", |
||
| 1755 | * "%d/%m/%Y %H:%M:%S", |
||
| 1756 | * "%B"=Long text of month, "%A"=Long text of day, "%b"=Short text of month, "%a"=Short text of day |
||
| 1757 | * "day", "daytext", "dayhour", "dayhourldap", "dayhourtext", "dayrfc", "dayhourrfc", "...reduceformat" |
||
| 1758 | * @param string $tzoutput true or 'gmt' => string is for Greenwich location |
||
| 1759 | * false or 'tzserver' => output string is for local PHP server TZ usage |
||
| 1760 | * 'tzuser' => output string is for user TZ (current browser TZ with current dst) => In a future, we should have same behaviour than 'tzuserrel' |
||
| 1761 | * 'tzuserrel' => output string is for user TZ (current browser TZ with dst or not, depending on date position) (TODO not implemented yet) |
||
| 1762 | * @param Translate $outputlangs Object lang that contains language for text translation. |
||
| 1763 | * @param boolean $encodetooutput false=no convert into output pagecode |
||
| 1764 | * @return string Formated date or '' if time is null |
||
| 1765 | * |
||
| 1766 | * @see dol_mktime, dol_stringtotime, dol_getdate |
||
| 1767 | */ |
||
| 1768 | static function dol_print_date($time, $format = '', $tzoutput = 'tzserver', $outputlangs = '', $encodetooutput = false) |
||
| 1769 | {
|
||
| 1770 | // global Globals::$conf, Globals::$langs; |
||
| 1771 | // Clean parameters |
||
| 1772 | $to_gmt = false; |
||
| 1773 | $offsettz = $offsetdst = 0; |
||
| 1774 | if ($tzoutput) {
|
||
| 1775 | $to_gmt = true; // For backward compatibility |
||
| 1776 | if (is_string($tzoutput)) {
|
||
| 1777 | if ($tzoutput == 'tzserver') {
|
||
| 1778 | $to_gmt = false; |
||
| 1779 | $offsettzstring = @date_default_timezone_get(); // Example 'Europe/Berlin' or 'Indian/Reunion' |
||
| 1780 | $offsettz = 0; |
||
| 1781 | $offsetdst = 0; |
||
| 1782 | } elseif ($tzoutput == 'tzuser' || $tzoutput == 'tzuserrel') {
|
||
| 1783 | $to_gmt = true; |
||
| 1784 | $offsettzstring = (empty($_SESSION['dol_tz_string']) ? 'UTC' : $_SESSION['dol_tz_string']); // Example 'Europe/Berlin' or 'Indian/Reunion' |
||
| 1785 | $offsettz = (empty($_SESSION['dol_tz']) ? 0 : $_SESSION['dol_tz']) * 60 * 60; // Will not be used anymore |
||
| 1786 | $offsetdst = (empty($_SESSION['dol_dst']) ? 0 : $_SESSION['dol_dst']) * 60 * 60; // Will not be used anymore |
||
| 1787 | } |
||
| 1788 | } |
||
| 1789 | } |
||
| 1790 | if (!is_object($outputlangs)) |
||
| 1791 | $outputlangs = Globals::$langs; |
||
| 1792 | if (!$format) |
||
| 1793 | $format = 'daytextshort'; |
||
| 1794 | $reduceformat = (!empty(Globals::$conf->dol_optimize_smallscreen) && in_array($format, array('day', 'dayhour'))) ? 1 : 0;
|
||
| 1795 | $formatwithoutreduce = preg_replace('/reduceformat/', '', $format);
|
||
| 1796 | if ($formatwithoutreduce != $format) {
|
||
| 1797 | $format = $formatwithoutreduce; |
||
| 1798 | $reduceformat = 1; |
||
| 1799 | } // so format 'dayreduceformat' is processed like day |
||
| 1800 | // Change predefined format into computer format. If found translation in lang file we use it, otherwise we use default. |
||
| 1801 | // TODO Add format daysmallyear and dayhoursmallyear |
||
| 1802 | if ($format == 'day') |
||
| 1803 | $format = ($outputlangs->trans("FormatDateShort") != "FormatDateShort" ? $outputlangs->trans("FormatDateShort") : Globals::$conf->format_date_short);
|
||
| 1804 | else if ($format == 'hour') |
||
| 1805 | $format = ($outputlangs->trans("FormatHourShort") != "FormatHourShort" ? $outputlangs->trans("FormatHourShort") : Globals::$conf->format_hour_short);
|
||
| 1806 | else if ($format == 'hourduration') |
||
| 1807 | $format = ($outputlangs->trans("FormatHourShortDuration") != "FormatHourShortDuration" ? $outputlangs->trans("FormatHourShortDuration") : Globals::$conf->format_hour_short_duration);
|
||
| 1808 | else if ($format == 'daytext') |
||
| 1809 | $format = ($outputlangs->trans("FormatDateText") != "FormatDateText" ? $outputlangs->trans("FormatDateText") : Globals::$conf->format_date_text);
|
||
| 1810 | else if ($format == 'daytextshort') |
||
| 1811 | // Notice: Undefined property: stdClass::$format_date_text_short in \alixar\dolibarr\htdocs\core\lib\functions.lib.php on line 1781 |
||
| 1812 | $format = ($outputlangs->trans("FormatDateTextShort") != "FormatDateTextShort" ? $outputlangs->trans("FormatDateTextShort") : Globals::$conf->format_date_text_short);
|
||
| 1813 | else if ($format == 'dayhour') |
||
| 1814 | $format = ($outputlangs->trans("FormatDateHourShort") != "FormatDateHourShort" ? $outputlangs->trans("FormatDateHourShort") : Globals::$conf->format_date_hour_short ?? "%d/%m/%Y %H:%M");
|
||
| 1815 | else if ($format == 'dayhoursec') |
||
| 1816 | $format = ($outputlangs->trans("FormatDateHourSecShort") != "FormatDateHourSecShort" ? $outputlangs->trans("FormatDateHourSecShort") : Globals::$conf->format_date_hour_sec_short);
|
||
| 1817 | else if ($format == 'dayhourtext') |
||
| 1818 | $format = ($outputlangs->trans("FormatDateHourText") != "FormatDateHourText" ? $outputlangs->trans("FormatDateHourText") : Globals::$conf->format_date_hour_text);
|
||
| 1819 | else if ($format == 'dayhourtextshort') |
||
| 1820 | $format = ($outputlangs->trans("FormatDateHourTextShort") != "FormatDateHourTextShort" ? $outputlangs->trans("FormatDateHourTextShort") : Globals::$conf->format_date_hour_text_short);
|
||
| 1821 | // Format not sensitive to language |
||
| 1822 | else if ($format == 'dayhourlog') |
||
| 1823 | $format = '%Y%m%d%H%M%S'; |
||
| 1824 | else if ($format == 'dayhourldap') |
||
| 1825 | $format = '%Y%m%d%H%M%SZ'; |
||
| 1826 | else if ($format == 'dayhourxcard') |
||
| 1827 | $format = '%Y%m%dT%H%M%SZ'; |
||
| 1828 | else if ($format == 'dayxcard') |
||
| 1829 | $format = '%Y%m%d'; |
||
| 1830 | else if ($format == 'dayrfc') |
||
| 1831 | $format = '%Y-%m-%d'; // DATE_RFC3339 |
||
| 1832 | else if ($format == 'dayhourrfc') |
||
| 1833 | $format = '%Y-%m-%dT%H:%M:%SZ'; // DATETIME RFC3339 |
||
| 1834 | else if ($format == 'standard') |
||
| 1835 | $format = '%Y-%m-%d %H:%M:%S'; |
||
| 1836 | |||
| 1837 | if ($reduceformat) {
|
||
| 1838 | $format = str_replace('%Y', '%y', $format);
|
||
| 1839 | $format = str_replace('yyyy', 'yy', $format);
|
||
| 1840 | } |
||
| 1841 | |||
| 1842 | // If date undefined or "", we return "" |
||
| 1843 | if (AlDolUtils::dol_strlen($time) == 0) |
||
| 1844 | return ''; // $time=0 allowed (it means 01/01/1970 00:00:00) |
||
| 1845 | |||
| 1846 | |||
| 1847 | |||
| 1848 | |||
| 1849 | |||
| 1850 | |||
| 1851 | |||
| 1852 | |||
| 1853 | |||
| 1854 | |||
| 1855 | |||
| 1856 | |||
| 1857 | |||
| 1858 | |||
| 1859 | |||
| 1860 | |||
| 1861 | |||
| 1862 | |||
| 1863 | |||
| 1864 | |||
| 1865 | |||
| 1866 | |||
| 1867 | |||
| 1868 | |||
| 1869 | |||
| 1870 | |||
| 1871 | |||
| 1872 | |||
| 1873 | |||
| 1874 | |||
| 1875 | |||
| 1876 | |||
| 1877 | |||
| 1878 | |||
| 1879 | |||
| 1880 | |||
| 1881 | |||
| 1882 | |||
| 1883 | |||
| 1884 | |||
| 1885 | |||
| 1886 | |||
| 1887 | |||
| 1888 | |||
| 1889 | |||
| 1890 | |||
| 1891 | |||
| 1892 | |||
| 1893 | |||
| 1894 | |||
| 1895 | |||
| 1896 | |||
| 1897 | |||
| 1898 | // Clean format |
||
| 1899 | if (preg_match('/%b/i', $format)) { // There is some text to translate
|
||
| 1900 | // We inhibate translation to text made by strftime functions. We will use trans instead later. |
||
| 1901 | $format = str_replace('%b', '__b__', $format);
|
||
| 1902 | $format = str_replace('%B', '__B__', $format);
|
||
| 1903 | } |
||
| 1904 | if (preg_match('/%a/i', $format)) { // There is some text to translate
|
||
| 1905 | // We inhibate translation to text made by strftime functions. We will use trans instead later. |
||
| 1906 | $format = str_replace('%a', '__a__', $format);
|
||
| 1907 | $format = str_replace('%A', '__A__', $format);
|
||
| 1908 | } |
||
| 1909 | |||
| 1910 | // Analyze date |
||
| 1911 | if (preg_match('/^([0-9]+)\-([0-9]+)\-([0-9]+) ?([0-9]+)?:?([0-9]+)?:?([0-9]+)?/i', $time, $reg) || preg_match('/^([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])$/i', $time, $reg)) { // Deprecated. Ex: 1970-01-01, 1970-01-01 01:00:00, 19700101010000
|
||
| 1912 | // TODO Remove this. |
||
| 1913 | // This part of code should not be used. |
||
| 1914 | AlDolUtils::dol_syslog("Functions.lib::DolUtils::dol_print_date static function call with deprecated value of time in page " . $_SERVER["PHP_SELF"], LOG_ERR);
|
||
| 1915 | // Date has format 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM:SS' or 'YYYYMMDDHHMMSS' |
||
| 1916 | $syear = (!empty($reg[1]) ? $reg[1] : ''); |
||
| 1917 | $smonth = (!empty($reg[2]) ? $reg[2] : ''); |
||
| 1918 | $sday = (!empty($reg[3]) ? $reg[3] : ''); |
||
| 1919 | $shour = (!empty($reg[4]) ? $reg[4] : ''); |
||
| 1920 | $smin = (!empty($reg[5]) ? $reg[5] : ''); |
||
| 1921 | $ssec = (!empty($reg[6]) ? $reg[6] : ''); |
||
| 1922 | |||
| 1923 | $time = AlDolUtils::dol_mktime($shour, $smin, $ssec, $smonth, $sday, $syear, true); |
||
| 1924 | $ret = adodb_strftime($format, $time + $offsettz + $offsetdst, $to_gmt); |
||
| 1925 | } else {
|
||
| 1926 | // Date is a timestamps |
||
| 1927 | if ($time < 100000000000) { // Protection against bad date values
|
||
| 1928 | $timetouse = $time + $offsettz + $offsetdst; // TODO Replace this with static function Date PHP. We also should not use anymore offsettz and offsetdst but only offsettzstring. |
||
| 1929 | |||
| 1930 | $ret = adodb_strftime($format, $timetouse, $to_gmt); |
||
| 1931 | } else |
||
| 1932 | $ret = 'Bad value ' . $time . ' for date'; |
||
| 1933 | } |
||
| 1934 | |||
| 1935 | if (preg_match('/__b__/i', $format)) {
|
||
| 1936 | $timetouse = $time + $offsettz + $offsetdst; // TODO Replace this with static function Date PHP. We also should not use anymore offsettz and offsetdst but only offsettzstring. |
||
| 1937 | // Here ret is string in PHP setup language (strftime was used). Now we convert to $outputlangs. |
||
| 1938 | $month = adodb_strftime('%m', $timetouse);
|
||
| 1939 | $month = sprintf("%02d", $month); // $month may be return with format '06' on some installation and '6' on other, so we force it to '06'.
|
||
| 1940 | if ($encodetooutput) {
|
||
| 1941 | $monthtext = $outputlangs->transnoentities('Month' . $month);
|
||
| 1942 | $monthtextshort = $outputlangs->transnoentities('MonthShort' . $month);
|
||
| 1943 | } else {
|
||
| 1944 | $monthtext = $outputlangs->transnoentitiesnoconv('Month' . $month);
|
||
| 1945 | $monthtextshort = $outputlangs->transnoentitiesnoconv('MonthShort' . $month);
|
||
| 1946 | } |
||
| 1947 | //print 'monthtext='.$monthtext.' monthtextshort='.$monthtextshort; |
||
| 1948 | $ret = str_replace('__b__', $monthtextshort, $ret);
|
||
| 1949 | $ret = str_replace('__B__', $monthtext, $ret);
|
||
| 1950 | //print 'x'.$outputlangs->charset_output.'-'.$ret.'x'; |
||
| 1951 | //return $ret; |
||
| 1952 | } |
||
| 1953 | if (preg_match('/__a__/i', $format)) {
|
||
| 1954 | $timetouse = $time + $offsettz + $offsetdst; // TODO Replace this with static function Date PHP. We also should not use anymore offsettz and offsetdst but only offsettzstring. |
||
| 1955 | |||
| 1956 | $w = adodb_strftime('%w', $timetouse); // TODO Replace this with static function Date PHP. We also should not use anymore offsettz and offsetdst but only offsettzstring.
|
||
| 1957 | $dayweek = $outputlangs->transnoentitiesnoconv('Day' . $w);
|
||
| 1958 | $ret = str_replace('__A__', $dayweek, $ret);
|
||
| 1959 | $ret = str_replace('__a__', dol_substr($dayweek, 0, 3), $ret);
|
||
| 1960 | } |
||
| 1961 | |||
| 1962 | return $ret; |
||
| 1963 | } |
||
| 1964 | |||
| 1965 | /** |
||
| 1966 | * Return an array with locale date info. |
||
| 1967 | * PHP getdate is restricted to the years 1901-2038 on Unix and 1970-2038 on Windows |
||
| 1968 | * WARNING: This static function always use PHP server timezone to return locale informations !!! |
||
| 1969 | * Usage must be avoid. |
||
| 1970 | * FIXME: Replace this with PHP date static function and a parameter $gm |
||
| 1971 | * |
||
| 1972 | * @param int $timestamp Timestamp |
||
| 1973 | * @param boolean $fast Fast mode |
||
| 1974 | * @return array Array of informations |
||
| 1975 | * If no fast mode: |
||
| 1976 | * 'seconds' => $secs, |
||
| 1977 | * 'minutes' => $min, |
||
| 1978 | * 'hours' => $hour, |
||
| 1979 | * 'mday' => $day, |
||
| 1980 | * 'wday' => $dow, 0=sunday, 6=saturday |
||
| 1981 | * 'mon' => $month, |
||
| 1982 | * 'year' => $year, |
||
| 1983 | * 'yday' => floor($secsInYear/$_day_power), |
||
| 1984 | * 'weekday' => gmdate('l',$_day_power*(3+$dow)),
|
||
| 1985 | * 'month' => gmdate('F',mktime(0,0,0,$month,2,1971)),
|
||
| 1986 | * If fast mode: |
||
| 1987 | * 'seconds' => $secs, |
||
| 1988 | * 'minutes' => $min, |
||
| 1989 | * 'hours' => $hour, |
||
| 1990 | * 'mday' => $day, |
||
| 1991 | * 'mon' => $month, |
||
| 1992 | * 'year' => $year, |
||
| 1993 | * 'yday' => floor($secsInYear/$_day_power), |
||
| 1994 | * 'leap' => $leaf, |
||
| 1995 | * 'ndays' => $ndays |
||
| 1996 | * @see DolUtils::dol_print_date, dol_stringtotime, dol_mktime |
||
| 1997 | */ |
||
| 1998 | static function dol_getdate($timestamp, $fast = false) |
||
| 1999 | {
|
||
| 2000 | // global Globals::$conf; |
||
| 2001 | |||
| 2002 | $usealternatemethod = false; |
||
| 2003 | if ($timestamp <= 0) |
||
| 2004 | $usealternatemethod = true; // <= 1970 |
||
| 2005 | if ($timestamp >= 2145913200) |
||
| 2006 | $usealternatemethod = true; // >= 2038 |
||
| 2007 | |||
| 2008 | if ($usealternatemethod) {
|
||
| 2009 | $arrayinfo = adodb_getdate($timestamp, $fast); |
||
| 2010 | } else {
|
||
| 2011 | $arrayinfo = getdate($timestamp); |
||
| 2012 | } |
||
| 2013 | |||
| 2014 | return $arrayinfo; |
||
| 2015 | } |
||
| 2016 | |||
| 2017 | /** |
||
| 2018 | * Return a timestamp date built from detailed informations (by default a local PHP server timestamp) |
||
| 2019 | * Replace static function mktime not available under Windows if year < 1970 |
||
| 2020 | * PHP mktime is restricted to the years 1901-2038 on Unix and 1970-2038 on Windows |
||
| 2021 | * |
||
| 2022 | * @param int $hour Hour (can be -1 for undefined) |
||
| 2023 | * @param int $minute Minute (can be -1 for undefined) |
||
| 2024 | * @param int $second Second (can be -1 for undefined) |
||
| 2025 | * @param int $month Month (1 to 12) |
||
| 2026 | * @param int $day Day (1 to 31) |
||
| 2027 | * @param int $year Year |
||
| 2028 | * @param mixed $gm True or 1 or 'gmt'=Input informations are GMT values |
||
| 2029 | * False or 0 or 'server' = local to server TZ |
||
| 2030 | * 'user' = local to user TZ |
||
| 2031 | * 'tz,TimeZone' = use specified timezone |
||
| 2032 | * @param int $check 0=No check on parameters (Can use day 32, etc...) |
||
| 2033 | * @return int|string Date as a timestamp, '' or false if error |
||
| 2034 | * @see DolUtils::dol_print_date, dol_stringtotime, dol_getdate |
||
| 2035 | */ |
||
| 2036 | static function dol_mktime($hour, $minute, $second, $month, $day, $year, $gm = false, $check = 1) |
||
| 2037 | {
|
||
| 2038 | // global Globals::$conf; |
||
| 2039 | //print "- ".$hour.",".$minute.",".$second.",".$month.",".$day.",".$year.",".$_SERVER["WINDIR"]." -"; |
||
| 2040 | // Clean parameters |
||
| 2041 | if ($hour == -1 || empty($hour)) |
||
| 2042 | $hour = 0; |
||
| 2043 | if ($minute == -1 || empty($minute)) |
||
| 2044 | $minute = 0; |
||
| 2045 | if ($second == -1 || empty($second)) |
||
| 2046 | $second = 0; |
||
| 2047 | |||
| 2048 | // Check parameters |
||
| 2049 | if ($check) {
|
||
| 2050 | if (!$month || !$day) |
||
| 2051 | return ''; |
||
| 2052 | if ($day > 31) |
||
| 2053 | return ''; |
||
| 2054 | if ($month > 12) |
||
| 2055 | return ''; |
||
| 2056 | if ($hour < 0 || $hour > 24) |
||
| 2057 | return ''; |
||
| 2058 | if ($minute < 0 || $minute > 60) |
||
| 2059 | return ''; |
||
| 2060 | if ($second < 0 || $second > 60) |
||
| 2061 | return ''; |
||
| 2062 | } |
||
| 2063 | |||
| 2064 | if (method_exists('DateTime', 'getTimestamp')) {
|
||
| 2065 | if (empty($gm) || $gm === 'server') {
|
||
| 2066 | $default_timezone = @date_default_timezone_get(); // Example 'Europe/Berlin' |
||
| 2067 | $localtz = new \DateTimeZone($default_timezone); |
||
| 2068 | } else if ($gm === 'user') {
|
||
| 2069 | // We use dol_tz_string first because it is more reliable. |
||
| 2070 | $default_timezone = (empty($_SESSION["dol_tz_string"]) ? @date_default_timezone_get() : $_SESSION["dol_tz_string"]); // Example 'Europe/Berlin' |
||
| 2071 | try {
|
||
| 2072 | $localtz = new \DateTimeZone($default_timezone); |
||
| 2073 | } catch (Exception $e) {
|
||
| 2074 | AlDolUtils::dol_syslog("Warning dol_tz_string contains an invalid value " . $_SESSION["dol_tz_string"], LOG_WARNING);
|
||
| 2075 | $default_timezone = @date_default_timezone_get(); |
||
| 2076 | } |
||
| 2077 | } else if (strrpos($gm, "tz,") !== false) {
|
||
| 2078 | $timezone = str_replace("tz,", "", $gm); // Example 'tz,Europe/Berlin'
|
||
| 2079 | try {
|
||
| 2080 | $localtz = new \DateTimeZone($timezone); |
||
| 2081 | } catch (Exception $e) {
|
||
| 2082 | AlDolUtils::dol_syslog("Warning passed timezone contains an invalid value " . $timezone, LOG_WARNING);
|
||
| 2083 | } |
||
| 2084 | } |
||
| 2085 | |||
| 2086 | if (empty($localtz)) {
|
||
| 2087 | $localtz = new \DateTimeZone('UTC');
|
||
| 2088 | } |
||
| 2089 | //var_dump($localtz); |
||
| 2090 | //var_dump($year.'-'.$month.'-'.$day.'-'.$hour.'-'.$minute); |
||
| 2091 | $dt = new \DateTime(null, $localtz); |
||
| 2092 | $dt->setDate($year, $month, $day); |
||
| 2093 | $dt->setTime((int) $hour, (int) $minute, (int) $second); |
||
| 2094 | $date = $dt->getTimestamp(); // should include daylight saving time |
||
| 2095 | //var_dump($date); |
||
| 2096 | return $date; |
||
| 2097 | } else {
|
||
| 2098 | dol_print_error('', 'PHP version must be 5.4+');
|
||
| 2099 | return ''; |
||
| 2100 | } |
||
| 2101 | } |
||
| 2102 | |||
| 2103 | /** |
||
| 2104 | * Return date for now. In most cases, we use this static function without parameters (that means GMT time). |
||
| 2105 | * |
||
| 2106 | * @param string $mode 'gmt' => we return GMT timestamp, |
||
| 2107 | * 'tzserver' => we add the PHP server timezone |
||
| 2108 | * 'tzref' => we add the company timezone |
||
| 2109 | * 'tzuser' => we add the user timezone |
||
| 2110 | * @return int $date Timestamp |
||
| 2111 | */ |
||
| 2112 | static function dol_now($mode = 'gmt') |
||
| 2113 | {
|
||
| 2114 | $ret = 0; |
||
| 2115 | |||
| 2116 | // Note that gmmktime and mktime return same value (GMT) when used without parameters |
||
| 2117 | //if ($mode == 'gmt') $ret=gmmktime(); // Strict Standards: gmmktime(): You should be using the time() static function instead |
||
| 2118 | if ($mode == 'gmt') |
||
| 2119 | $ret = time(); // Time for now at greenwich. |
||
| 2120 | else if ($mode == 'tzserver') { // Time for now with PHP server timezone added
|
||
| 2121 | require_once DOL_BASE_PATH . '/core/lib/date.lib.php'; |
||
| 2122 | $tzsecond = getServerTimeZoneInt('now'); // Contains tz+dayling saving time
|
||
| 2123 | $ret = (int) (dol_now('gmt') + ($tzsecond * 3600));
|
||
| 2124 | } |
||
| 2125 | /* else if ($mode == 'tzref') // Time for now with parent company timezone is added |
||
| 2126 | {
|
||
| 2127 | require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; |
||
| 2128 | $tzsecond=getParentCompanyTimeZoneInt(); // Contains tz+dayling saving time |
||
| 2129 | $ret=dol_now('gmt')+($tzsecond*3600);
|
||
| 2130 | } */ else if ($mode == 'tzuser') { // Time for now with user timezone added
|
||
| 2131 | //print 'time: '.time().'-'.mktime().'-'.gmmktime(); |
||
| 2132 | $offsettz = (empty($_SESSION['dol_tz']) ? 0 : $_SESSION['dol_tz']) * 60 * 60; |
||
| 2133 | $offsetdst = (empty($_SESSION['dol_dst']) ? 0 : $_SESSION['dol_dst']) * 60 * 60; |
||
| 2134 | $ret = (int) (dol_now('gmt') + ($offsettz + $offsetdst));
|
||
| 2135 | } |
||
| 2136 | |||
| 2137 | return $ret; |
||
| 2138 | } |
||
| 2139 | |||
| 2140 | /** |
||
| 2141 | * Return string with formated size |
||
| 2142 | * |
||
| 2143 | * @param int $size Size to print |
||
| 2144 | * @param int $shortvalue Tell if we want long value to use another unit (Ex: 1.5Kb instead of 1500b) |
||
| 2145 | * @param int $shortunit Use short label of size unit (for example 'b' instead of 'bytes') |
||
| 2146 | * @return string Link |
||
| 2147 | */ |
||
| 2148 | static function dol_print_size($size, $shortvalue = 0, $shortunit = 0) |
||
| 2149 | {
|
||
| 2150 | // global Globals::$conf, Globals::$langs; |
||
| 2151 | $level = 1024; |
||
| 2152 | |||
| 2153 | if (!empty(Globals::$conf->dol_optimize_smallscreen)) |
||
| 2154 | $shortunit = 1; |
||
| 2155 | |||
| 2156 | // Set value text |
||
| 2157 | if (empty($shortvalue) || $size < ($level * 10)) {
|
||
| 2158 | $ret = $size; |
||
| 2159 | $textunitshort = Globals::$langs->trans("b");
|
||
| 2160 | $textunitlong = Globals::$langs->trans("Bytes");
|
||
| 2161 | } else {
|
||
| 2162 | $ret = round($size / $level, 0); |
||
| 2163 | $textunitshort = Globals::$langs->trans("Kb");
|
||
| 2164 | $textunitlong = Globals::$langs->trans("KiloBytes");
|
||
| 2165 | } |
||
| 2166 | // Use long or short text unit |
||
| 2167 | if (empty($shortunit)) {
|
||
| 2168 | $ret .= ' ' . $textunitlong; |
||
| 2169 | } else {
|
||
| 2170 | $ret .= ' ' . $textunitshort; |
||
| 2171 | } |
||
| 2172 | |||
| 2173 | return $ret; |
||
| 2174 | } |
||
| 2175 | |||
| 2176 | /** |
||
| 2177 | * Show Url link |
||
| 2178 | * |
||
| 2179 | * @param string $url Url to show |
||
| 2180 | * @param string $target Target for link |
||
| 2181 | * @param int $max Max number of characters to show |
||
| 2182 | * @param int $withpicto With picto |
||
| 2183 | * @return string HTML Link |
||
| 2184 | */ |
||
| 2185 | static function dol_print_url($url, $target = '_blank', $max = 32, $withpicto = 0) |
||
| 2186 | {
|
||
| 2187 | // global Globals::$langs; |
||
| 2188 | |||
| 2189 | if (empty($url)) |
||
| 2190 | return ''; |
||
| 2191 | |||
| 2192 | $link = '<a href="'; |
||
| 2193 | if (!preg_match('/^http/i', $url))
|
||
| 2194 | $link .= 'http://'; |
||
| 2195 | $link .= $url; |
||
| 2196 | $link .= '"'; |
||
| 2197 | if ($target) |
||
| 2198 | $link .= ' target="' . $target . '"'; |
||
| 2199 | $link .= '>'; |
||
| 2200 | if (!preg_match('/^http/i', $url))
|
||
| 2201 | $link .= 'http://'; |
||
| 2202 | $link .= dol_trunc($url, $max); |
||
| 2203 | $link .= '</a>'; |
||
| 2204 | return '<div class="nospan float" style="margin-right: 10px">' . ($withpicto ? img_picto(Globals::$langs->trans("Url"), 'object_globe.png') . ' ' : '') . $link . '</div>';
|
||
| 2205 | } |
||
| 2206 | |||
| 2207 | /** |
||
| 2208 | * Show EMail link |
||
| 2209 | * |
||
| 2210 | * @param string $email EMail to show (only email, without 'Name of recipient' before) |
||
| 2211 | * @param int $cid Id of contact if known |
||
| 2212 | * @param int $socid Id of third party if known |
||
| 2213 | * @param int $addlink 0=no link, 1=email has a html email link (+ link to create action if constant AGENDA_ADDACTIONFOREMAIL is on) |
||
| 2214 | * @param int $max Max number of characters to show |
||
| 2215 | * @param int $showinvalid Show warning if syntax email is wrong |
||
| 2216 | * @param int $withpicto Show picto |
||
| 2217 | * @return string HTML Link |
||
| 2218 | */ |
||
| 2219 | static function dol_print_email($email, $cid = 0, $socid = 0, $addlink = 0, $max = 64, $showinvalid = 1, $withpicto = 0) |
||
| 2220 | {
|
||
| 2221 | // global Globals::$conf, $user, Globals::$langs, Globals::$hookManager; |
||
| 2222 | |||
| 2223 | $newemail = $email; |
||
| 2224 | |||
| 2225 | if (empty($email)) |
||
| 2226 | return ' '; |
||
| 2227 | |||
| 2228 | if (!empty($addlink)) {
|
||
| 2229 | $newemail = '<a style="text-overflow: ellipsis;" href="'; |
||
| 2230 | if (!preg_match('/^mailto:/i', $email))
|
||
| 2231 | $newemail .= 'mailto:'; |
||
| 2232 | $newemail .= $email; |
||
| 2233 | $newemail .= '">'; |
||
| 2234 | $newemail .= dol_trunc($email, $max); |
||
| 2235 | $newemail .= '</a>'; |
||
| 2236 | if ($showinvalid && !isValidEmail($email)) {
|
||
| 2237 | Globals::$langs->load("errors");
|
||
| 2238 | $newemail .= img_warning(Globals::$langs->trans("ErrorBadEMail", $email));
|
||
| 2239 | } |
||
| 2240 | |||
| 2241 | if (($cid || $socid) && !empty(Globals::$conf->agenda->enabled) && $user->rights->agenda->myactions->create) {
|
||
| 2242 | $type = 'AC_EMAIL'; |
||
| 2243 | $link = ''; |
||
| 2244 | if (!empty(Globals::$conf->global->AGENDA_ADDACTIONFOREMAIL)) |
||
| 2245 | $link = '<a href="' . DOL_BASE_URI . '/comm/action/card.php?action=create&backtopage=1&actioncode=' . $type . '&contactid=' . $cid . '&socid=' . $socid . '">' . img_object(Globals::$langs->trans("AddAction"), "calendar") . '</a>';
|
||
| 2246 | if ($link) |
||
| 2247 | $newemail = '<div>' . $newemail . ' ' . $link . '</div>'; |
||
| 2248 | } |
||
| 2249 | } |
||
| 2250 | else {
|
||
| 2251 | if ($showinvalid && !isValidEmail($email)) {
|
||
| 2252 | Globals::$langs->load("errors");
|
||
| 2253 | $newemail .= img_warning(Globals::$langs->trans("ErrorBadEMail", $email));
|
||
| 2254 | } |
||
| 2255 | } |
||
| 2256 | |||
| 2257 | $rep = '<div class="nospan float" style="margin-right: 10px">' . ($withpicto ? img_picto(Globals::$langs->trans("EMail"), 'object_email.png') . ' ' : '') . $newemail . '</div>';
|
||
| 2258 | if (Globals::$hookManager) {
|
||
| 2259 | $parameters = array('cid' => $cid, 'socid' => $socid, 'addlink' => $addlink, 'picto' => $withpicto);
|
||
| 2260 | $reshook = Globals::$hookManager->executeHooks('printEmail', $parameters, $email);
|
||
| 2261 | $rep .= Globals::$hookManager->resPrint; |
||
| 2262 | } |
||
| 2263 | |||
| 2264 | return $rep; |
||
| 2265 | } |
||
| 2266 | |||
| 2267 | /** |
||
| 2268 | * Show social network link |
||
| 2269 | * |
||
| 2270 | * @param string $value Skype to show (only skype, without 'Name of recipient' before) |
||
| 2271 | * @param int $cid Id of contact if known |
||
| 2272 | * @param int $socid Id of third party if known |
||
| 2273 | * @param string $type 'skype','facebook',... |
||
| 2274 | * @return string HTML Link |
||
| 2275 | */ |
||
| 2276 | static function dol_print_socialnetworks($value, $cid, $socid, $type) |
||
| 2277 | {
|
||
| 2278 | // global Globals::$conf, $user, Globals::$langs; |
||
| 2279 | |||
| 2280 | $newskype = $value; |
||
| 2281 | |||
| 2282 | if (empty($value)) |
||
| 2283 | return ' '; |
||
| 2284 | |||
| 2285 | if (!empty($type)) {
|
||
| 2286 | $newskype = '<div class="divsocialnetwork inline-block valignmiddle">'; |
||
| 2287 | $newskype .= img_picto(Globals::$langs->trans(strtoupper($type)), $type . '.png', '', false, 0, 0, '', 'paddingright'); |
||
| 2288 | $newskype .= $value; |
||
| 2289 | if ($type == 'skype') {
|
||
| 2290 | $newskype .= ' '; |
||
| 2291 | $newskype .= '<a href="skype:'; |
||
| 2292 | $newskype .= $value; |
||
| 2293 | $newskype .= '?call" alt="' . Globals::$langs->trans("Call") . ' ' . $value . '" title="' . Globals::$langs->trans("Call") . ' ' . $value . '">';
|
||
| 2294 | $newskype .= '<img src="' . DOL_BASE_URI . '/theme/common/skype_callbutton.png" border="0">'; |
||
| 2295 | $newskype .= '</a><a href="skype:'; |
||
| 2296 | $newskype .= $value; |
||
| 2297 | $newskype .= '?chat" alt="' . Globals::$langs->trans("Chat") . ' ' . $value . '" title="' . Globals::$langs->trans("Chat") . ' ' . $value . '">';
|
||
| 2298 | $newskype .= '<img class="paddingleft" src="' . DOL_BASE_URI . '/theme/common/skype_chatbutton.png" border="0">'; |
||
| 2299 | $newskype .= '</a>'; |
||
| 2300 | } |
||
| 2301 | if (($cid || $socid) && !empty(Globals::$conf->agenda->enabled) && $user->rights->agenda->myactions->create && $type == 'skype') {
|
||
| 2302 | $addlink = 'AC_SKYPE'; |
||
| 2303 | $link = ''; |
||
| 2304 | if (!empty(Globals::$conf->global->AGENDA_ADDACTIONFORSKYPE)) |
||
| 2305 | $link = '<a href="' . DOL_BASE_URI . '/comm/action/card.php?action=create&backtopage=1&actioncode=' . $addlink . '&contactid=' . $cid . '&socid=' . $socid . '">' . img_object(Globals::$langs->trans("AddAction"), "calendar") . '</a>';
|
||
| 2306 | $newskype .= ($link ? ' ' . $link : ''); |
||
| 2307 | } |
||
| 2308 | $newskype .= '</div>'; |
||
| 2309 | } |
||
| 2310 | else {
|
||
| 2311 | Globals::$langs->load("errors");
|
||
| 2312 | $newskype .= img_warning(Globals::$langs->trans("ErrorBadSocialNetworkValue", $value));
|
||
| 2313 | } |
||
| 2314 | return $newskype; |
||
| 2315 | } |
||
| 2316 | |||
| 2317 | /** |
||
| 2318 | * Format phone numbers according to country |
||
| 2319 | * |
||
| 2320 | * @param string $phone Phone number to format |
||
| 2321 | * @param string $countrycode Country code to use for formatting |
||
| 2322 | * @param int $cid Id of contact if known |
||
| 2323 | * @param int $socid Id of third party if known |
||
| 2324 | * @param string $addlink ''=no link to create action, 'AC_TEL'=add link to clicktodial (if module enabled) and add link to create event (if conf->global->AGENDA_ADDACTIONFORPHONE set) |
||
| 2325 | * @param string $separ Separation between numbers for a better visibility example : xx.xx.xx.xx.xx |
||
| 2326 | * @param string $withpicto Show picto |
||
| 2327 | * @param string $titlealt Text to show on alt |
||
| 2328 | * @param int $adddivfloat Add div float around phone. |
||
| 2329 | * @return string Formated phone number |
||
| 2330 | */ |
||
| 2331 | static function dol_print_phone($phone, $countrycode = '', $cid = 0, $socid = 0, $addlink = '', $separ = " ", $withpicto = '', $titlealt = '', $adddivfloat = 0) |
||
| 2332 | {
|
||
| 2333 | // global Globals::$conf, $user, Globals::$langs, $mysoc, Globals::$hookManager; |
||
| 2334 | // Clean phone parameter |
||
| 2335 | $phone = preg_replace("/[\s.-]/", "", trim($phone));
|
||
| 2336 | if (empty($phone)) {
|
||
| 2337 | return ''; |
||
| 2338 | } |
||
| 2339 | if (empty($countrycode)) |
||
| 2340 | $countrycode = $mysoc->country_code; |
||
| 2341 | |||
| 2342 | // Short format for small screens |
||
| 2343 | if (Globals::$conf->dol_optimize_smallscreen) |
||
| 2344 | $separ = ''; |
||
| 2345 | |||
| 2346 | $newphone = $phone; |
||
| 2347 | if (strtoupper($countrycode) == "FR") {
|
||
| 2348 | // France |
||
| 2349 | if (AlDolUtils::dol_strlen($phone) == 10) {
|
||
| 2350 | $newphone = substr($newphone, 0, 2) . $separ . substr($newphone, 2, 2) . $separ . substr($newphone, 4, 2) . $separ . substr($newphone, 6, 2) . $separ . substr($newphone, 8, 2); |
||
| 2351 | } elseif (AlDolUtils::dol_strlen($phone) == 7) {
|
||
| 2352 | $newphone = substr($newphone, 0, 3) . $separ . substr($newphone, 3, 2) . $separ . substr($newphone, 5, 2); |
||
| 2353 | } elseif (AlDolUtils::dol_strlen($phone) == 9) {
|
||
| 2354 | $newphone = substr($newphone, 0, 2) . $separ . substr($newphone, 2, 3) . $separ . substr($newphone, 5, 2) . $separ . substr($newphone, 7, 2); |
||
| 2355 | } elseif (AlDolUtils::dol_strlen($phone) == 11) {
|
||
| 2356 | $newphone = substr($newphone, 0, 3) . $separ . substr($newphone, 3, 2) . $separ . substr($newphone, 5, 2) . $separ . substr($newphone, 7, 2) . $separ . substr($newphone, 9, 2); |
||
| 2357 | } elseif (AlDolUtils::dol_strlen($phone) == 12) {
|
||
| 2358 | $newphone = substr($newphone, 0, 4) . $separ . substr($newphone, 4, 2) . $separ . substr($newphone, 6, 2) . $separ . substr($newphone, 8, 2) . $separ . substr($newphone, 10, 2); |
||
| 2359 | } |
||
| 2360 | } elseif (strtoupper($countrycode) == "CA") {
|
||
| 2361 | if (AlDolUtils::dol_strlen($phone) == 10) {
|
||
| 2362 | $newphone = ($separ != '' ? '(' : '') . substr($newphone, 0, 3) . ($separ != '' ? ')' : '') . $separ . substr($newphone, 3, 3) . ($separ != '' ? '-' : '') . substr($newphone, 6, 4);
|
||
| 2363 | } |
||
| 2364 | } elseif (strtoupper($countrycode) == "PT") {//Portugal
|
||
| 2365 | if (AlDolUtils::dol_strlen($phone) == 13) {//ex: +351_ABC_DEF_GHI
|
||
| 2366 | $newphone = substr($newphone, 0, 4) . $separ . substr($newphone, 4, 3) . $separ . substr($newphone, 7, 3) . $separ . substr($newphone, 10, 3); |
||
| 2367 | } |
||
| 2368 | } elseif (strtoupper($countrycode) == "SR") {//Suriname
|
||
| 2369 | if (AlDolUtils::dol_strlen($phone) == 10) {//ex: +597_ABC_DEF
|
||
| 2370 | $newphone = substr($newphone, 0, 4) . $separ . substr($newphone, 4, 3) . $separ . substr($newphone, 7, 3); |
||
| 2371 | } elseif (AlDolUtils::dol_strlen($phone) == 11) {//ex: +597_ABC_DEFG
|
||
| 2372 | $newphone = substr($newphone, 0, 4) . $separ . substr($newphone, 4, 3) . $separ . substr($newphone, 7, 4); |
||
| 2373 | } |
||
| 2374 | } elseif (strtoupper($countrycode) == "DE") {//Allemagne
|
||
| 2375 | if (AlDolUtils::dol_strlen($phone) == 14) {//ex: +49_ABCD_EFGH_IJK
|
||
| 2376 | $newphone = substr($newphone, 0, 3) . $separ . substr($newphone, 3, 4) . $separ . substr($newphone, 7, 4) . $separ . substr($newphone, 11, 3); |
||
| 2377 | } elseif (AlDolUtils::dol_strlen($phone) == 13) {//ex: +49_ABC_DEFG_HIJ
|
||
| 2378 | $newphone = substr($newphone, 0, 3) . $separ . substr($newphone, 3, 3) . $separ . substr($newphone, 6, 4) . $separ . substr($newphone, 10, 3); |
||
| 2379 | } |
||
| 2380 | } elseif (strtoupper($countrycode) == "ES") {//Espagne
|
||
| 2381 | if (AlDolUtils::dol_strlen($phone) == 12) {//ex: +34_ABC_DEF_GHI
|
||
| 2382 | $newphone = substr($newphone, 0, 3) . $separ . substr($newphone, 3, 3) . $separ . substr($newphone, 6, 3) . $separ . substr($newphone, 9, 3); |
||
| 2383 | } |
||
| 2384 | } elseif (strtoupper($countrycode) == "BF") {// Burkina Faso
|
||
| 2385 | if (AlDolUtils::dol_strlen($phone) == 12) {//ex : +22 A BC_DE_FG_HI
|
||
| 2386 | $newphone = substr($newphone, 0, 3) . $separ . substr($newphone, 3, 1) . $separ . substr($newphone, 4, 2) . $separ . substr($newphone, 6, 2) . $separ . substr($newphone, 8, 2) . $separ . substr($newphone, 10, 2); |
||
| 2387 | } |
||
| 2388 | } elseif (strtoupper($countrycode) == "RO") {// Roumanie
|
||
| 2389 | if (AlDolUtils::dol_strlen($phone) == 12) {//ex : +40 AB_CDE_FG_HI
|
||
| 2390 | $newphone = substr($newphone, 0, 3) . $separ . substr($newphone, 3, 2) . $separ . substr($newphone, 5, 3) . $separ . substr($newphone, 8, 2) . $separ . substr($newphone, 10, 2); |
||
| 2391 | } |
||
| 2392 | } elseif (strtoupper($countrycode) == "TR") {//Turquie
|
||
| 2393 | if (AlDolUtils::dol_strlen($phone) == 13) {//ex : +90 ABC_DEF_GHIJ
|
||
| 2394 | $newphone = substr($newphone, 0, 3) . $separ . substr($newphone, 3, 3) . $separ . substr($newphone, 6, 3) . $separ . substr($newphone, 9, 4); |
||
| 2395 | } |
||
| 2396 | } elseif (strtoupper($countrycode) == "US") {//Etat-Unis
|
||
| 2397 | if (AlDolUtils::dol_strlen($phone) == 12) {//ex: +1 ABC_DEF_GHIJ
|
||
| 2398 | $newphone = substr($newphone, 0, 2) . $separ . substr($newphone, 2, 3) . $separ . substr($newphone, 5, 3) . $separ . substr($newphone, 8, 4); |
||
| 2399 | } |
||
| 2400 | } elseif (strtoupper($countrycode) == "MX") {//Mexique
|
||
| 2401 | if (AlDolUtils::dol_strlen($phone) == 12) {//ex: +52 ABCD_EFG_HI
|
||
| 2402 | $newphone = substr($newphone, 0, 3) . $separ . substr($newphone, 3, 4) . $separ . substr($newphone, 7, 3) . $separ . substr($newphone, 10, 2); |
||
| 2403 | } elseif (AlDolUtils::dol_strlen($phone) == 11) {//ex: +52 AB_CD_EF_GH
|
||
| 2404 | $newphone = substr($newphone, 0, 3) . $separ . substr($newphone, 3, 2) . $separ . substr($newphone, 5, 2) . $separ . substr($newphone, 7, 2) . $separ . substr($newphone, 9, 2); |
||
| 2405 | } elseif (AlDolUtils::dol_strlen($phone) == 13) {//ex: +52 ABC_DEF_GHIJ
|
||
| 2406 | $newphone = substr($newphone, 0, 3) . $separ . substr($newphone, 3, 3) . $separ . substr($newphone, 6, 3) . $separ . substr($newphone, 9, 4); |
||
| 2407 | } |
||
| 2408 | } elseif (strtoupper($countrycode) == "ML") {//Mali
|
||
| 2409 | if (AlDolUtils::dol_strlen($phone) == 12) {//ex: +223 AB_CD_EF_GH
|
||
| 2410 | $newphone = substr($newphone, 0, 4) . $separ . substr($newphone, 4, 2) . $separ . substr($newphone, 6, 2) . $separ . substr($newphone, 8, 2) . $separ . substr($newphone, 10, 2); |
||
| 2411 | } |
||
| 2412 | } elseif (strtoupper($countrycode) == "TH") {//Thaïlande
|
||
| 2413 | if (AlDolUtils::dol_strlen($phone) == 11) {//ex: +66_ABC_DE_FGH
|
||
| 2414 | $newphone = substr($newphone, 0, 3) . $separ . substr($newphone, 3, 3) . $separ . substr($newphone, 6, 2) . $separ . substr($newphone, 8, 3); |
||
| 2415 | } elseif (AlDolUtils::dol_strlen($phone) == 12) {//ex: +66_A_BCD_EF_GHI
|
||
| 2416 | $newphone = substr($newphone, 0, 3) . $separ . substr($newphone, 3, 1) . $separ . substr($newphone, 4, 3) . $separ . substr($newphone, 7, 2) . $separ . substr($newphone, 9, 3); |
||
| 2417 | } |
||
| 2418 | } elseif (strtoupper($countrycode) == "MU") {//Maurice
|
||
| 2419 | if (AlDolUtils::dol_strlen($phone) == 11) {//ex: +230_ABC_DE_FG
|
||
| 2420 | $newphone = substr($newphone, 0, 4) . $separ . substr($newphone, 4, 3) . $separ . substr($newphone, 7, 2) . $separ . substr($newphone, 9, 2); |
||
| 2421 | } elseif (AlDolUtils::dol_strlen($phone) == 12) {//ex: +230_ABCD_EF_GH
|
||
| 2422 | $newphone = substr($newphone, 0, 4) . $separ . substr($newphone, 4, 4) . $separ . substr($newphone, 8, 2) . $separ . substr($newphone, 10, 2); |
||
| 2423 | } |
||
| 2424 | } elseif (strtoupper($countrycode) == "ZA") {//Afrique du sud
|
||
| 2425 | if (AlDolUtils::dol_strlen($phone) == 12) {//ex: +27_AB_CDE_FG_HI
|
||
| 2426 | $newphone = substr($newphone, 0, 3) . $separ . substr($newphone, 3, 2) . $separ . substr($newphone, 5, 3) . $separ . substr($newphone, 8, 2) . $separ . substr($newphone, 10, 2); |
||
| 2427 | } |
||
| 2428 | } elseif (strtoupper($countrycode) == "SY") {//Syrie
|
||
| 2429 | if (AlDolUtils::dol_strlen($phone) == 12) {//ex: +963_AB_CD_EF_GH
|
||
| 2430 | $newphone = substr($newphone, 0, 4) . $separ . substr($newphone, 4, 2) . $separ . substr($newphone, 6, 2) . $separ . substr($newphone, 8, 2) . $separ . substr($newphone, 10, 2); |
||
| 2431 | } elseif (AlDolUtils::dol_strlen($phone) == 13) {//ex: +963_AB_CD_EF_GHI
|
||
| 2432 | $newphone = substr($newphone, 0, 4) . $separ . substr($newphone, 4, 2) . $separ . substr($newphone, 6, 2) . $separ . substr($newphone, 8, 2) . $separ . substr($newphone, 10, 3); |
||
| 2433 | } |
||
| 2434 | } elseif (strtoupper($countrycode) == "AE") {//Emirats Arabes Unis
|
||
| 2435 | if (AlDolUtils::dol_strlen($phone) == 12) {//ex: +971_ABC_DEF_GH
|
||
| 2436 | $newphone = substr($newphone, 0, 4) . $separ . substr($newphone, 4, 3) . $separ . substr($newphone, 7, 3) . $separ . substr($newphone, 10, 2); |
||
| 2437 | } elseif (AlDolUtils::dol_strlen($phone) == 13) {//ex: +971_ABC_DEF_GHI
|
||
| 2438 | $newphone = substr($newphone, 0, 4) . $separ . substr($newphone, 4, 3) . $separ . substr($newphone, 7, 3) . $separ . substr($newphone, 10, 3); |
||
| 2439 | } elseif (AlDolUtils::dol_strlen($phone) == 14) {//ex: +971_ABC_DEF_GHIK
|
||
| 2440 | $newphone = substr($newphone, 0, 4) . $separ . substr($newphone, 4, 3) . $separ . substr($newphone, 7, 3) . $separ . substr($newphone, 10, 4); |
||
| 2441 | } |
||
| 2442 | } elseif (strtoupper($countrycode) == "DZ") {//Algérie
|
||
| 2443 | if (AlDolUtils::dol_strlen($phone) == 13) {//ex: +213_ABC_DEF_GHI
|
||
| 2444 | $newphone = substr($newphone, 0, 4) . $separ . substr($newphone, 4, 3) . $separ . substr($newphone, 7, 3) . $separ . substr($newphone, 10, 3); |
||
| 2445 | } |
||
| 2446 | } elseif (strtoupper($countrycode) == "BE") {//Belgique
|
||
| 2447 | if (AlDolUtils::dol_strlen($phone) == 11) {//ex: +32_ABC_DE_FGH
|
||
| 2448 | $newphone = substr($newphone, 0, 3) . $separ . substr($newphone, 3, 3) . $separ . substr($newphone, 6, 2) . $separ . substr($newphone, 8, 3); |
||
| 2449 | } elseif (AlDolUtils::dol_strlen($phone) == 12) {//ex: +32_ABC_DEF_GHI
|
||
| 2450 | $newphone = substr($newphone, 0, 3) . $separ . substr($newphone, 3, 3) . $separ . substr($newphone, 6, 3) . $separ . substr($newphone, 9, 3); |
||
| 2451 | } |
||
| 2452 | } elseif (strtoupper($countrycode) == "PF") {//Polynésie française
|
||
| 2453 | if (AlDolUtils::dol_strlen($phone) == 12) {//ex: +689_AB_CD_EF_GH
|
||
| 2454 | $newphone = substr($newphone, 0, 4) . $separ . substr($newphone, 4, 2) . $separ . substr($newphone, 6, 2) . $separ . substr($newphone, 8, 2) . $separ . substr($newphone, 10, 2); |
||
| 2455 | } |
||
| 2456 | } elseif (strtoupper($countrycode) == "CO") {//Colombie
|
||
| 2457 | if (AlDolUtils::dol_strlen($phone) == 13) {//ex: +57_ABC_DEF_GH_IJ
|
||
| 2458 | $newphone = substr($newphone, 0, 3) . $separ . substr($newphone, 3, 3) . $separ . substr($newphone, 6, 3) . $separ . substr($newphone, 9, 2) . $separ . substr($newphone, 11, 2); |
||
| 2459 | } |
||
| 2460 | } elseif (strtoupper($countrycode) == "JO") {//Jordanie
|
||
| 2461 | if (AlDolUtils::dol_strlen($phone) == 12) {//ex: +962_A_BCD_EF_GH
|
||
| 2462 | $newphone = substr($newphone, 0, 4) . $separ . substr($newphone, 4, 1) . $separ . substr($newphone, 5, 3) . $separ . substr($newphone, 7, 2) . $separ . substr($newphone, 9, 2); |
||
| 2463 | } |
||
| 2464 | } elseif (strtoupper($countrycode) == "MG") {//Madagascar
|
||
| 2465 | if (AlDolUtils::dol_strlen($phone) == 13) {//ex: +261_AB_CD_EF_GHI
|
||
| 2466 | $newphone = substr($newphone, 0, 4) . $separ . substr($newphone, 4, 2) . $separ . substr($newphone, 6, 2) . $separ . substr($newphone, 8, 2) . $separ . substr($newphone, 10, 3); |
||
| 2467 | } |
||
| 2468 | } elseif (strtoupper($countrycode) == "GB") {//Royaume uni
|
||
| 2469 | if (AlDolUtils::dol_strlen($phone) == 13) {//ex: +44_ABCD_EFG_HIJ
|
||
| 2470 | $newphone = substr($newphone, 0, 3) . $separ . substr($newphone, 3, 4) . $separ . substr($newphone, 7, 3) . $separ . substr($newphone, 10, 3); |
||
| 2471 | } |
||
| 2472 | } elseif (strtoupper($countrycode) == "CH") {//Suisse
|
||
| 2473 | if (AlDolUtils::dol_strlen($phone) == 12) {//ex: +41_AB_CDE_FG_HI
|
||
| 2474 | $newphone = substr($newphone, 0, 3) . $separ . substr($newphone, 3, 2) . $separ . substr($newphone, 5, 3) . $separ . substr($newphone, 8, 2) . $separ . substr($newphone, 10, 2); |
||
| 2475 | } elseif (AlDolUtils::dol_strlen($phone) == 15) {// +41_AB_CDE_FGH_IJKL
|
||
| 2476 | $newphone = $newphone = substr($newphone, 0, 3) . $separ . substr($newphone, 3, 2) . $separ . substr($newphone, 5, 3) . $separ . substr($newphone, 8, 3) . $separ . substr($newphone, 11, 4); |
||
| 2477 | } |
||
| 2478 | } elseif (strtoupper($countrycode) == "TN") {//Tunisie
|
||
| 2479 | if (AlDolUtils::dol_strlen($phone) == 12) {//ex: +216_AB_CDE_FGH
|
||
| 2480 | $newphone = substr($newphone, 0, 4) . $separ . substr($newphone, 4, 2) . $separ . substr($newphone, 6, 3) . $separ . substr($newphone, 9, 3); |
||
| 2481 | } |
||
| 2482 | } elseif (strtoupper($countrycode) == "GF") {//Guyane francaise
|
||
| 2483 | if (AlDolUtils::dol_strlen($phone) == 13) {//ex: +594_ABC_DE_FG_HI (ABC=594 de nouveau)
|
||
| 2484 | $newphone = substr($newphone, 0, 4) . $separ . substr($newphone, 4, 3) . $separ . substr($newphone, 7, 2) . $separ . substr($newphone, 9, 2) . $separ . substr($newphone, 11, 2); |
||
| 2485 | } |
||
| 2486 | } elseif (strtoupper($countrycode) == "GP") {//Guadeloupe
|
||
| 2487 | if (AlDolUtils::dol_strlen($phone) == 13) {//ex: +590_ABC_DE_FG_HI (ABC=590 de nouveau)
|
||
| 2488 | $newphone = substr($newphone, 0, 4) . $separ . substr($newphone, 4, 3) . $separ . substr($newphone, 7, 2) . $separ . substr($newphone, 9, 2) . $separ . substr($newphone, 11, 2); |
||
| 2489 | } |
||
| 2490 | } elseif (strtoupper($countrycode) == "MQ") {//Martinique
|
||
| 2491 | if (AlDolUtils::dol_strlen($phone) == 13) {//ex: +596_ABC_DE_FG_HI (ABC=596 de nouveau)
|
||
| 2492 | $newphone = substr($newphone, 0, 4) . $separ . substr($newphone, 4, 3) . $separ . substr($newphone, 7, 2) . $separ . substr($newphone, 9, 2) . $separ . substr($newphone, 11, 2); |
||
| 2493 | } |
||
| 2494 | } elseif (strtoupper($countrycode) == "IT") {//Italie
|
||
| 2495 | if (AlDolUtils::dol_strlen($phone) == 12) {//ex: +39_ABC_DEF_GHI
|
||
| 2496 | $newphone = substr($newphone, 0, 3) . $separ . substr($newphone, 3, 3) . $separ . substr($newphone, 6, 3) . $separ . substr($newphone, 9, 3); |
||
| 2497 | } elseif (AlDolUtils::dol_strlen($phone) == 13) {//ex: +39_ABC_DEF_GH_IJ
|
||
| 2498 | $newphone = substr($newphone, 0, 3) . $separ . substr($newphone, 3, 3) . $separ . substr($newphone, 6, 3) . $separ . substr($newphone, 9, 2) . $separ . substr($newphone, 11, 2); |
||
| 2499 | } |
||
| 2500 | } elseif (strtoupper($countrycode) == "AU") {//Australie
|
||
| 2501 | if (AlDolUtils::dol_strlen($phone) == 12) {//ex: +61_A_BCDE_FGHI
|
||
| 2502 | $newphone = substr($newphone, 0, 3) . $separ . substr($newphone, 3, 1) . $separ . substr($newphone, 4, 4) . $separ . substr($newphone, 8, 4); |
||
| 2503 | } |
||
| 2504 | } |
||
| 2505 | if (!empty($addlink)) { // Link on phone number (+ link to add action if conf->global->AGENDA_ADDACTIONFORPHONE set)
|
||
| 2506 | if (Globals::$conf->browser->layout == 'phone' || (!empty(Globals::$conf->clicktodial->enabled) && !empty(Globals::$conf->global->CLICKTODIAL_USE_TEL_LINK_ON_PHONE_NUMBERS))) { // If phone or option for, we use link of phone
|
||
| 2507 | $newphone = '<a href="tel:' . $phone . '"'; |
||
| 2508 | $newphone .= '>' . $phone . '</a>'; |
||
| 2509 | } else if (!empty(Globals::$conf->clicktodial->enabled) && $addlink == 'AC_TEL') { // If click to dial, we use click to dial url
|
||
| 2510 | if (empty($user->clicktodial_loaded)) |
||
| 2511 | $user->fetch_clicktodial(); |
||
| 2512 | |||
| 2513 | // Define urlmask |
||
| 2514 | $urlmask = 'ErrorClickToDialModuleNotConfigured'; |
||
| 2515 | if (!empty(Globals::$conf->global->CLICKTODIAL_URL)) |
||
| 2516 | $urlmask = Globals::$conf->global->CLICKTODIAL_URL; |
||
| 2517 | if (!empty($user->clicktodial_url)) |
||
| 2518 | $urlmask = $user->clicktodial_url; |
||
| 2519 | |||
| 2520 | $clicktodial_poste = (!empty($user->clicktodial_poste) ? urlencode($user->clicktodial_poste) : ''); |
||
| 2521 | $clicktodial_login = (!empty($user->clicktodial_login) ? urlencode($user->clicktodial_login) : ''); |
||
| 2522 | $clicktodial_password = (!empty($user->clicktodial_password) ? urlencode($user->clicktodial_password) : ''); |
||
| 2523 | // This line is for backward compatibility |
||
| 2524 | $url = sprintf($urlmask, urlencode($phone), $clicktodial_poste, $clicktodial_login, $clicktodial_password); |
||
| 2525 | // Thoose lines are for substitution |
||
| 2526 | $substitarray = array('__PHONEFROM__' => $clicktodial_poste,
|
||
| 2527 | '__PHONETO__' => urlencode($phone), |
||
| 2528 | '__LOGIN__' => $clicktodial_login, |
||
| 2529 | '__PASS__' => $clicktodial_password); |
||
| 2530 | $url = make_substitutions($url, $substitarray); |
||
| 2531 | $newphonesav = $newphone; |
||
| 2532 | $newphone = '<a href="' . $url . '"'; |
||
| 2533 | if (!empty(Globals::$conf->global->CLICKTODIAL_FORCENEWTARGET)) |
||
| 2534 | $newphone .= ' target="_blank"'; |
||
| 2535 | $newphone .= '>' . $newphonesav . '</a>'; |
||
| 2536 | } |
||
| 2537 | |||
| 2538 | //if (($cid || $socid) && ! empty(Globals::$conf->agenda->enabled) && $user->rights->agenda->myactions->create) |
||
| 2539 | if (!empty(Globals::$conf->agenda->enabled) && $user->rights->agenda->myactions->create) {
|
||
| 2540 | $type = 'AC_TEL'; |
||
| 2541 | $link = ''; |
||
| 2542 | if ($addlink == 'AC_FAX') |
||
| 2543 | $type = 'AC_FAX'; |
||
| 2544 | if (!empty(Globals::$conf->global->AGENDA_ADDACTIONFORPHONE)) |
||
| 2545 | $link = '<a href="' . DOL_BASE_URI . '/comm/action/card.php?action=create&backtopage=1&actioncode=' . $type . ($cid ? '&contactid=' . $cid : '') . ($socid ? '&socid=' . $socid : '') . '">' . img_object(Globals::$langs->trans("AddAction"), "calendar") . '</a>';
|
||
| 2546 | if ($link) |
||
| 2547 | $newphone = '<div>' . $newphone . ' ' . $link . '</div>'; |
||
| 2548 | } |
||
| 2549 | } |
||
| 2550 | |||
| 2551 | if (empty($titlealt)) {
|
||
| 2552 | $titlealt = ($withpicto == 'fax' ? Globals::$langs->trans("Fax") : Globals::$langs->trans("Phone"));
|
||
| 2553 | } |
||
| 2554 | $rep = ''; |
||
| 2555 | |||
| 2556 | if (Globals::$hookManager) {
|
||
| 2557 | $parameters = array('countrycode' => $countrycode, 'cid' => $cid, 'socid' => $socid, 'titlealt' => $titlealt, 'picto' => $withpicto);
|
||
| 2558 | $reshook = Globals::$hookManager->executeHooks('printPhone', $parameters, $phone);
|
||
| 2559 | $rep .= Globals::$hookManager->resPrint; |
||
| 2560 | } |
||
| 2561 | if (empty($reshook)) {
|
||
| 2562 | $picto = ''; |
||
| 2563 | if ($withpicto) {
|
||
| 2564 | if ($withpicto == 'fax') {
|
||
| 2565 | $picto = 'phoning_fax'; |
||
| 2566 | } elseif ($withpicto == 'phone') {
|
||
| 2567 | $picto = 'phoning'; |
||
| 2568 | } elseif ($withpicto == 'mobile') {
|
||
| 2569 | $picto = 'phoning_mobile'; |
||
| 2570 | } else {
|
||
| 2571 | $picto = ''; |
||
| 2572 | } |
||
| 2573 | } |
||
| 2574 | if ($adddivfloat) |
||
| 2575 | $rep .= '<div class="nospan float" style="margin-right: 10px">'; |
||
| 2576 | else |
||
| 2577 | $rep .= '<span style="margin-right: 10px;">'; |
||
| 2578 | $rep .= ($withpicto ? img_picto($titlealt, 'object_' . $picto . '.png') . ' ' : '') . $newphone; |
||
| 2579 | if ($adddivfloat) |
||
| 2580 | $rep .= '</div>'; |
||
| 2581 | else |
||
| 2582 | $rep .= '</span>'; |
||
| 2583 | } |
||
| 2584 | |||
| 2585 | return $rep; |
||
| 2586 | } |
||
| 2587 | |||
| 2588 | /** |
||
| 2589 | * Return an IP formated to be shown on screen |
||
| 2590 | * |
||
| 2591 | * @param string $ip IP |
||
| 2592 | * @param int $mode 0=return IP + country/flag, 1=return only country/flag, 2=return only IP |
||
| 2593 | * @return string Formated IP, with country if GeoIP module is enabled |
||
| 2594 | */ |
||
| 2595 | static function dol_print_ip($ip, $mode = 0) |
||
| 2596 | {
|
||
| 2597 | // global Globals::$conf, Globals::$langs; |
||
| 2598 | |||
| 2599 | $ret = ''; |
||
| 2600 | |||
| 2601 | if (empty($mode)) {
|
||
| 2602 | $ret .= $ip; |
||
| 2603 | } |
||
| 2604 | |||
| 2605 | echo ('<p>DOL_BASE_PATH: ' . DOL_BASE_PATH . '/DOL_BASE_URI: ' . DOL_BASE_URI . '</p>');
|
||
| 2606 | |||
| 2607 | if ($mode != 2) {
|
||
| 2608 | $countrycode = dolGetCountryCodeFromIp($ip); |
||
| 2609 | if ($countrycode) { // If success, countrycode is us, fr, ...
|
||
| 2610 | if (file_exists(DOL_BASE_PATH . '/theme/common/flags/' . $countrycode . '.png')) {
|
||
| 2611 | $ret .= ' ' . img_picto($countrycode . ' ' . Globals::$langs->trans("AccordingToGeoIPDatabase"), DOL_BASE_URI . '/theme/common/flags/' . $countrycode . '.png', '', 1);
|
||
| 2612 | } else |
||
| 2613 | $ret .= ' (' . $countrycode . ')';
|
||
| 2614 | } |
||
| 2615 | } |
||
| 2616 | |||
| 2617 | return $ret; |
||
| 2618 | } |
||
| 2619 | |||
| 2620 | /** |
||
| 2621 | * Return the IP of remote user. |
||
| 2622 | * Take HTTP_X_FORWARDED_FOR (defined when using proxy) |
||
| 2623 | * Then HTTP_CLIENT_IP if defined (rare) |
||
| 2624 | * Then REMOTE_ADDR (not way to be modified by user but may be wrong if using proxy) |
||
| 2625 | * |
||
| 2626 | * @return string Ip of remote user. |
||
| 2627 | */ |
||
| 2628 | static function getUserRemoteIP() |
||
| 2629 | {
|
||
| 2630 | $ip = empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? (empty($_SERVER['HTTP_CLIENT_IP']) ? (empty($_SERVER['REMOTE_ADDR']) ? '' : $_SERVER['REMOTE_ADDR']) : $_SERVER['HTTP_CLIENT_IP']) : $_SERVER['HTTP_X_FORWARDED_FOR']; |
||
| 2631 | return $ip; |
||
| 2632 | } |
||
| 2633 | |||
| 2634 | /** |
||
| 2635 | * Return a country code from IP. Empty string if not found. |
||
| 2636 | * |
||
| 2637 | * @param string $ip IP |
||
| 2638 | * @return string Country code ('us', 'fr', ...)
|
||
| 2639 | */ |
||
| 2640 | static function dolGetCountryCodeFromIp($ip) |
||
| 2641 | {
|
||
| 2642 | // global Globals::$conf; |
||
| 2643 | |||
| 2644 | $countrycode = ''; |
||
| 2645 | |||
| 2646 | if (!empty(Globals::$conf->geoipmaxmind->enabled)) {
|
||
| 2647 | $datafile = Globals::$conf->global->GEOIPMAXMIND_COUNTRY_DATAFILE; |
||
| 2648 | //$ip='24.24.24.24'; |
||
| 2649 | //$datafile='E:\Mes Sites\Web\Admin1\awstats\maxmind\GeoIP.dat'; Note that this must be downloaded datafile (not same than datafile provided with ubuntu packages) |
||
| 2650 | |||
| 2651 | include_once DOL_BASE_PATH . '/core/class/dolgeoip.class.php'; |
||
| 2652 | $geoip = new DolGeoIP('country', $datafile);
|
||
| 2653 | //print 'ip='.$ip.' databaseType='.$geoip->gi->databaseType." GEOIP_CITY_EDITION_REV1=".GEOIP_CITY_EDITION_REV1."\n"; |
||
| 2654 | //print "geoip_country_id_by_addr=".geoip_country_id_by_addr($geoip->gi,$ip)."\n"; |
||
| 2655 | $countrycode = $geoip->getCountryCodeFromIP($ip); |
||
| 2656 | } |
||
| 2657 | |||
| 2658 | return $countrycode; |
||
| 2659 | } |
||
| 2660 | |||
| 2661 | /** |
||
| 2662 | * Return country code for current user. |
||
| 2663 | * If software is used inside a local network, detection may fails (we need a public ip) |
||
| 2664 | * |
||
| 2665 | * @return string Country code (fr, es, it, us, ...) |
||
| 2666 | */ |
||
| 2667 | static function dol_user_country() |
||
| 2668 | {
|
||
| 2669 | // global Globals::$conf, Globals::$langs, $user; |
||
| 2670 | //$ret=$user->xxx; |
||
| 2671 | $ret = ''; |
||
| 2672 | if (!empty(Globals::$conf->geoipmaxmind->enabled)) {
|
||
| 2673 | $ip = getUserRemoteIP(); |
||
| 2674 | $datafile = Globals::$conf->global->GEOIPMAXMIND_COUNTRY_DATAFILE; |
||
| 2675 | //$ip='24.24.24.24'; |
||
| 2676 | //$datafile='E:\Mes Sites\Web\Admin1\awstats\maxmind\GeoIP.dat'; |
||
| 2677 | include_once DOL_BASE_PATH . '/core/class/dolgeoip.class.php'; |
||
| 2678 | $geoip = new DolGeoIP('country', $datafile);
|
||
| 2679 | $countrycode = $geoip->getCountryCodeFromIP($ip); |
||
| 2680 | $ret = $countrycode; |
||
| 2681 | } |
||
| 2682 | return $ret; |
||
| 2683 | } |
||
| 2684 | |||
| 2685 | /** |
||
| 2686 | * Format address string |
||
| 2687 | * |
||
| 2688 | * @param string $address Address |
||
| 2689 | * @param int $htmlid Html ID (for example 'gmap') |
||
| 2690 | * @param int $mode thirdparty|contact|member|other |
||
| 2691 | * @param int $id Id of object |
||
| 2692 | * @param int $noprint No output. Result is the static function return |
||
| 2693 | * @param string $charfornl Char to use instead of nl2br. '' means we use a standad nl2br. |
||
| 2694 | * @return string|void Nothing if noprint is 0, formatted address if noprint is 1 |
||
| 2695 | * @see dol_format_address |
||
| 2696 | */ |
||
| 2697 | static function dol_print_address($address, $htmlid, $mode, $id, $noprint = 0, $charfornl = '') |
||
| 2698 | {
|
||
| 2699 | // global Globals::$conf, $user, Globals::$langs, Globals::$hookManager; |
||
| 2700 | |||
| 2701 | $out = ''; |
||
| 2702 | |||
| 2703 | if ($address) {
|
||
| 2704 | if (Globals::$hookManager) {
|
||
| 2705 | $parameters = array('element' => $mode, 'id' => $id);
|
||
| 2706 | $reshook = Globals::$hookManager->executeHooks('printAddress', $parameters, $address);
|
||
| 2707 | $out .= Globals::$hookManager->resPrint; |
||
| 2708 | } |
||
| 2709 | if (empty($reshook)) {
|
||
| 2710 | if (empty($charfornl)) |
||
| 2711 | $out .= nl2br($address); |
||
| 2712 | else |
||
| 2713 | $out .= preg_replace('/[\r\n]+/', $charfornl, $address);
|
||
| 2714 | |||
| 2715 | $showgmap = $showomap = 0; |
||
| 2716 | |||
| 2717 | // TODO Add a hook here |
||
| 2718 | if (($mode == 'thirdparty' || $mode == 'societe') && !empty(Globals::$conf->google->enabled) && !empty(Globals::$conf->global->GOOGLE_ENABLE_GMAPS)) |
||
| 2719 | $showgmap = 1; |
||
| 2720 | if ($mode == 'contact' && !empty(Globals::$conf->google->enabled) && !empty(Globals::$conf->global->GOOGLE_ENABLE_GMAPS_CONTACTS)) |
||
| 2721 | $showgmap = 1; |
||
| 2722 | if ($mode == 'member' && !empty(Globals::$conf->google->enabled) && !empty(Globals::$conf->global->GOOGLE_ENABLE_GMAPS_MEMBERS)) |
||
| 2723 | $showgmap = 1; |
||
| 2724 | if (($mode == 'thirdparty' || $mode == 'societe') && !empty(Globals::$conf->openstreetmap->enabled) && !empty(Globals::$conf->global->OPENSTREETMAP_ENABLE_MAPS)) |
||
| 2725 | $showomap = 1; |
||
| 2726 | if ($mode == 'contact' && !empty(Globals::$conf->openstreetmap->enabled) && !empty(Globals::$conf->global->OPENSTREETMAP_ENABLE_MAPS_CONTACTS)) |
||
| 2727 | $showomap = 1; |
||
| 2728 | if ($mode == 'member' && !empty(Globals::$conf->openstreetmap->enabled) && !empty(Globals::$conf->global->OPENSTREETMAP_ENABLE_MAPS_MEMBERS)) |
||
| 2729 | $showomap = 1; |
||
| 2730 | |||
| 2731 | if ($showgmap) {
|
||
| 2732 | $url = dol_buildpath('/google/gmaps.php?mode=' . $mode . '&id=' . $id, 1);
|
||
| 2733 | $out .= ' <a href="' . $url . '" target="_gmaps"><img id="' . $htmlid . '" class="valigntextbottom" src="' . DOL_BASE_URI . '/theme/common/gmap.png"></a>'; |
||
| 2734 | } |
||
| 2735 | if ($showomap) {
|
||
| 2736 | $url = dol_buildpath('/openstreetmap/maps.php?mode=' . $mode . '&id=' . $id, 1);
|
||
| 2737 | $out .= ' <a href="' . $url . '" target="_gmaps"><img id="' . $htmlid . '_openstreetmap" class="valigntextbottom" src="' . DOL_BASE_URI . '/theme/common/gmap.png"></a>'; |
||
| 2738 | } |
||
| 2739 | } |
||
| 2740 | } |
||
| 2741 | if ($noprint) |
||
| 2742 | return $out; |
||
| 2743 | else |
||
| 2744 | print $out; |
||
| 2745 | } |
||
| 2746 | |||
| 2747 | /** |
||
| 2748 | * Return true if email syntax is ok |
||
| 2749 | * |
||
| 2750 | * @param string $address email (Ex: "[email protected]", "John Do <[email protected]>") |
||
| 2751 | * @param int $acceptsupervisorkey If 1, the special string '__SUPERVISOREMAIL__' is also accepted as valid |
||
| 2752 | * @return boolean true if email syntax is OK, false if KO or empty string |
||
| 2753 | */ |
||
| 2754 | static function isValidEmail($address, $acceptsupervisorkey = 0) |
||
| 2755 | {
|
||
| 2756 | if ($acceptsupervisorkey && $address == '__SUPERVISOREMAIL__') |
||
| 2757 | return true; |
||
| 2758 | if (filter_var($address, FILTER_VALIDATE_EMAIL)) |
||
| 2759 | return true; |
||
| 2760 | |||
| 2761 | return false; |
||
| 2762 | } |
||
| 2763 | |||
| 2764 | /** |
||
| 2765 | * Return if the domain name has a valid MX record. |
||
| 2766 | * WARNING: This need static function idn_to_ascii, checkdnsrr and getmxrr |
||
| 2767 | * |
||
| 2768 | * @param string $domain Domain name (Ex: "yahoo.com", "yhaoo.com", "dolibarr.fr") |
||
| 2769 | * @return int -1 if error (static function not available), 0=Not valid, 1=Valid |
||
| 2770 | */ |
||
| 2771 | static function isValidMXRecord($domain) |
||
| 2772 | {
|
||
| 2773 | if (function_exists('idn_to_ascii') && function_exists('checkdnsrr')) {
|
||
| 2774 | if (!checkdnsrr(idn_to_ascii($domain), 'MX')) {
|
||
| 2775 | return 0; |
||
| 2776 | } |
||
| 2777 | if (function_exists('getmxrr')) {
|
||
| 2778 | $mxhosts = array(); |
||
| 2779 | $weight = array(); |
||
| 2780 | getmxrr(idn_to_ascii($domain), $mxhosts, $weight); |
||
| 2781 | if (count($mxhosts) > 1) |
||
| 2782 | return 1; |
||
| 2783 | if (count($mxhosts) == 1 && !empty($mxhosts[0])) |
||
| 2784 | return 1; |
||
| 2785 | |||
| 2786 | return 0; |
||
| 2787 | } |
||
| 2788 | } |
||
| 2789 | return -1; |
||
| 2790 | } |
||
| 2791 | |||
| 2792 | /** |
||
| 2793 | * Return true if phone number syntax is ok |
||
| 2794 | * TODO Decide what to do with this |
||
| 2795 | * |
||
| 2796 | * @param string $phone phone (Ex: "0601010101") |
||
| 2797 | * @return boolean true if phone syntax is OK, false if KO or empty string |
||
| 2798 | */ |
||
| 2799 | static function isValidPhone($phone) |
||
| 2800 | {
|
||
| 2801 | return true; |
||
| 2802 | } |
||
| 2803 | |||
| 2804 | /** |
||
| 2805 | * Make a strlen call. Works even if mbstring module not enabled |
||
| 2806 | * |
||
| 2807 | * @param string $string String to calculate length |
||
| 2808 | * @param string $stringencoding Encoding of string |
||
| 2809 | * @return int Length of string |
||
| 2810 | */ |
||
| 2811 | static function dol_strlen($string, $stringencoding = 'UTF-8') |
||
| 2812 | {
|
||
| 2813 | if (function_exists('mb_strlen'))
|
||
| 2814 | return mb_strlen($string, $stringencoding); |
||
| 2815 | else |
||
| 2816 | return strlen($string); |
||
| 2817 | } |
||
| 2818 | |||
| 2819 | /** |
||
| 2820 | * Make a substring. Works even if mbstring module is not enabled for better compatibility. |
||
| 2821 | * |
||
| 2822 | * @param string $string String to scan |
||
| 2823 | * @param string $start Start position |
||
| 2824 | * @param int $length Length (in nb of characters or nb of bytes depending on trunconbytes param) |
||
| 2825 | * @param string $stringencoding Page code used for input string encoding |
||
| 2826 | * @param int $trunconbytes 1=Length is max of bytes instead of max of characters |
||
| 2827 | * @return string substring |
||
| 2828 | */ |
||
| 2829 | static function dol_substr($string, $start, $length, $stringencoding = '', $trunconbytes = 0) |
||
| 2830 | {
|
||
| 2831 | // global Globals::$langs; |
||
| 2832 | |||
| 2833 | if (empty($stringencoding)) |
||
| 2834 | $stringencoding = Globals::$langs->charset_output; |
||
| 2835 | |||
| 2836 | $ret = ''; |
||
| 2837 | if (empty($trunconbytes)) {
|
||
| 2838 | if (function_exists('mb_substr')) {
|
||
| 2839 | $ret = mb_substr($string, $start, $length, $stringencoding); |
||
| 2840 | } else {
|
||
| 2841 | $ret = substr($string, $start, $length); |
||
| 2842 | } |
||
| 2843 | } else {
|
||
| 2844 | if (function_exists('mb_strcut')) {
|
||
| 2845 | $ret = mb_strcut($string, $start, $length, $stringencoding); |
||
| 2846 | } else {
|
||
| 2847 | $ret = substr($string, $start, $length); |
||
| 2848 | } |
||
| 2849 | } |
||
| 2850 | return $ret; |
||
| 2851 | } |
||
| 2852 | |||
| 2853 | /** |
||
| 2854 | * Truncate a string to a particular length adding '...' if string larger than length. |
||
| 2855 | * If length = max length+1, we do no truncate to avoid having just 1 char replaced with '...'. |
||
| 2856 | * MAIN_DISABLE_TRUNC=1 can disable all truncings |
||
| 2857 | * |
||
| 2858 | * @param string $string String to truncate |
||
| 2859 | * @param int $size Max string size visible (excluding ...). 0 for no limit. WARNING: Final string size can have 3 more chars (if we added ..., or if size was max+1 or max+2 or max+3 so it does not worse to replace with ...) |
||
| 2860 | * @param string $trunc Where to trunc: right, left, middle (size must be a 2 power), wrap |
||
| 2861 | * @param string $stringencoding Tell what is source string encoding |
||
| 2862 | * @param int $nodot Truncation do not add ... after truncation. So it's an exact truncation. |
||
| 2863 | * @param int $display Trunc is used to display data and can be changed for small screen. TODO Remove this param (must be dealt with CSS) |
||
| 2864 | * @return string Truncated string. WARNING: length is never higher than $size if $nodot is set, but can be 3 chars higher otherwise. |
||
| 2865 | */ |
||
| 2866 | static function dol_trunc($string, $size = 40, $trunc = 'right', $stringencoding = 'UTF-8', $nodot = 0, $display = 0) |
||
| 2867 | {
|
||
| 2868 | // global Globals::$conf; |
||
| 2869 | |||
| 2870 | if ($size == 0 || !empty(Globals::$conf->global->MAIN_DISABLE_TRUNC)) |
||
| 2871 | return $string; |
||
| 2872 | |||
| 2873 | if (empty($stringencoding)) |
||
| 2874 | $stringencoding = 'UTF-8'; |
||
| 2875 | // reduce for small screen |
||
| 2876 | if (Globals::$conf->dol_optimize_smallscreen == 1 && $display == 1) |
||
| 2877 | $size = round($size / 3); |
||
| 2878 | |||
| 2879 | // We go always here |
||
| 2880 | if ($trunc == 'right') {
|
||
| 2881 | $newstring = AlDolUtils::dol_textishtml($string) ? dol_string_nohtmltag($string, 1) : $string; |
||
| 2882 | if (AlDolUtils::dol_strlen($newstring, $stringencoding) > ($size + ($nodot ? 0 : 3))) // If nodot is 0 and size is 1,2 or 3 chars more, we don't trunc and don't add ... |
||
| 2883 | return dol_substr($newstring, 0, $size, $stringencoding) . ($nodot ? '' : '...'); |
||
| 2884 | else |
||
| 2885 | //return 'u'.$size.'-'.$newstring.'-'.DolUtils::dol_strlen($newstring,$stringencoding).'-'.$string; |
||
| 2886 | return $string; |
||
| 2887 | } |
||
| 2888 | elseif ($trunc == 'middle') {
|
||
| 2889 | $newstring = AlDolUtils::dol_textishtml($string) ? dol_string_nohtmltag($string, 1) : $string; |
||
| 2890 | if (AlDolUtils::dol_strlen($newstring, $stringencoding) > 2 && AlDolUtils::dol_strlen($newstring, $stringencoding) > ($size + 1)) {
|
||
| 2891 | $size1 = round($size / 2); |
||
| 2892 | $size2 = round($size / 2); |
||
| 2893 | return dol_substr($newstring, 0, $size1, $stringencoding) . '...' . dol_substr($newstring, AlDolUtils::dol_strlen($newstring, $stringencoding) - $size2, $size2, $stringencoding); |
||
| 2894 | } else |
||
| 2895 | return $string; |
||
| 2896 | } |
||
| 2897 | elseif ($trunc == 'left') {
|
||
| 2898 | $newstring = AlDolUtils::dol_textishtml($string) ? dol_string_nohtmltag($string, 1) : $string; |
||
| 2899 | if (AlDolUtils::dol_strlen($newstring, $stringencoding) > ($size + ($nodot ? 0 : 3))) // If nodot is 0 and size is 1,2 or 3 chars more, we don't trunc and don't add ... |
||
| 2900 | return '...' . dol_substr($newstring, AlDolUtils::dol_strlen($newstring, $stringencoding) - $size, $size, $stringencoding); |
||
| 2901 | else |
||
| 2902 | return $string; |
||
| 2903 | } |
||
| 2904 | elseif ($trunc == 'wrap') {
|
||
| 2905 | $newstring = AlDolUtils::dol_textishtml($string) ? dol_string_nohtmltag($string, 1) : $string; |
||
| 2906 | if (AlDolUtils::dol_strlen($newstring, $stringencoding) > ($size + 1)) |
||
| 2907 | return dol_substr($newstring, 0, $size, $stringencoding) . "\n" . dol_trunc(dol_substr($newstring, $size, AlDolUtils::dol_strlen($newstring, $stringencoding) - $size, $stringencoding), $size, $trunc); |
||
| 2908 | else |
||
| 2909 | return $string; |
||
| 2910 | } else |
||
| 2911 | return 'BadParam3CallingDolTrunc'; |
||
| 2912 | } |
||
| 2913 | |||
| 2914 | /** |
||
| 2915 | * Show picto whatever it's its name (generic function) |
||
| 2916 | * |
||
| 2917 | * @param string $titlealt Text on title tag for tooltip. Not used if param notitle is set to 1. |
||
| 2918 | * @param string $picto Name of image file to show ('filenew', ...)
|
||
| 2919 | * If no extension provided, we use '.png'. Image must be stored into theme/xxx/img directory. |
||
| 2920 | * Example: picto.png if picto.png is stored into htdocs/theme/mytheme/img |
||
| 2921 | * Example: picto.png@mymodule if picto.png is stored into htdocs/mymodule/img |
||
| 2922 | * Example: /mydir/mysubdir/picto.png if picto.png is stored into htdocs/mydir/mysubdir (pictoisfullpath must be set to 1) |
||
| 2923 | * @param string $moreatt Add more attribute on img tag (For example 'style="float: right"') |
||
| 2924 | * @param boolean|int $pictoisfullpath If true or 1, image path is a full path |
||
| 2925 | * @param int $srconly Return only content of the src attribute of img. |
||
| 2926 | * @param int $notitle 1=Disable tag title. Use it if you add js tooltip, to avoid duplicate tooltip. |
||
| 2927 | * @param string $alt Force alt for bind people |
||
| 2928 | * @param string $morecss Add more class css on img tag (For example 'myclascss'). Work only if $moreatt is empty. |
||
| 2929 | * @return string Return img tag |
||
| 2930 | * @see #img_object, #img_picto_common |
||
| 2931 | */ |
||
| 2932 | static function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $srconly = 0, $notitle = 0, $alt = '', $morecss = '') |
||
| 2933 | {
|
||
| 2934 | // global Globals::$conf, Globals::$langs; |
||
| 2935 | // We forge fullpathpicto for image to $path/img/$picto. By default, we take DOL_BASE_URI/theme/Globals::$conf->theme/img/$picto |
||
| 2936 | //$url = DOL_BASE_URI; |
||
| 2937 | $url = DOL_BASE_URI; |
||
| 2938 | |||
| 2939 | $theme = Globals::$conf->theme; |
||
| 2940 | $path = 'theme/' . $theme; |
||
| 2941 | |||
| 2942 | // Define fullpathpicto to use into src |
||
| 2943 | if ($pictoisfullpath) {
|
||
| 2944 | // Clean parameters |
||
| 2945 | if (!preg_match('/(\.png|\.gif|\.svg)$/i', $picto)) {
|
||
| 2946 | $picto .= '.png'; |
||
| 2947 | } |
||
| 2948 | $fullpathpicto = $picto; |
||
| 2949 | } else {
|
||
| 2950 | $pictowithoutext = preg_replace('/(\.png|\.gif|\.svg)$/', '', $picto);
|
||
| 2951 | |||
| 2952 | //if (in_array($picto, array('switch_off', 'switch_on', 'off', 'on')))
|
||
| 2953 | if (empty($srconly) && in_array($pictowithoutext, array( |
||
| 2954 | 'bank', 'close_title', 'delete', 'edit', 'ellipsis-h', 'filter', 'grip', 'grip_title', 'list', 'listlight', 'off', 'on', 'play', 'playdisabled', 'printer', 'resize', |
||
| 2955 | 'note', 'switch_off', 'switch_on', 'unlink', 'uparrow', '1downarrow', '1uparrow', |
||
| 2956 | 'jabber', 'skype', 'twitter', 'facebook' |
||
| 2957 | ) |
||
| 2958 | )) {
|
||
| 2959 | $fakey = $pictowithoutext; |
||
| 2960 | $facolor = ''; |
||
| 2961 | $fasize = ''; |
||
| 2962 | $marginleftonlyshort = 2; |
||
| 2963 | if ($pictowithoutext == 'switch_off') {
|
||
| 2964 | $fakey = 'fa-toggle-off'; |
||
| 2965 | $facolor = '#999'; |
||
| 2966 | $fasize = '2em'; |
||
| 2967 | } elseif ($pictowithoutext == 'switch_on') {
|
||
| 2968 | $fakey = 'fa-toggle-on'; |
||
| 2969 | $facolor = '#227722'; |
||
| 2970 | $fasize = '2em'; |
||
| 2971 | } elseif ($pictowithoutext == 'off') {
|
||
| 2972 | $fakey = 'fa-square-o'; |
||
| 2973 | $fasize = '1.3em'; |
||
| 2974 | } elseif ($pictowithoutext == 'on') {
|
||
| 2975 | $fakey = 'fa-check-square-o'; |
||
| 2976 | $fasize = '1.3em'; |
||
| 2977 | } elseif ($pictowithoutext == 'bank') {
|
||
| 2978 | $fakey = 'fa-bank'; |
||
| 2979 | $facolor = '#444'; |
||
| 2980 | } elseif ($pictowithoutext == 'close_title') {
|
||
| 2981 | $fakey = 'fa-window-close'; |
||
| 2982 | } elseif ($pictowithoutext == 'delete') {
|
||
| 2983 | $fakey = 'fa-trash'; |
||
| 2984 | $facolor = '#444'; |
||
| 2985 | } elseif ($pictowithoutext == 'edit') {
|
||
| 2986 | $fakey = 'fa-pencil'; |
||
| 2987 | $facolor = '#444'; |
||
| 2988 | } elseif ($pictowithoutext == 'filter') {
|
||
| 2989 | $fakey = 'fa-' . $pictowithoutext; |
||
| 2990 | } elseif ($pictowithoutext == 'grip_title' || $pictowithoutext == 'grip') {
|
||
| 2991 | $fakey = 'fa-arrows'; |
||
| 2992 | } elseif ($pictowithoutext == 'listlight') {
|
||
| 2993 | $fakey = 'fa-download'; |
||
| 2994 | $facolor = '#999'; |
||
| 2995 | $marginleftonlyshort = 1; |
||
| 2996 | } elseif ($pictowithoutext == 'printer') {
|
||
| 2997 | $fakey = 'fa-print'; |
||
| 2998 | $fasize = '1.2em'; |
||
| 2999 | $facolor = '#444'; |
||
| 3000 | } elseif ($pictowithoutext == 'resize') {
|
||
| 3001 | $fakey = 'fa-crop'; |
||
| 3002 | $facolor = '#444'; |
||
| 3003 | } elseif ($pictowithoutext == 'note') {
|
||
| 3004 | $fakey = 'fa-sticky-note-o'; |
||
| 3005 | $facolor = '#999'; |
||
| 3006 | $marginleftonlyshort = 1; |
||
| 3007 | } elseif ($pictowithoutext == 'uparrow') {
|
||
| 3008 | $fakey = 'fa-mail-forward'; |
||
| 3009 | $facolor = '#555'; |
||
| 3010 | } elseif ($pictowithoutext == '1uparrow') {
|
||
| 3011 | $fakey = 'fa-caret-up'; |
||
| 3012 | $marginleftonlyshort = 1; |
||
| 3013 | } elseif ($pictowithoutext == '1downarrow') {
|
||
| 3014 | $fakey = 'fa-caret-down'; |
||
| 3015 | $marginleftonlyshort = 1; |
||
| 3016 | } elseif ($pictowithoutext == 'unlink') {
|
||
| 3017 | $fakey = 'fa-chain-broken'; |
||
| 3018 | $facolor = '#555'; |
||
| 3019 | } elseif ($pictowithoutext == 'playdisabled') {
|
||
| 3020 | $fakey = 'fa-play'; |
||
| 3021 | $facolor = '#ccc'; |
||
| 3022 | } elseif ($pictowithoutext == 'play') {
|
||
| 3023 | $fakey = 'fa-play'; |
||
| 3024 | $facolor = '#444'; |
||
| 3025 | } elseif ($pictowithoutext == 'jabber') {
|
||
| 3026 | $fakey = 'fa-comment-o'; |
||
| 3027 | } else {
|
||
| 3028 | $fakey = 'fa-' . $pictowithoutext; |
||
| 3029 | $facolor = '#444'; |
||
| 3030 | $marginleftonlyshort = 0; |
||
| 3031 | } |
||
| 3032 | |||
| 3033 | if (preg_match('/class="([^"]+)"/', $moreatt, $reg)) {
|
||
| 3034 | $morecss .= ($morecss ? ' ' : '') . $reg[1]; |
||
| 3035 | } |
||
| 3036 | $enabledisablehtml = '<span class="fa ' . $fakey . ' ' . ($marginleftonlyshort ? ($marginleftonlyshort == 1 ? 'marginleftonlyshort' : 'marginleftonly') : '') . ' valignmiddle' . ($morecss ? ' ' . $morecss : '') . '" style="' . ($fasize ? ('font-size: ' . $fasize . ';') : '') . ($facolor ? (' color: ' . $facolor . ';') : '') . '" alt="' . AlDolUtils::dol_escape_htmltag($titlealt) . '"' . (($notitle || empty($title)) ? '' : ' title="' . AlDolUtils::dol_escape_htmltag($title) . '"') . ($moreatt ? ' ' . $moreatt : '') . '>';
|
||
| 3037 | if (!empty(Globals::$conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
|
||
| 3038 | $enabledisablehtml .= $titlealt; |
||
| 3039 | } |
||
| 3040 | $enabledisablehtml .= '</span>'; |
||
| 3041 | |||
| 3042 | return $enabledisablehtml; |
||
| 3043 | } |
||
| 3044 | |||
| 3045 | if (!empty(Globals::$conf->global->MAIN_OVERWRITE_THEME_PATH)) {
|
||
| 3046 | $path = Globals::$conf->global->MAIN_OVERWRITE_THEME_PATH . '/theme/' . $theme; // If the theme does not have the same name as the module |
||
| 3047 | } else if (!empty(Globals::$conf->global->MAIN_OVERWRITE_THEME_RES)) {
|
||
| 3048 | $path = Globals::$conf->global->MAIN_OVERWRITE_THEME_RES . '/theme/' . Globals::$conf->global->MAIN_OVERWRITE_THEME_RES; // To allow an external module to overwrite image resources whatever is activated theme |
||
| 3049 | } else if (!empty(Globals::$conf->modules_parts['theme']) && array_key_exists($theme, Globals::$conf->modules_parts['theme'])) {
|
||
| 3050 | $path = $theme . '/theme/' . $theme; // If the theme have the same name as the module |
||
| 3051 | } |
||
| 3052 | |||
| 3053 | // If we ask an image into $url/$mymodule/img (instead of default path) |
||
| 3054 | if (preg_match('/^([^@]+)@([^@]+)$/i', $picto, $regs)) {
|
||
| 3055 | $picto = $regs[1]; |
||
| 3056 | $path = $regs[2]; // $path is $mymodule |
||
| 3057 | } |
||
| 3058 | |||
| 3059 | // Clean parameters |
||
| 3060 | if (!preg_match('/(\.png|\.gif|\.svg)$/i', $picto)) {
|
||
| 3061 | $picto .= '.png'; |
||
| 3062 | } |
||
| 3063 | // If alt path are defined, define url where img file is, according to physical path |
||
| 3064 | // ex: array(["main"]=>"/home/maindir/htdocs", ["alt0"]=>"/home/moddir0/htdocs", ...) |
||
| 3065 | foreach (Globals::$conf->file->dol_document_root as $type => $dirroot) {
|
||
| 3066 | if ($type == 'main') {
|
||
| 3067 | continue; |
||
| 3068 | } |
||
| 3069 | // This need a lot of time, that's why enabling alternative dir like "custom" dir is not recommanded |
||
| 3070 | if (file_exists($dirroot . '/' . $path . '/img/' . $picto)) {
|
||
| 3071 | //$url = DOL_BASE_URI . Globals::$conf->file->dol_url_root[$type]; |
||
| 3072 | $url = DOL_BASE_URI . Globals::$conf->file->dol_url_root[$type]; |
||
| 3073 | break; |
||
| 3074 | } |
||
| 3075 | } |
||
| 3076 | |||
| 3077 | // $url is '' or '/custom', $path is current theme or |
||
| 3078 | $fullpathpicto = $url . '/' . $path . '/img/' . $picto; |
||
| 3079 | } |
||
| 3080 | |||
| 3081 | if ($srconly) {
|
||
| 3082 | return $fullpathpicto; |
||
| 3083 | } |
||
| 3084 | |||
| 3085 | // tag title is used for tooltip on <a>, tag alt can be used with very simple text on image for bind people |
||
| 3086 | return '<img src="' . $fullpathpicto . '" alt="' . AlDolUtils::dol_escape_htmltag($alt) . '"' . (($notitle || empty($titlealt)) ? '' : ' title="' . AlDolUtils::dol_escape_htmltag($titlealt) . '"') . ($moreatt ? ' ' . $moreatt : ' class="inline-block' . ($morecss ? ' ' . $morecss : '') . '"') . '>'; // Alt is used for accessibility, title for popup |
||
| 3087 | } |
||
| 3088 | |||
| 3089 | /** |
||
| 3090 | * Show a picto called object_picto (generic function) |
||
| 3091 | * |
||
| 3092 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3093 | * @param string $picto Name of image to show object_picto (example: user, group, action, bill, contract, propal, product, ...) |
||
| 3094 | * For external modules use imagename@mymodule to search into directory "img" of module. |
||
| 3095 | * @param string $moreatt Add more attribute on img tag (ie: class="datecallink") |
||
| 3096 | * @param int $pictoisfullpath If 1, image path is a full path |
||
| 3097 | * @param int $srconly Return only content of the src attribute of img. |
||
| 3098 | * @param int $notitle 1=Disable tag title. Use it if you add js tooltip, to avoid duplicate tooltip. |
||
| 3099 | * @return string Return img tag |
||
| 3100 | * @see #img_picto, #img_picto_common |
||
| 3101 | */ |
||
| 3102 | static function img_object($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $srconly = 0, $notitle = 0) |
||
| 3103 | {
|
||
| 3104 | return img_picto($titlealt, 'object_' . $picto, $moreatt, $pictoisfullpath, $srconly, $notitle); |
||
| 3105 | } |
||
| 3106 | |||
| 3107 | /** |
||
| 3108 | * Show weather picto |
||
| 3109 | * |
||
| 3110 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3111 | * @param string $picto Name of image file to show (If no extension provided, we use '.png'). Image must be stored into htdocs/theme/common directory. |
||
| 3112 | * @param string $moreatt Add more attribute on img tag |
||
| 3113 | * @param int $pictoisfullpath If 1, image path is a full path |
||
| 3114 | * @return string Return img tag |
||
| 3115 | * @see #img_object, #img_picto |
||
| 3116 | */ |
||
| 3117 | static function img_weather($titlealt, $picto, $moreatt = '', $pictoisfullpath = 0) |
||
| 3118 | {
|
||
| 3119 | // global Globals::$conf; |
||
| 3120 | |||
| 3121 | if (!preg_match('/(\.png|\.gif)$/i', $picto))
|
||
| 3122 | $picto .= '.png'; |
||
| 3123 | |||
| 3124 | //$path = DOL_BASE_URI . '/theme/' . Globals::$conf->theme . '/img/weather/' . $picto; |
||
| 3125 | $path = DOL_BASE_URI . '/theme/' . Globals::$conf->theme . '/img/weather/' . $picto; |
||
| 3126 | |||
| 3127 | return img_picto($titlealt, $path, $moreatt, 1); |
||
| 3128 | } |
||
| 3129 | |||
| 3130 | /** |
||
| 3131 | * Show picto (generic function) |
||
| 3132 | * |
||
| 3133 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3134 | * @param string $picto Name of image file to show (If no extension provided, we use '.png'). Image must be stored into htdocs/theme/common directory. |
||
| 3135 | * @param string $moreatt Add more attribute on img tag |
||
| 3136 | * @param int $pictoisfullpath If 1, image path is a full path |
||
| 3137 | * @return string Return img tag |
||
| 3138 | * @see #img_object, #img_picto |
||
| 3139 | */ |
||
| 3140 | static function img_picto_common($titlealt, $picto, $moreatt = '', $pictoisfullpath = 0) |
||
| 3141 | {
|
||
| 3142 | // global Globals::$conf; |
||
| 3143 | |||
| 3144 | if (!preg_match('/(\.png|\.gif)$/i', $picto)) {
|
||
| 3145 | $picto .= '.png'; |
||
| 3146 | } |
||
| 3147 | |||
| 3148 | if ($pictoisfullpath) {
|
||
| 3149 | $path = $picto; |
||
| 3150 | } else {
|
||
| 3151 | //$path = DOL_BASE_URI . '/theme/common/' . $picto; |
||
| 3152 | $path = DOL_BASE_URI . '/theme/common/' . $picto; |
||
| 3153 | |||
| 3154 | if (!empty(Globals::$conf->global->MAIN_MODULE_CAN_OVERWRITE_COMMONICONS)) {
|
||
| 3155 | $themepath = DOL_BASE_PATH . 'theme/' . Globals::$conf->theme . '/img/' . $picto; |
||
| 3156 | |||
| 3157 | if (file_exists($themepath)) {
|
||
| 3158 | $path = $themepath; |
||
| 3159 | } |
||
| 3160 | } |
||
| 3161 | } |
||
| 3162 | |||
| 3163 | return self::img_picto($titlealt, $path, $moreatt, 1); |
||
| 3164 | } |
||
| 3165 | |||
| 3166 | /** |
||
| 3167 | * Show logo action |
||
| 3168 | * |
||
| 3169 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3170 | * @param string $numaction Action id or code to show |
||
| 3171 | * @return string Return an img tag |
||
| 3172 | */ |
||
| 3173 | static function img_action($titlealt, $numaction) |
||
| 3174 | {
|
||
| 3175 | // global Globals::$conf, Globals::$langs; |
||
| 3176 | |||
| 3177 | if (empty($titlealt) || $titlealt == 'default') {
|
||
| 3178 | if ($numaction == '-1' || $numaction == 'ST_NO') {
|
||
| 3179 | $numaction = -1; |
||
| 3180 | $titlealt = Globals::$langs->transnoentitiesnoconv('ChangeDoNotContact');
|
||
| 3181 | } elseif ($numaction == '0' || $numaction == 'ST_NEVER') {
|
||
| 3182 | $numaction = 0; |
||
| 3183 | $titlealt = Globals::$langs->transnoentitiesnoconv('ChangeNeverContacted');
|
||
| 3184 | } elseif ($numaction == '1' || $numaction == 'ST_TODO') {
|
||
| 3185 | $numaction = 1; |
||
| 3186 | $titlealt = Globals::$langs->transnoentitiesnoconv('ChangeToContact');
|
||
| 3187 | } elseif ($numaction == '2' || $numaction == 'ST_PEND') {
|
||
| 3188 | $numaction = 2; |
||
| 3189 | $titlealt = Globals::$langs->transnoentitiesnoconv('ChangeContactInProcess');
|
||
| 3190 | } elseif ($numaction == '3' || $numaction == 'ST_DONE') {
|
||
| 3191 | $numaction = 3; |
||
| 3192 | $titlealt = Globals::$langs->transnoentitiesnoconv('ChangeContactDone');
|
||
| 3193 | } else {
|
||
| 3194 | $titlealt = Globals::$langs->transnoentitiesnoconv('ChangeStatus ' . $numaction);
|
||
| 3195 | $numaction = 0; |
||
| 3196 | } |
||
| 3197 | } |
||
| 3198 | if (!is_numeric($numaction)) |
||
| 3199 | $numaction = 0; |
||
| 3200 | |||
| 3201 | return img_picto($titlealt, 'stcomm' . $numaction . '.png'); |
||
| 3202 | } |
||
| 3203 | |||
| 3204 | /** |
||
| 3205 | * Show pdf logo |
||
| 3206 | * |
||
| 3207 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3208 | * @param int $size Taille de l'icone : 3 = 16x16px , 2 = 14x14px |
||
| 3209 | * @return string Retourne tag img |
||
| 3210 | */ |
||
| 3211 | static function img_pdf($titlealt = 'default', $size = 3) |
||
| 3212 | {
|
||
| 3213 | // global Globals::$conf, Globals::$langs; |
||
| 3214 | |||
| 3215 | if ($titlealt == 'default') |
||
| 3216 | $titlealt = Globals::$langs->trans('Show');
|
||
| 3217 | |||
| 3218 | return img_picto($titlealt, 'pdf' . $size . '.png'); |
||
| 3219 | } |
||
| 3220 | |||
| 3221 | /** |
||
| 3222 | * Show logo + |
||
| 3223 | * |
||
| 3224 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3225 | * @param string $other Add more attributes on img |
||
| 3226 | * @return string Return tag img |
||
| 3227 | */ |
||
| 3228 | static function img_edit_add($titlealt = 'default', $other = '') |
||
| 3229 | {
|
||
| 3230 | // global Globals::$conf, Globals::$langs; |
||
| 3231 | |||
| 3232 | if ($titlealt == 'default') |
||
| 3233 | $titlealt = Globals::$langs->trans('Add');
|
||
| 3234 | |||
| 3235 | return img_picto($titlealt, 'edit_add.png', $other); |
||
| 3236 | } |
||
| 3237 | |||
| 3238 | /** |
||
| 3239 | * Show logo - |
||
| 3240 | * |
||
| 3241 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3242 | * @param string $other Add more attributes on img |
||
| 3243 | * @return string Return tag img |
||
| 3244 | */ |
||
| 3245 | static function img_edit_remove($titlealt = 'default', $other = '') |
||
| 3246 | {
|
||
| 3247 | // global Globals::$conf, Globals::$langs; |
||
| 3248 | |||
| 3249 | if ($titlealt == 'default') |
||
| 3250 | $titlealt = Globals::$langs->trans('Remove');
|
||
| 3251 | |||
| 3252 | return img_picto($titlealt, 'edit_remove.png', $other); |
||
| 3253 | } |
||
| 3254 | |||
| 3255 | /** |
||
| 3256 | * Show logo editer/modifier fiche |
||
| 3257 | * |
||
| 3258 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3259 | * @param integer $float Si il faut y mettre le style "float: right" |
||
| 3260 | * @param string $other Add more attributes on img |
||
| 3261 | * @return string Return tag img |
||
| 3262 | */ |
||
| 3263 | static function img_edit($titlealt = 'default', $float = 0, $other = 'class="pictoedit"') |
||
| 3264 | {
|
||
| 3265 | // global Globals::$conf, Globals::$langs; |
||
| 3266 | |||
| 3267 | if ($titlealt == 'default') |
||
| 3268 | $titlealt = Globals::$langs->trans('Modify');
|
||
| 3269 | |||
| 3270 | return img_picto($titlealt, 'edit.png', ($float ? 'style="float: ' . (Globals::$langs->tab_translate["DIRECTION"] == 'rtl' ? 'left' : 'right') . '"' : "") . ($other ? ' ' . $other : '')); |
||
| 3271 | } |
||
| 3272 | |||
| 3273 | /** |
||
| 3274 | * Show logo view card |
||
| 3275 | * |
||
| 3276 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3277 | * @param integer $float Si il faut y mettre le style "float: right" |
||
| 3278 | * @param string $other Add more attributes on img |
||
| 3279 | * @return string Return tag img |
||
| 3280 | */ |
||
| 3281 | static function img_view($titlealt = 'default', $float = 0, $other = '') |
||
| 3282 | {
|
||
| 3283 | // global Globals::$conf, Globals::$langs; |
||
| 3284 | |||
| 3285 | if ($titlealt == 'default') |
||
| 3286 | $titlealt = Globals::$langs->trans('View');
|
||
| 3287 | |||
| 3288 | $moreatt = ($float ? 'style="float: right" ' : '') . $other; |
||
| 3289 | |||
| 3290 | return img_picto($titlealt, 'view.png', $moreatt); |
||
| 3291 | } |
||
| 3292 | |||
| 3293 | /** |
||
| 3294 | * Show delete logo |
||
| 3295 | * |
||
| 3296 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3297 | * @param string $other Add more attributes on img |
||
| 3298 | * @return string Retourne tag img |
||
| 3299 | */ |
||
| 3300 | static function img_delete($titlealt = 'default', $other = 'class="pictodelete"') |
||
| 3301 | {
|
||
| 3302 | // global Globals::$conf, Globals::$langs; |
||
| 3303 | |||
| 3304 | if ($titlealt == 'default') |
||
| 3305 | $titlealt = Globals::$langs->trans('Delete');
|
||
| 3306 | |||
| 3307 | return img_picto($titlealt, 'delete.png', $other); |
||
| 3308 | //return '<span class="fa fa-trash fa-2x fa-fw" style="font-size: 1.7em;" title="'.$titlealt.'"></span>'; |
||
| 3309 | } |
||
| 3310 | |||
| 3311 | /** |
||
| 3312 | * Show printer logo |
||
| 3313 | * |
||
| 3314 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3315 | * @param string $other Add more attributes on img |
||
| 3316 | * @return string Retourne tag img |
||
| 3317 | */ |
||
| 3318 | static function img_printer($titlealt = "default", $other = '') |
||
| 3319 | {
|
||
| 3320 | // global Globals::$conf, Globals::$langs; |
||
| 3321 | if ($titlealt == "default") |
||
| 3322 | $titlealt = Globals::$langs->trans("Print");
|
||
| 3323 | return img_picto($titlealt, 'printer.png', $other); |
||
| 3324 | } |
||
| 3325 | |||
| 3326 | /** |
||
| 3327 | * Show split logo |
||
| 3328 | * |
||
| 3329 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3330 | * @param string $other Add more attributes on img |
||
| 3331 | * @return string Retourne tag img |
||
| 3332 | */ |
||
| 3333 | static function img_split($titlealt = 'default', $other = 'class="pictosplit"') |
||
| 3334 | {
|
||
| 3335 | // global Globals::$conf, Globals::$langs; |
||
| 3336 | |||
| 3337 | if ($titlealt == 'default') |
||
| 3338 | $titlealt = Globals::$langs->trans('Split');
|
||
| 3339 | |||
| 3340 | return img_picto($titlealt, 'split.png', $other); |
||
| 3341 | } |
||
| 3342 | |||
| 3343 | /** |
||
| 3344 | * Show help logo with cursor "?" |
||
| 3345 | * |
||
| 3346 | * @param int $usehelpcursor 1=Use help cursor, 2=Use click pointer cursor, 0=No specific cursor |
||
| 3347 | * @param int|string $usealttitle Text to use as alt title |
||
| 3348 | * @return string Return tag img |
||
| 3349 | */ |
||
| 3350 | static function img_help($usehelpcursor = 1, $usealttitle = 1) |
||
| 3351 | {
|
||
| 3352 | // global Globals::$conf, Globals::$langs; |
||
| 3353 | |||
| 3354 | if ($usealttitle) {
|
||
| 3355 | if (is_string($usealttitle)) |
||
| 3356 | $usealttitle = AlDolUtils::dol_escape_htmltag($usealttitle); |
||
| 3357 | else |
||
| 3358 | $usealttitle = Globals::$langs->trans('Info');
|
||
| 3359 | } |
||
| 3360 | |||
| 3361 | return img_picto($usealttitle, 'info.png', 'style="vertical-align: middle;' . ($usehelpcursor == 1 ? ' cursor: help' : ($usehelpcursor == 2 ? ' cursor: pointer' : '')) . '"'); |
||
| 3362 | } |
||
| 3363 | |||
| 3364 | /** |
||
| 3365 | * Show info logo |
||
| 3366 | * |
||
| 3367 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3368 | * @return string Return img tag |
||
| 3369 | */ |
||
| 3370 | static function img_info($titlealt = 'default') |
||
| 3371 | {
|
||
| 3372 | // global Globals::$conf, Globals::$langs; |
||
| 3373 | |||
| 3374 | if ($titlealt == 'default') |
||
| 3375 | $titlealt = Globals::$langs->trans('Informations');
|
||
| 3376 | |||
| 3377 | return img_picto($titlealt, 'info.png', 'style="vertical-align: middle;"'); |
||
| 3378 | } |
||
| 3379 | |||
| 3380 | /** |
||
| 3381 | * Show warning logo |
||
| 3382 | * |
||
| 3383 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3384 | * @param string $moreatt Add more attribute on img tag (For example 'style="float: right"'). If 1, add float: right. Can't be "class" attribute. |
||
| 3385 | * @return string Return img tag |
||
| 3386 | */ |
||
| 3387 | static function img_warning($titlealt = 'default', $moreatt = '') |
||
| 3388 | {
|
||
| 3389 | // global Globals::$conf, Globals::$langs; |
||
| 3390 | |||
| 3391 | if ($titlealt == 'default') |
||
| 3392 | $titlealt = Globals::$langs->trans('Warning');
|
||
| 3393 | |||
| 3394 | //return '<div class="imglatecoin">'.img_picto($titlealt, 'warning_white.png', 'class="pictowarning valignmiddle"'.($moreatt ? ($moreatt == '1' ? ' style="float: right"' : ' '.$moreatt): '')).'</div>'; |
||
| 3395 | return img_picto($titlealt, 'warning.png', 'class="pictowarning valignmiddle"' . ($moreatt ? ($moreatt == '1' ? ' style="float: right"' : ' ' . $moreatt) : '')); |
||
| 3396 | } |
||
| 3397 | |||
| 3398 | /** |
||
| 3399 | * Show error logo |
||
| 3400 | * |
||
| 3401 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3402 | * @return string Return img tag |
||
| 3403 | */ |
||
| 3404 | static function img_error($titlealt = 'default') |
||
| 3405 | {
|
||
| 3406 | // global Globals::$conf, Globals::$langs; |
||
| 3407 | |||
| 3408 | if ($titlealt == 'default') |
||
| 3409 | $titlealt = Globals::$langs->trans('Error');
|
||
| 3410 | |||
| 3411 | return img_picto($titlealt, 'error.png', 'class="valigntextbottom"'); |
||
| 3412 | } |
||
| 3413 | |||
| 3414 | /** |
||
| 3415 | * Show next logo |
||
| 3416 | * |
||
| 3417 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3418 | * @param string $moreatt Add more attribute on img tag (For example 'style="float: right"') |
||
| 3419 | * @return string Return img tag |
||
| 3420 | */ |
||
| 3421 | static function img_next($titlealt = 'default', $moreatt = '') |
||
| 3422 | {
|
||
| 3423 | // global Globals::$conf, Globals::$langs; |
||
| 3424 | |||
| 3425 | if ($titlealt == 'default') |
||
| 3426 | $titlealt = Globals::$langs->trans('Next');
|
||
| 3427 | |||
| 3428 | //return img_picto($titlealt, 'next.png', $moreatt); |
||
| 3429 | return '<span class="fa fa-chevron-right paddingright paddingleft" title="' . AlDolUtils::dol_escape_htmltag($titlealt) . '"></span>'; |
||
| 3430 | } |
||
| 3431 | |||
| 3432 | /** |
||
| 3433 | * Show previous logo |
||
| 3434 | * |
||
| 3435 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3436 | * @param string $moreatt Add more attribute on img tag (For example 'style="float: right"') |
||
| 3437 | * @return string Return img tag |
||
| 3438 | */ |
||
| 3439 | static function img_previous($titlealt = 'default', $moreatt = '') |
||
| 3440 | {
|
||
| 3441 | // global Globals::$conf, Globals::$langs; |
||
| 3442 | |||
| 3443 | if ($titlealt == 'default') |
||
| 3444 | $titlealt = Globals::$langs->trans('Previous');
|
||
| 3445 | |||
| 3446 | //return img_picto($titlealt, 'previous.png', $moreatt); |
||
| 3447 | return '<span class="fa fa-chevron-left paddingright paddingleft" title="' . AlDolUtils::dol_escape_htmltag($titlealt) . '"></span>'; |
||
| 3448 | } |
||
| 3449 | |||
| 3450 | /** |
||
| 3451 | * Show down arrow logo |
||
| 3452 | * |
||
| 3453 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3454 | * @param int $selected Selected |
||
| 3455 | * @param string $moreclass Add more CSS classes |
||
| 3456 | * @return string Return img tag |
||
| 3457 | */ |
||
| 3458 | static function img_down($titlealt = 'default', $selected = 0, $moreclass = '') |
||
| 3459 | {
|
||
| 3460 | // global Globals::$conf, Globals::$langs; |
||
| 3461 | |||
| 3462 | if ($titlealt == 'default') |
||
| 3463 | $titlealt = Globals::$langs->trans('Down');
|
||
| 3464 | |||
| 3465 | return img_picto($titlealt, ($selected ? '1downarrow_selected.png' : '1downarrow.png'), 'class="imgdown' . ($moreclass ? " " . $moreclass : "") . '"'); |
||
| 3466 | } |
||
| 3467 | |||
| 3468 | /** |
||
| 3469 | * Show top arrow logo |
||
| 3470 | * |
||
| 3471 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3472 | * @param int $selected Selected |
||
| 3473 | * @param string $moreclass Add more CSS classes |
||
| 3474 | * @return string Return img tag |
||
| 3475 | */ |
||
| 3476 | static function img_up($titlealt = 'default', $selected = 0, $moreclass = '') |
||
| 3477 | {
|
||
| 3478 | // global Globals::$conf, Globals::$langs; |
||
| 3479 | |||
| 3480 | if ($titlealt == 'default') |
||
| 3481 | $titlealt = Globals::$langs->trans('Up');
|
||
| 3482 | |||
| 3483 | return img_picto($titlealt, ($selected ? '1uparrow_selected.png' : '1uparrow.png'), 'class="imgup' . ($moreclass ? " " . $moreclass : "") . '"'); |
||
| 3484 | } |
||
| 3485 | |||
| 3486 | /** |
||
| 3487 | * Show left arrow logo |
||
| 3488 | * |
||
| 3489 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3490 | * @param int $selected Selected |
||
| 3491 | * @param string $moreatt Add more attribute on img tag (For example 'style="float: right"') |
||
| 3492 | * @return string Return img tag |
||
| 3493 | */ |
||
| 3494 | static function img_left($titlealt = 'default', $selected = 0, $moreatt = '') |
||
| 3495 | {
|
||
| 3496 | // global Globals::$conf, Globals::$langs; |
||
| 3497 | |||
| 3498 | if ($titlealt == 'default') |
||
| 3499 | $titlealt = Globals::$langs->trans('Left');
|
||
| 3500 | |||
| 3501 | return img_picto($titlealt, ($selected ? '1leftarrow_selected.png' : '1leftarrow.png'), $moreatt); |
||
| 3502 | } |
||
| 3503 | |||
| 3504 | /** |
||
| 3505 | * Show right arrow logo |
||
| 3506 | * |
||
| 3507 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3508 | * @param int $selected Selected |
||
| 3509 | * @param string $moreatt Add more attribute on img tag (For example 'style="float: right"') |
||
| 3510 | * @return string Return img tag |
||
| 3511 | */ |
||
| 3512 | static function img_right($titlealt = 'default', $selected = 0, $moreatt = '') |
||
| 3513 | {
|
||
| 3514 | // global Globals::$conf, Globals::$langs; |
||
| 3515 | |||
| 3516 | if ($titlealt == 'default') |
||
| 3517 | $titlealt = Globals::$langs->trans('Right');
|
||
| 3518 | |||
| 3519 | return img_picto($titlealt, ($selected ? '1rightarrow_selected.png' : '1rightarrow.png'), $moreatt); |
||
| 3520 | } |
||
| 3521 | |||
| 3522 | /** |
||
| 3523 | * Show tick logo if allowed |
||
| 3524 | * |
||
| 3525 | * @param string $allow Allow |
||
| 3526 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3527 | * @return string Return img tag |
||
| 3528 | */ |
||
| 3529 | static function img_allow($allow, $titlealt = 'default') |
||
| 3530 | {
|
||
| 3531 | // global Globals::$conf, Globals::$langs; |
||
| 3532 | |||
| 3533 | if ($titlealt == 'default') |
||
| 3534 | $titlealt = Globals::$langs->trans('Active');
|
||
| 3535 | |||
| 3536 | if ($allow == 1) |
||
| 3537 | return img_picto($titlealt, 'tick.png'); |
||
| 3538 | |||
| 3539 | return '-'; |
||
| 3540 | } |
||
| 3541 | |||
| 3542 | /** |
||
| 3543 | * Return image of a credit card according to its brand name |
||
| 3544 | * |
||
| 3545 | * @param string $brand Brand name of credit card |
||
| 3546 | * @return string Return img tag |
||
| 3547 | */ |
||
| 3548 | static function img_credit_card($brand) |
||
| 3549 | {
|
||
| 3550 | if ($brand == 'Visa') {
|
||
| 3551 | $brand = 'cc-visa'; |
||
| 3552 | } elseif ($brand == 'MasterCard') {
|
||
| 3553 | $brand = 'cc-mastercard'; |
||
| 3554 | } elseif ($brand == 'American Express') {
|
||
| 3555 | $brand = 'cc-amex'; |
||
| 3556 | } elseif ($brand == 'Discover') {
|
||
| 3557 | $brand = 'cc-discover'; |
||
| 3558 | } elseif ($brand == 'JCB') {
|
||
| 3559 | $brand = 'cc-jcb'; |
||
| 3560 | } elseif ($brand == 'Diners Club') {
|
||
| 3561 | $brand = 'cc-diners-club'; |
||
| 3562 | } elseif (!in_array($brand, array('cc-visa', 'cc-mastercard', 'cc-amex', 'cc-discover', 'cc-jcb', 'cc-diners-club'))) {
|
||
| 3563 | $brand = 'credit-card'; |
||
| 3564 | } |
||
| 3565 | |||
| 3566 | return '<span class="fa fa-' . $brand . ' fa-2x fa-fw"></span>'; |
||
| 3567 | } |
||
| 3568 | |||
| 3569 | /** |
||
| 3570 | * Show MIME img of a file |
||
| 3571 | * |
||
| 3572 | * @param string $file Filename |
||
| 3573 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3574 | * @param string $morecss More css |
||
| 3575 | * @return string Return img tag |
||
| 3576 | */ |
||
| 3577 | static function img_mime($file, $titlealt = '', $morecss = '') |
||
| 3578 | {
|
||
| 3579 | require_once DOL_BASE_PATH . '/core/lib/files.lib.php'; |
||
| 3580 | |||
| 3581 | $mimetype = dol_mimetype($file, '', 1); |
||
| 3582 | $mimeimg = dol_mimetype($file, '', 2); |
||
| 3583 | $mimefa = dol_mimetype($file, '', 4); |
||
| 3584 | |||
| 3585 | if (empty($titlealt)) |
||
| 3586 | $titlealt = 'Mime type: ' . $mimetype; |
||
| 3587 | |||
| 3588 | //return img_picto_common($titlealt, 'mime/'.$mimeimg, 'class="'.$morecss.'"'); |
||
| 3589 | return '<i class="fa fa-' . $mimefa . ' paddingright"></i>'; |
||
| 3590 | } |
||
| 3591 | |||
| 3592 | /** |
||
| 3593 | * Show phone logo. |
||
| 3594 | * Use img_picto instead. |
||
| 3595 | * |
||
| 3596 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3597 | * @param int $option Option |
||
| 3598 | * @return string Return img tag |
||
| 3599 | * @deprecated |
||
| 3600 | * @see img_picto |
||
| 3601 | */ |
||
| 3602 | static function img_phone($titlealt = 'default', $option = 0) |
||
| 3603 | {
|
||
| 3604 | AlDolUtils::dol_syslog(__FUNCTION__ . " is deprecated", LOG_WARNING); |
||
| 3605 | |||
| 3606 | // global Globals::$conf, Globals::$langs; |
||
| 3607 | |||
| 3608 | if ($titlealt == 'default') |
||
| 3609 | $titlealt = Globals::$langs->trans('Call');
|
||
| 3610 | |||
| 3611 | if ($option == 1) |
||
| 3612 | $img = 'call'; |
||
| 3613 | else |
||
| 3614 | $img = 'call_out'; |
||
| 3615 | |||
| 3616 | return img_picto($titlealt, $img); |
||
| 3617 | } |
||
| 3618 | |||
| 3619 | /** |
||
| 3620 | * Show search logo |
||
| 3621 | * |
||
| 3622 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3623 | * @param string $other Add more attributes on img |
||
| 3624 | * @return string Retourne tag img |
||
| 3625 | */ |
||
| 3626 | static function img_search($titlealt = 'default', $other = '') |
||
| 3627 | {
|
||
| 3628 | // global Globals::$conf, Globals::$langs; |
||
| 3629 | |||
| 3630 | if ($titlealt == 'default') |
||
| 3631 | $titlealt = Globals::$langs->trans('Search');
|
||
| 3632 | |||
| 3633 | $img = img_picto($titlealt, 'search.png', $other, false, 1); |
||
| 3634 | |||
| 3635 | $input = '<input type="image" class="liste_titre" name="button_search" src="' . $img . '" '; |
||
| 3636 | $input .= 'value="' . AlDolUtils::dol_escape_htmltag($titlealt) . '" title="' . AlDolUtils::dol_escape_htmltag($titlealt) . '" >'; |
||
| 3637 | |||
| 3638 | return $input; |
||
| 3639 | } |
||
| 3640 | |||
| 3641 | /** |
||
| 3642 | * Show search logo |
||
| 3643 | * |
||
| 3644 | * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. |
||
| 3645 | * @param string $other Add more attributes on img |
||
| 3646 | * @return string Retourne tag img |
||
| 3647 | */ |
||
| 3648 | static function img_searchclear($titlealt = 'default', $other = '') |
||
| 3649 | {
|
||
| 3650 | // global Globals::$conf, Globals::$langs; |
||
| 3651 | |||
| 3652 | if ($titlealt == 'default') |
||
| 3653 | $titlealt = Globals::$langs->trans('Search');
|
||
| 3654 | |||
| 3655 | $img = img_picto($titlealt, 'searchclear.png', $other, false, 1); |
||
| 3656 | |||
| 3657 | $input = '<input type="image" class="liste_titre" name="button_removefilter" src="' . $img . '" '; |
||
| 3658 | $input .= 'value="' . AlDolUtils::dol_escape_htmltag($titlealt) . '" title="' . AlDolUtils::dol_escape_htmltag($titlealt) . '" >'; |
||
| 3659 | |||
| 3660 | return $input; |
||
| 3661 | } |
||
| 3662 | |||
| 3663 | /** |
||
| 3664 | * Show information for admin users or standard users |
||
| 3665 | * |
||
| 3666 | * @param string $text Text info |
||
| 3667 | * @param integer $infoonimgalt Info is shown only on alt of star picto, otherwise it is show on output after the star picto |
||
| 3668 | * @param int $nodiv No div |
||
| 3669 | * @param string $admin '1'=Info for admin users. '0'=Info for standard users (change only the look), 'xxx'=Other |
||
| 3670 | * @param string $morecss More CSS |
||
| 3671 | * @return string String with info text |
||
| 3672 | */ |
||
| 3673 | static function info_admin($text, $infoonimgalt = 0, $nodiv = 0, $admin = '1', $morecss = '') |
||
| 3674 | {
|
||
| 3675 | // global Globals::$conf, Globals::$langs; |
||
| 3676 | |||
| 3677 | if ($infoonimgalt) {
|
||
| 3678 | return img_picto($text, 'info', 'class="hideonsmartphone' . ($morecss ? ' ' . $morecss : '') . '"'); |
||
| 3679 | } |
||
| 3680 | |||
| 3681 | return ($nodiv ? '' : '<div class="' . (empty($admin) ? '' : ($admin == '1' ? 'info' : $admin)) . ' hideonsmartphone' . ($morecss ? ' ' . $morecss : '') . '">') . '<span class="fa fa-info-circle" title="' . AlDolUtils::dol_escape_htmltag($admin ? Globals::$langs->trans('InfoAdmin') : Globals::$langs->trans('Note')) . '"></span> ' . $text . ($nodiv ? '' : '</div>');
|
||
| 3682 | } |
||
| 3683 | |||
| 3684 | /** |
||
| 3685 | * Affiche message erreur system avec toutes les informations pour faciliter le diagnostic et la remontee des bugs. |
||
| 3686 | * On doit appeler cette fonction quand une erreur technique bloquante est rencontree. |
||
| 3687 | * Toutefois, il faut essayer de ne l'appeler qu'au sein de pages php, les classes devant |
||
| 3688 | * renvoyer leur erreur par l'intermediaire de leur propriete "error". |
||
| 3689 | * |
||
| 3690 | * @param DoliDB $db Database handler |
||
| 3691 | * @param mixed $error String or array of errors strings to show |
||
| 3692 | * @param array $errors Array of errors |
||
| 3693 | * @return void |
||
| 3694 | * @see dol_htmloutput_errors |
||
| 3695 | */ |
||
| 3696 | static function dol_print_error($dbError = '', $error = '', $errors = null) |
||
| 3697 | {
|
||
| 3698 | // global Globals::$conf, Globals::$langs, $argv; |
||
| 3699 | // global $dolibarr_main_prod; |
||
| 3700 | |||
| 3701 | $out = ''; |
||
| 3702 | $syslog = ''; |
||
| 3703 | |||
| 3704 | // Si erreur intervenue avant chargement langue |
||
| 3705 | if (!Globals::$langs) {
|
||
| 3706 | //require_once DOL_BASE_PATH . '/core/class/translate.class.php'; |
||
| 3707 | Globals::$langs = new Translate('', Globals::$conf);
|
||
| 3708 | Globals::$langs->load("main");
|
||
| 3709 | } |
||
| 3710 | |||
| 3711 | // Load translation files required by the page |
||
| 3712 | Globals::$langs->loadLangs(array('main', 'errors'));
|
||
| 3713 | |||
| 3714 | if ($_SERVER['DOCUMENT_ROOT']) { // Mode web
|
||
| 3715 | $out .= Globals::$langs->trans("DolibarrHasDetectedError") . ".<br>\n";
|
||
| 3716 | if (!empty(Globals::$conf->global->MAIN_FEATURES_LEVEL)) {
|
||
| 3717 | $out .= "You use an experimental or develop level of features, so please do NOT report any bugs, except if problem is confirmed moving option MAIN_FEATURES_LEVEL back to 0.<br>\n"; |
||
| 3718 | } |
||
| 3719 | $out .= Globals::$langs->trans("InformationToHelpDiagnose") . ":<br>\n";
|
||
| 3720 | |||
| 3721 | $out .= "<b>" . Globals::$langs->trans("Date") . ":</b> " . AlDolUtils::dol_print_date(time(), 'dayhourlog') . "<br>\n";
|
||
| 3722 | $out .= "<b>" . Globals::$langs->trans("Dolibarr") . ":</b> " . DOL_VERSION . "<br>\n";
|
||
| 3723 | if (isset(Globals::$conf->global->MAIN_FEATURES_LEVEL)) {
|
||
| 3724 | $out .= "<b>" . Globals::$langs->trans("LevelOfFeature") . ":</b> " . Globals::$conf->global->MAIN_FEATURES_LEVEL . "<br>\n";
|
||
| 3725 | } |
||
| 3726 | if (function_exists("phpversion")) {
|
||
| 3727 | $out .= "<b>" . Globals::$langs->trans("PHP") . ":</b> " . phpversion() . "<br>\n";
|
||
| 3728 | } |
||
| 3729 | $out .= "<b>" . Globals::$langs->trans("Server") . ":</b> " . $_SERVER["SERVER_SOFTWARE"] . "<br>\n";
|
||
| 3730 | if (function_exists("php_uname")) {
|
||
| 3731 | $out .= "<b>" . Globals::$langs->trans("OS") . ":</b> " . php_uname() . "<br>\n";
|
||
| 3732 | } |
||
| 3733 | $out .= "<b>" . Globals::$langs->trans("UserAgent") . ":</b> " . $_SERVER["HTTP_USER_AGENT"] . "<br>\n";
|
||
| 3734 | $out .= "<br>\n"; |
||
| 3735 | $out .= "<b>" . Globals::$langs->trans("RequestedUrl") . ":</b> " . AlDolUtils::dol_htmlentities($_SERVER["REQUEST_URI"], ENT_COMPAT, 'UTF-8') . "<br>\n";
|
||
| 3736 | $out .= "<b>" . Globals::$langs->trans("Referer") . ":</b> " . (isset($_SERVER["HTTP_REFERER"]) ? AlDolUtils::dol_htmlentities($_SERVER["HTTP_REFERER"], ENT_COMPAT, 'UTF-8') : '') . "<br>\n";
|
||
| 3737 | $out .= "<b>" . Globals::$langs->trans("MenuManager") . ":</b> " . (isset(Globals::$conf->standard_menu) ? Globals::$conf->standard_menu : '') . "<br>\n";
|
||
| 3738 | $out .= "<br>\n"; |
||
| 3739 | $syslog .= "url=" . AlDolUtils::dol_escape_htmltag($_SERVER["REQUEST_URI"]); |
||
| 3740 | $syslog .= ", query_string=" . AlDolUtils::dol_escape_htmltag($_SERVER["QUERY_STRING"]); |
||
| 3741 | } else { // Mode CLI
|
||
| 3742 | $out .= '> ' . Globals::$langs->transnoentities("ErrorInternalErrorDetected") . ":\n" . $argv[0] . "\n";
|
||
| 3743 | $syslog .= "pid=" . dol_getmypid(); |
||
| 3744 | } |
||
| 3745 | |||
| 3746 | if (is_object($dbError)) {
|
||
| 3747 | $out .= '<pre>' . print_r($dbError, true) . '</pre>'; |
||
| 3748 | /* |
||
| 3749 | if ($_SERVER['DOCUMENT_ROOT']) { // Mode web
|
||
| 3750 | $out .= "<b>" . Globals::$langs->trans("DatabaseTypeManager") . ":</b> " . $dbError->type . "<br>\n";
|
||
| 3751 | $out .= "<b>" . Globals::$langs->trans("RequestLastAccessInError") . ":</b> " . ($dbError->lastqueryerror() ? AlDolUtils::dol_escape_htmltag($db->lastqueryerror()) : Globals::$langs->trans("ErrorNoRequestInError")) . "<br>\n";
|
||
| 3752 | $out .= "<b>" . Globals::$langs->trans("ReturnCodeLastAccessInError") . ":</b> " . ($dbError->lasterrno() ? AlDolUtils::dol_escape_htmltag($db->lasterrno()) : Globals::$langs->trans("ErrorNoRequestInError")) . "<br>\n";
|
||
| 3753 | $out .= "<b>" . Globals::$langs->trans("InformationLastAccessInError") . ":</b> " . ($dbError->lasterror() ? AlDolUtils::dol_escape_htmltag($db->lasterror()) : Globals::$langs->trans("ErrorNoRequestInError")) . "<br>\n";
|
||
| 3754 | $out .= "<br>\n"; |
||
| 3755 | } else { // Mode CLI
|
||
| 3756 | // No AlDolUtils::dol_escape_htmltag for output, we are in CLI mode |
||
| 3757 | $out .= '> ' . Globals::$langs->transnoentities("DatabaseTypeManager") . ":\n" . $db->type . "\n";
|
||
| 3758 | $out .= '> ' . Globals::$langs->transnoentities("RequestLastAccessInError") . ":\n" . ($db->lastqueryerror() ? $db->lastqueryerror() : Globals::$langs->transnoentities("ErrorNoRequestInError")) . "\n";
|
||
| 3759 | $out .= '> ' . Globals::$langs->transnoentities("ReturnCodeLastAccessInError") . ":\n" . ($db->lasterrno() ? $db->lasterrno() : Globals::$langs->transnoentities("ErrorNoRequestInError")) . "\n";
|
||
| 3760 | $out .= '> ' . Globals::$langs->transnoentities("InformationLastAccessInError") . ":\n" . ($db->lasterror() ? $db->lasterror() : Globals::$langs->transnoentities("ErrorNoRequestInError")) . "\n";
|
||
| 3761 | } |
||
| 3762 | $syslog .= ", sql=" . $db->lastquery(); |
||
| 3763 | $syslog .= ", db_error=" . $db->lasterror(); |
||
| 3764 | */ |
||
| 3765 | } |
||
| 3766 | |||
| 3767 | if ($error || $errors) {
|
||
| 3768 | Globals::$langs->load("errors");
|
||
| 3769 | |||
| 3770 | // Merge all into $errors array |
||
| 3771 | if (is_array($error) && is_array($errors)) {
|
||
| 3772 | $errors = array_merge($error, $errors); |
||
| 3773 | } elseif (is_array($error)) {
|
||
| 3774 | $errors = $error; |
||
| 3775 | } elseif (is_array($errors)) {
|
||
| 3776 | $errors = array_merge(array($error), $errors); |
||
| 3777 | } else {
|
||
| 3778 | $errors = array_merge(array($error)); |
||
| 3779 | } |
||
| 3780 | |||
| 3781 | foreach ($errors as $msg) {
|
||
| 3782 | if (empty($msg)) {
|
||
| 3783 | continue; |
||
| 3784 | } |
||
| 3785 | if ($_SERVER['DOCUMENT_ROOT']) { // Mode web
|
||
| 3786 | $out .= "<b>" . Globals::$langs->trans("Message") . ":</b> " . AlDolUtils::dol_escape_htmltag($msg) . "<br>\n";
|
||
| 3787 | } else { // Mode CLI
|
||
| 3788 | $out .= '> ' . Globals::$langs->transnoentities("Message") . ":\n" . $msg . "\n";
|
||
| 3789 | } |
||
| 3790 | $syslog .= ", msg=" . $msg; |
||
| 3791 | } |
||
| 3792 | } |
||
| 3793 | if (empty($dolibarr_main_prod) && $_SERVER['DOCUMENT_ROOT'] && function_exists('xdebug_print_function_stack') && function_exists('xdebug_call_file')) {
|
||
| 3794 | xdebug_print_function_stack(); |
||
| 3795 | $out .= '<b>XDebug informations:</b>' . "<br>\n"; |
||
| 3796 | $out .= 'File: ' . xdebug_call_file() . "<br>\n"; |
||
| 3797 | $out .= 'Line: ' . xdebug_call_line() . "<br>\n"; |
||
| 3798 | $out .= 'Function: ' . xdebug_call_function() . "<br>\n"; |
||
| 3799 | $out .= "<br>\n"; |
||
| 3800 | } |
||
| 3801 | |||
| 3802 | if (empty($dolibarr_main_prod)) {
|
||
| 3803 | print $out; |
||
| 3804 | } else {
|
||
| 3805 | print Globals::$langs->trans("DolibarrHasDetectedError") . '. ';
|
||
| 3806 | print Globals::$langs->trans("YouCanSetOptionDolibarrMainProdToZero");
|
||
| 3807 | define("MAIN_CORE_ERROR", 1);
|
||
| 3808 | } |
||
| 3809 | //else print 'Sorry, an error occured but the parameter $dolibarr_main_prod is defined in conf file so no message is reported to your browser. Please read the log file for error message.'; |
||
| 3810 | AlDolUtils::dol_syslog("Error " . $syslog, LOG_ERR);
|
||
| 3811 | } |
||
| 3812 | |||
| 3813 | /** |
||
| 3814 | * Show a public email and error code to contact if technical error |
||
| 3815 | * |
||
| 3816 | * @param string $prefixcode Prefix of public error code |
||
| 3817 | * @param string $errormessage Complete error message |
||
| 3818 | * @param array $errormessages Array of error messages |
||
| 3819 | * @param string $morecss More css |
||
| 3820 | * @param string $email Email |
||
| 3821 | * @return void |
||
| 3822 | */ |
||
| 3823 | static function dol_print_error_email($prefixcode, $errormessage = '', $errormessages = array(), $morecss = 'error', $email = '') |
||
| 3824 | {
|
||
| 3825 | // global Globals::$langs, Globals::$conf; |
||
| 3826 | |||
| 3827 | if (empty($email)) {
|
||
| 3828 | $email = Globals::$conf->global->MAIN_INFO_SOCIETE_MAIL; |
||
| 3829 | } |
||
| 3830 | |||
| 3831 | Globals::$langs->load("errors");
|
||
| 3832 | $now = dol_now(); |
||
| 3833 | |||
| 3834 | print '<br><div class="center login_main_message"><div class="' . $morecss . '">'; |
||
| 3835 | print Globals::$langs->trans("ErrorContactEMail", $email, $prefixcode . AlDolUtils::dol_print_date($now, '%Y%m%d'));
|
||
| 3836 | if ($errormessage) {
|
||
| 3837 | print '<br><br>' . $errormessage; |
||
| 3838 | } |
||
| 3839 | if (is_array($errormessages) && count($errormessages)) {
|
||
| 3840 | foreach ($errormessages as $mesgtoshow) {
|
||
| 3841 | print '<br><br>' . $mesgtoshow; |
||
| 3842 | } |
||
| 3843 | } |
||
| 3844 | print '</div></div>'; |
||
| 3845 | } |
||
| 3846 | |||
| 3847 | /** |
||
| 3848 | * Show title line of an array |
||
| 3849 | * |
||
| 3850 | * @param string $name Label of field |
||
| 3851 | * @param string $file Url used when we click on sort picto |
||
| 3852 | * @param string $field Field to use for new sorting |
||
| 3853 | * @param string $begin ("" by defaut)
|
||
| 3854 | * @param string $moreparam Add more parameters on sort url links ("" by default)
|
||
| 3855 | * @param string $moreattrib Options of attribute td ("" by defaut, example: 'align="center"')
|
||
| 3856 | * @param string $sortfield Current field used to sort |
||
| 3857 | * @param string $sortorder Current sort order |
||
| 3858 | * @param string $prefix Prefix for css. Use space after prefix to add your own CSS tag. |
||
| 3859 | * @param string $tooltip Tooltip |
||
| 3860 | * @return void |
||
| 3861 | */ |
||
| 3862 | static function print_liste_field_titre($name, $file = "", $field = "", $begin = "", $moreparam = "", $moreattrib = "", $sortfield = "", $sortorder = "", $prefix = "", $tooltip = "") |
||
| 3863 | {
|
||
| 3864 | print getTitleFieldOfList($name, 0, $file, $field, $begin, $moreparam, $moreattrib, $sortfield, $sortorder, $prefix, 0, $tooltip); |
||
| 3865 | } |
||
| 3866 | |||
| 3867 | /** |
||
| 3868 | * Get title line of an array |
||
| 3869 | * |
||
| 3870 | * @param string $name Translation key of field |
||
| 3871 | * @param int $thead 0=To use with standard table format, 1=To use inside <thead><tr>, 2=To use with <div> |
||
| 3872 | * @param string $file Url used when we click on sort picto |
||
| 3873 | * @param string $field Field to use for new sorting. Empty if this field is not sortable. Example "t.abc" or "t.abc,t.def" |
||
| 3874 | * @param string $begin ("" by defaut)
|
||
| 3875 | * @param string $moreparam Add more parameters on sort url links ("" by default)
|
||
| 3876 | * @param string $moreattrib Add more attributes on th ("" by defaut, example: 'align="center"'). To add more css class, use param $prefix.
|
||
| 3877 | * @param string $sortfield Current field used to sort (Ex: 'd.datep,d.id') |
||
| 3878 | * @param string $sortorder Current sort order (Ex: 'asc,desc') |
||
| 3879 | * @param string $prefix Prefix for css. Use space after prefix to add your own CSS tag, for example 'mycss '. |
||
| 3880 | * @param string $disablesortlink 1=Disable sort link |
||
| 3881 | * @param string $tooltip Tooltip |
||
| 3882 | * @return string |
||
| 3883 | */ |
||
| 3884 | static function getTitleFieldOfList($name, $thead = 0, $file = "", $field = "", $begin = "", $moreparam = "", $moreattrib = "", $sortfield = "", $sortorder = "", $prefix = "", $disablesortlink = 0, $tooltip = '') |
||
| 3977 | } |
||
| 3978 | |||
| 3979 | /** |
||
| 3980 | * Show a title. |
||
| 3981 | * |
||
| 3982 | * @param string $title Title to show |
||
| 3983 | * @return string Title to show |
||
| 3984 | * @deprecated Use load_fiche_titre instead |
||
| 3985 | * @see load_fiche_titre |
||
| 3986 | */ |
||
| 3987 | static function print_titre($title) |
||
| 3988 | {
|
||
| 3989 | AlDolUtils::dol_syslog(__FUNCTION__ . " is deprecated", LOG_WARNING); |
||
| 3990 | |||
| 3991 | print '<div class="titre">' . $title . '</div>'; |
||
| 3992 | } |
||
| 3993 | |||
| 3994 | /** |
||
| 3995 | * Show a title with picto |
||
| 3996 | * |
||
| 3997 | * @param string $title Title to show |
||
| 3998 | * @param string $mesg Added message to show on right |
||
| 3999 | * @param string $picto Icon to use before title (should be a 32x32 transparent png file) |
||
| 4000 | * @param int $pictoisfullpath 1=Icon name is a full absolute url of image |
||
| 4001 | * @param int $id To force an id on html objects |
||
| 4002 | * @return void |
||
| 4003 | * @deprecated Use print load_fiche_titre instead |
||
| 4004 | */ |
||
| 4005 | static function print_fiche_titre($title, $mesg = '', $picto = 'title_generic.png', $pictoisfullpath = 0, $id = '') |
||
| 4006 | {
|
||
| 4007 | print load_fiche_titre($title, $mesg, $picto, $pictoisfullpath, $id); |
||
| 4008 | } |
||
| 4009 | |||
| 4010 | /** |
||
| 4011 | * Load a title with picto |
||
| 4012 | * |
||
| 4013 | * @param string $titre Title to show |
||
| 4014 | * @param string $morehtmlright Added message to show on right |
||
| 4015 | * @param string $picto Icon to use before title (should be a 32x32 transparent png file) |
||
| 4016 | * @param int $pictoisfullpath 1=Icon name is a full absolute url of image |
||
| 4017 | * @param string $id To force an id on html objects |
||
| 4018 | * @param string $morecssontable More css on table |
||
| 4019 | * @param string $morehtmlcenter Added message to show on center |
||
| 4020 | * @return string |
||
| 4021 | * @see print_barre_liste |
||
| 4022 | */ |
||
| 4023 | static function load_fiche_titre($titre, $morehtmlright = '', $picto = 'title_generic.png', $pictoisfullpath = 0, $id = '', $morecssontable = '', $morehtmlcenter = '') |
||
| 4024 | {
|
||
| 4025 | // global Globals::$conf; |
||
| 4026 | |||
| 4027 | $return = ''; |
||
| 4028 | |||
| 4029 | if ($picto == 'setup') {
|
||
| 4030 | $picto = 'title_generic.png'; |
||
| 4031 | } |
||
| 4032 | |||
| 4033 | $return .= "\n"; |
||
| 4034 | $return .= '<table ' . ($id ? 'id="' . $id . '" ' : '') . 'summary="" class="centpercent notopnoleftnoright' . ($morecssontable ? ' ' . $morecssontable : '') . '" style="margin-bottom: 6px;"><tr>'; // maring bottom must be same than into print_barre_list |
||
| 4035 | if ($picto) {
|
||
| 4036 | $return .= '<td class="nobordernopadding widthpictotitle opacityhigh" valign="middle">' . AlDolUtils::img_picto('', $picto, 'class="valignmiddle widthpictotitle pictotitle"', $pictoisfullpath) . '</td>';
|
||
| 4037 | } |
||
| 4038 | $return .= '<td class="nobordernopadding valignmiddle">'; |
||
| 4039 | $return .= '<div class="titre inline-block">' . $titre . '</div>'; |
||
| 4040 | $return .= '</td>'; |
||
| 4041 | if (AlDolUtils::dol_strlen($morehtmlcenter)) {
|
||
| 4042 | $return .= '<td class="nobordernopadding" align="center" valign="middle">' . $morehtmlcenter . '</td>'; |
||
| 4043 | } |
||
| 4044 | if (AlDolUtils::dol_strlen($morehtmlright)) {
|
||
| 4045 | $return .= '<td class="nobordernopadding titre_right wordbreak" align="right" valign="middle">' . $morehtmlright . '</td>'; |
||
| 4046 | } |
||
| 4047 | $return .= '</tr></table>' . "\n"; |
||
| 4048 | |||
| 4049 | return $return; |
||
| 4050 | } |
||
| 4051 | |||
| 4052 | /** |
||
| 4053 | * Print a title with navigation controls for pagination |
||
| 4054 | * |
||
| 4055 | * @param string $titre Title to show (required) |
||
| 4056 | * @param int $page Numero of page to show in navigation links (required) |
||
| 4057 | * @param string $file Url of page (required) |
||
| 4058 | * @param string $options More parameters for links ('' by default, does not include sortfield neither sortorder). Value must be 'urlencoded' before calling function.
|
||
| 4059 | * @param string $sortfield Field to sort on ('' by default)
|
||
| 4060 | * @param string $sortorder Order to sort ('' by default)
|
||
| 4061 | * @param string $morehtmlcenter String in the middle ('' by default). We often find here string $massaction comming from $form->selectMassAction()
|
||
| 4062 | * @param int $num Number of records found by select with limit+1 |
||
| 4063 | * @param int|string $totalnboflines Total number of records/lines for all pages (if known). Use a negative value of number to not show number. Use '' if unknown. |
||
| 4064 | * @param string $picto Icon to use before title (should be a 32x32 transparent png file) |
||
| 4065 | * @param int $pictoisfullpath 1=Icon name is a full absolute url of image |
||
| 4066 | * @param string $morehtmlright More html to show |
||
| 4067 | * @param string $morecss More css to the table |
||
| 4068 | * @param int $limit Max number of lines (-1 = use default, 0 = no limit, > 0 = limit). |
||
| 4069 | * @param int $hideselectlimit Force to hide select limit |
||
| 4070 | * @param int $hidenavigation Force to hide all navigation tools |
||
| 4071 | * @return void |
||
| 4072 | */ |
||
| 4073 | static function print_barre_liste($titre, $page, $file, $options = '', $sortfield = '', $sortorder = '', $morehtmlcenter = '', $num = -1, $totalnboflines = '', $picto = 'title_generic.png', $pictoisfullpath = 0, $morehtmlright = '', $morecss = '', $limit = -1, $hideselectlimit = 0, $hidenavigation = 0) |
||
| 4074 | {
|
||
| 4075 | // global Globals::$conf, Globals::$langs; |
||
| 4076 | |||
| 4077 | $savlimit = $limit; |
||
| 4078 | $savtotalnboflines = $totalnboflines; |
||
| 4079 | $totalnboflines = abs($totalnboflines); |
||
| 4080 | |||
| 4081 | if ($picto == 'setup') |
||
| 4082 | $picto = 'title_setup.png'; |
||
| 4083 | if ((Globals::$conf->browser->name == 'ie') && $picto == 'title_generic.png') |
||
| 4084 | $picto = 'title.gif'; |
||
| 4085 | if ($limit < 0) |
||
| 4086 | $limit = Globals::$conf->liste_limit; |
||
| 4087 | if ($savlimit != 0 && (($num > $limit) || ($num == -1) || ($limit == 0))) {
|
||
| 4088 | $nextpage = 1; |
||
| 4089 | } else {
|
||
| 4090 | $nextpage = 0; |
||
| 4091 | } |
||
| 4092 | //print 'totalnboflines='.$totalnboflines.'-savlimit='.$savlimit.'-limit='.$limit.'-num='.$num.'-nextpage='.$nextpage; |
||
| 4093 | |||
| 4094 | print "\n"; |
||
| 4095 | print "<!-- Begin title '" . $titre . "' -->\n"; |
||
| 4096 | print '<table border="0" class="centpercent notopnoleftnoright' . ($morecss ? ' ' . $morecss : '') . '" style="margin-bottom: 6px;"><tr>'; // maring bottom must be same than into load_fiche_tire |
||
| 4097 | // Left |
||
| 4098 | //if ($picto && $titre) print '<td class="nobordernopadding hideonsmartphone" width="40" align="left" valign="middle">'.img_picto('', $picto, 'id="pictotitle"', $pictoisfullpath).'</td>';
|
||
| 4099 | print '<td class="nobordernopadding valignmiddle">'; |
||
| 4100 | if ($picto && $titre) |
||
| 4101 | print img_picto('', $picto, 'class="hideonsmartphone valignmiddle opacityhigh pictotitle widthpictotitle"', $pictoisfullpath);
|
||
| 4102 | print '<div class="titre inline-block">' . $titre; |
||
| 4103 | if (!empty($titre) && $savtotalnboflines >= 0 && (string) $savtotalnboflines != '') |
||
| 4104 | print ' (' . $totalnboflines . ')';
|
||
| 4105 | print '</div></td>'; |
||
| 4106 | |||
| 4107 | // Center |
||
| 4108 | if ($morehtmlcenter) {
|
||
| 4109 | print '<td class="nobordernopadding center valignmiddle">' . $morehtmlcenter . '</td>'; |
||
| 4110 | } |
||
| 4111 | |||
| 4112 | // Right |
||
| 4113 | print '<td class="nobordernopadding valignmiddle" align="right">'; |
||
| 4114 | if ($sortfield) |
||
| 4115 | $options .= "&sortfield=" . urlencode($sortfield); |
||
| 4116 | if ($sortorder) |
||
| 4117 | $options .= "&sortorder=" . urlencode($sortorder); |
||
| 4118 | // Show navigation bar |
||
| 4119 | $pagelist = ''; |
||
| 4120 | if ($savlimit != 0 && ($page > 0 || $num > $limit)) {
|
||
| 4121 | if ($totalnboflines) { // If we know total nb of lines
|
||
| 4122 | // Define nb of extra page links before and after selected page + ... + first or last |
||
| 4123 | $maxnbofpage = (empty(Globals::$conf->dol_optimize_smallscreen) ? 4 : 1); |
||
| 4124 | |||
| 4125 | if ($limit > 0) |
||
| 4126 | $nbpages = ceil($totalnboflines / $limit); |
||
| 4127 | else |
||
| 4128 | $nbpages = 1; |
||
| 4129 | $cpt = ($page - $maxnbofpage); |
||
| 4130 | if ($cpt < 0) {
|
||
| 4131 | $cpt = 0; |
||
| 4132 | } |
||
| 4133 | |||
| 4134 | if ($cpt >= 1) {
|
||
| 4135 | $pagelist .= '<li' . ((Globals::$conf->dol_use_jmobile != 4) ? ' class="pagination"' : '') . '><a href="' . $file . '?page=0' . $options . '">1</a></li>'; |
||
| 4136 | if ($cpt > 2) |
||
| 4137 | $pagelist .= '<li' . ( (Globals::$conf->dol_use_jmobile != 4) ? ' class="pagination"' : '') . '><span ' . ((Globals::$conf->dol_use_jmobile != 4) ? 'class="inactive"' : '') . '>...</span></li>'; |
||
| 4138 | else if ($cpt == 2) |
||
| 4139 | $pagelist .= '<li' . ( (Globals::$conf->dol_use_jmobile != 4) ? ' class="pagination"' : '') . '><a href="' . $file . '?page=1' . $options . '">2</a></li>'; |
||
| 4140 | } |
||
| 4141 | |||
| 4142 | do {
|
||
| 4143 | if ($cpt == $page) {
|
||
| 4144 | $pagelist .= '<li' . ((Globals::$conf->dol_use_jmobile != 4) ? ' class="pagination"' : '') . '><span ' . ((Globals::$conf->dol_use_jmobile != 4) ? 'class="active"' : '') . '>' . ($page + 1) . '</span></li>'; |
||
| 4145 | } else {
|
||
| 4146 | $pagelist .= '<li' . ((Globals::$conf->dol_use_jmobile != 4) ? ' class="pagination"' : '') . '><a href="' . $file . '?page=' . $cpt . $options . '">' . ($cpt + 1) . '</a></li>'; |
||
| 4147 | } |
||
| 4148 | $cpt++; |
||
| 4149 | } while ($cpt < $nbpages && $cpt <= $page + $maxnbofpage); |
||
| 4150 | |||
| 4151 | if ($cpt < $nbpages) {
|
||
| 4152 | if ($cpt < $nbpages - 2) |
||
| 4153 | $pagelist .= '<li' . ( (Globals::$conf->dol_use_jmobile != 4) ? ' class="pagination"' : '') . '><span ' . ((Globals::$conf->dol_use_jmobile != 4) ? 'class="inactive"' : '') . '>...</span></li>'; |
||
| 4154 | else if ($cpt == $nbpages - 2) |
||
| 4155 | $pagelist .= '<li' . ( (Globals::$conf->dol_use_jmobile != 4) ? ' class="pagination"' : '') . '><a href="' . $file . '?page=' . ($nbpages - 2) . $options . '">' . ($nbpages - 1) . '</a></li>'; |
||
| 4156 | $pagelist .= '<li' . ((Globals::$conf->dol_use_jmobile != 4) ? ' class="pagination"' : '') . '><a href="' . $file . '?page=' . ($nbpages - 1) . $options . '">' . $nbpages . '</a></li>'; |
||
| 4157 | } |
||
| 4158 | } |
||
| 4159 | else {
|
||
| 4160 | $pagelist .= '<li' . ((Globals::$conf->dol_use_jmobile != 4) ? ' class="pagination"' : '') . '><span ' . ((Globals::$conf->dol_use_jmobile != 4) ? 'class="active"' : '') . '>' . ($page + 1) . "</li>"; |
||
| 4161 | } |
||
| 4162 | } |
||
| 4163 | |||
| 4164 | print_fleche_navigation($page, $file, $options, $nextpage, $pagelist, $morehtmlright, $savlimit, $totalnboflines, $hideselectlimit); // output the div and ul for previous/last completed with page numbers into $pagelist |
||
| 4165 | |||
| 4166 | print '</td>'; |
||
| 4167 | |||
| 4168 | print '</tr></table>' . "\n"; |
||
| 4169 | print "<!-- End title -->\n\n"; |
||
| 4170 | } |
||
| 4171 | |||
| 4172 | /** |
||
| 4173 | * Function to show navigation arrows into lists |
||
| 4174 | * |
||
| 4175 | * @param int $page Number of page |
||
| 4176 | * @param string $file Page URL (in most cases provided with $_SERVER["PHP_SELF"]) |
||
| 4177 | * @param string $options Other url paramaters to propagate ("" by default, may include sortfield and sortorder)
|
||
| 4178 | * @param integer $nextpage Do we show a next page button |
||
| 4179 | * @param string $betweenarrows HTML content to show between arrows. MUST contains '<li> </li>' tags or '<li><span> </span></li>'. |
||
| 4180 | * @param string $afterarrows HTML content to show after arrows. Must NOT contains '<li> </li>' tags. |
||
| 4181 | * @param int $limit Max nb of record to show (-1 = no combo with limit, 0 = no limit, > 0 = limit) |
||
| 4182 | * @param int $totalnboflines Total number of records/lines for all pages (if known) |
||
| 4183 | * @param int $hideselectlimit Force to hide select limit |
||
| 4184 | * @return void |
||
| 4185 | */ |
||
| 4186 | static function print_fleche_navigation($page, $file, $options = '', $nextpage = 0, $betweenarrows = '', $afterarrows = '', $limit = -1, $totalnboflines = 0, $hideselectlimit = 0) |
||
| 4187 | {
|
||
| 4188 | // global Globals::$conf, Globals::$langs; |
||
| 4189 | |||
| 4190 | print '<div class="pagination"><ul>'; |
||
| 4191 | if ((int) $limit >= 0 && empty($hideselectlimit)) {
|
||
| 4192 | $pagesizechoices = '10:10,15:15,20:20,30:30,40:40,50:50,100:100,250:250,500:500,1000:1000,5000:5000'; |
||
| 4193 | //$pagesizechoices.=',0:'.Globals::$langs->trans("All"); // Not yet supported
|
||
| 4194 | //$pagesizechoices.=',2:2'; |
||
| 4195 | if (!empty(Globals::$conf->global->MAIN_PAGESIZE_CHOICES)) |
||
| 4196 | $pagesizechoices = Globals::$conf->global->MAIN_PAGESIZE_CHOICES; |
||
| 4197 | |||
| 4198 | print '<li class="pagination">'; |
||
| 4199 | print '<select class="flat selectlimit" name="limit" title="' . AlDolUtils::dol_escape_htmltag(Globals::$langs->trans("MaxNbOfRecordPerPage")) . '">';
|
||
| 4200 | $tmpchoice = explode(',', $pagesizechoices);
|
||
| 4201 | $tmpkey = $limit . ':' . $limit; |
||
| 4202 | if (!in_array($tmpkey, $tmpchoice)) |
||
| 4203 | $tmpchoice[] = $tmpkey; |
||
| 4204 | $tmpkey = Globals::$conf->liste_limit . ':' . Globals::$conf->liste_limit; |
||
| 4205 | if (!in_array($tmpkey, $tmpchoice)) |
||
| 4206 | $tmpchoice[] = $tmpkey; |
||
| 4207 | asort($tmpchoice, SORT_NUMERIC); |
||
| 4208 | $found = false; |
||
| 4209 | foreach ($tmpchoice as $val) {
|
||
| 4210 | $selected = ''; |
||
| 4211 | $tmp = explode(':', $val);
|
||
| 4212 | $key = $tmp[0]; |
||
| 4213 | $val = $tmp[1]; |
||
| 4214 | if ($key != '' && $val != '') {
|
||
| 4215 | if ((int) $key == (int) $limit) {
|
||
| 4216 | $selected = ' selected="selected"'; |
||
| 4217 | $found = true; |
||
| 4218 | } |
||
| 4219 | print '<option name="' . $key . '"' . $selected . '>' . AlDolUtils::dol_escape_htmltag($val) . '</option>' . "\n"; |
||
| 4220 | } |
||
| 4221 | } |
||
| 4222 | print '</select>'; |
||
| 4223 | if (Globals::$conf->use_javascript_ajax) {
|
||
| 4224 | print '<!-- JS CODE TO ENABLE select limit to launch submit of page --> |
||
| 4225 | <script type="text/javascript"> |
||
| 4226 | jQuery(document).ready(static function () {
|
||
| 4227 | jQuery(".selectlimit").change(function() {
|
||
| 4228 | console.log("Change limit. Send submit");
|
||
| 4229 | $(this).parents(\'form:first\').submit(); |
||
| 4230 | }); |
||
| 4231 | }); |
||
| 4232 | </script> |
||
| 4233 | '; |
||
| 4234 | } |
||
| 4235 | print '</li>'; |
||
| 4236 | } |
||
| 4237 | if ($page > 0) {
|
||
| 4238 | print '<li class="pagination"><a class="paginationprevious" href="' . $file . '?page=' . ($page - 1) . $options . '"><i class="fa fa-chevron-left" title="' . AlDolUtils::dol_escape_htmltag(Globals::$langs->trans("Previous")) . '"></i></a></li>';
|
||
| 4239 | } |
||
| 4240 | if ($betweenarrows) {
|
||
| 4241 | print $betweenarrows; |
||
| 4242 | } |
||
| 4243 | if ($nextpage > 0) {
|
||
| 4244 | print '<li class="pagination"><a class="paginationnext" href="' . $file . '?page=' . ($page + 1) . $options . '"><i class="fa fa-chevron-right" title="' . AlDolUtils::dol_escape_htmltag(Globals::$langs->trans("Next")) . '"></i></a></li>';
|
||
| 4245 | } |
||
| 4246 | if ($afterarrows) {
|
||
| 4247 | print '<li class="paginationafterarrows">'; |
||
| 4248 | print $afterarrows; |
||
| 4249 | print '</li>'; |
||
| 4250 | } |
||
| 4251 | print '</ul></div>' . "\n"; |
||
| 4252 | } |
||
| 4253 | |||
| 4254 | /** |
||
| 4255 | * Return a string with VAT rate label formated for view output |
||
| 4256 | * Used into pdf and HTML pages |
||
| 4257 | * |
||
| 4258 | * @param string $rate Rate value to format ('19.6', '19,6', '19.6%', '19,6%', '19.6 (CODEX)', ...)
|
||
| 4259 | * @param boolean $addpercent Add a percent % sign in output |
||
| 4260 | * @param int $info_bits Miscellaneous information on vat (0=Default, 1=French NPR vat) |
||
| 4261 | * @param int $usestarfornpr -1=Never show, 0 or 1=Use '*' for NPR vat rates |
||
| 4262 | * @return string String with formated amounts ('19,6' or '19,6%' or '8.5% (NPR)' or '8.5% *' or '19,6 (CODEX)')
|
||
| 4263 | */ |
||
| 4264 | static function vatrate($rate, $addpercent = false, $info_bits = 0, $usestarfornpr = 0) |
||
| 4265 | {
|
||
| 4266 | $morelabel = ''; |
||
| 4267 | |||
| 4268 | if (preg_match('/%/', $rate)) {
|
||
| 4269 | $rate = str_replace('%', '', $rate);
|
||
| 4270 | $addpercent = true; |
||
| 4271 | } |
||
| 4272 | if (preg_match('/\((.*)\)/', $rate, $reg)) {
|
||
| 4273 | $morelabel = ' (' . $reg[1] . ')';
|
||
| 4274 | $rate = preg_replace('/\s*' . preg_quote($morelabel, '/') . '/', '', $rate);
|
||
| 4275 | } |
||
| 4276 | if (preg_match('/\*/', $rate)) {
|
||
| 4277 | $rate = str_replace('*', '', $rate);
|
||
| 4278 | $info_bits |= 1; |
||
| 4279 | } |
||
| 4280 | |||
| 4281 | // If rate is '9/9/9' we don't change it. If rate is '9.000' we apply price() |
||
| 4282 | if (!preg_match('/\//', $rate))
|
||
| 4283 | $ret = price($rate, 0, '', 0, 0) . ($addpercent ? '%' : ''); |
||
| 4284 | else {
|
||
| 4285 | // TODO Split on / and output with a price2num to have clean numbers without ton of 000. |
||
| 4286 | $ret = $rate . ($addpercent ? '%' : ''); |
||
| 4287 | } |
||
| 4288 | if (($info_bits & 1) && $usestarfornpr >= 0) |
||
| 4289 | $ret .= ' *'; |
||
| 4290 | $ret .= $morelabel; |
||
| 4291 | return $ret; |
||
| 4292 | } |
||
| 4293 | |||
| 4294 | /** |
||
| 4295 | * Function to format a value into an amount for visual output |
||
| 4296 | * Function used into PDF and HTML pages |
||
| 4297 | * |
||
| 4298 | * @param float $amount Amount to format |
||
| 4299 | * @param integer $form Type of format, HTML or not (not by default) |
||
| 4300 | * @param Translate $outlangs Object langs for output |
||
| 4301 | * @param int $trunc 1=Truncate if there is more decimals than MAIN_MAX_DECIMALS_SHOWN (default), 0=Does not truncate. Deprecated because amount are rounded (to unit or total amount accurancy) before beeing inserted into database or after a computation, so this parameter should be useless. |
||
| 4302 | * @param int $rounding Minimum number of decimal to show. If 0, no change, if -1, we use min(Globals::$conf->global->MAIN_MAX_DECIMALS_UNIT,Globals::$conf->global->MAIN_MAX_DECIMALS_TOT) |
||
| 4303 | * @param int $forcerounding Force the number of decimal to forcerounding decimal (-1=do not force) |
||
| 4304 | * @param string $currency_code To add currency symbol (''=add nothing, 'auto'=Use default currency, 'XXX'=add currency symbols for XXX currency)
|
||
| 4305 | * @return string Chaine avec montant formate |
||
| 4306 | * |
||
| 4307 | * @see price2num Revert static function of price |
||
| 4308 | */ |
||
| 4309 | static function price($amount, $form = 0, $outlangs = '', $trunc = 1, $rounding = -1, $forcerounding = -1, $currency_code = '') |
||
| 4385 | } |
||
| 4386 | |||
| 4387 | /** |
||
| 4388 | * Function that return a number with universal decimal format (decimal separator is '.') from an amount typed by a user. |
||
| 4389 | * Function to use on each input amount before any numeric test or database insert |
||
| 4390 | * |
||
| 4391 | * @param float $amount Amount to convert/clean |
||
| 4392 | * @param string $rounding ''=No rounding |
||
| 4393 | * 'MU'=Round to Max unit price (MAIN_MAX_DECIMALS_UNIT) |
||
| 4394 | * 'MT'=Round to Max for totals with Tax (MAIN_MAX_DECIMALS_TOT) |
||
| 4395 | * 'MS'=Round to Max for stock quantity (MAIN_MAX_DECIMALS_STOCK) |
||
| 4396 | * Numeric = Nb of digits for rounding |
||
| 4397 | * @param int $alreadysqlnb Put 1 if you know that content is already universal format number |
||
| 4398 | * @return string Amount with universal numeric format (Example: '99.99999') or unchanged text if conversion fails. If amount is null or '', it returns ''. |
||
| 4399 | * |
||
| 4400 | * @see price Opposite static function of price2num |
||
| 4401 | */ |
||
| 4402 | static function price2num($amount, $rounding = '', $alreadysqlnb = 0) |
||
| 4403 | {
|
||
| 4404 | // global Globals::$langs, Globals::$conf; |
||
| 4405 | // Round PHP static function does not allow number like '1,234.56' nor '1.234,56' nor '1 234,56' |
||
| 4406 | // Numbers must be '1234.56' |
||
| 4407 | // Decimal delimiter for PHP and database SQL requests must be '.' |
||
| 4408 | $dec = ','; |
||
| 4409 | $thousand = ' '; |
||
| 4410 | if (Globals::$langs->transnoentitiesnoconv("SeparatorDecimal") != "SeparatorDecimal")
|
||
| 4411 | $dec = Globals::$langs->transnoentitiesnoconv("SeparatorDecimal");
|
||
| 4412 | if (Globals::$langs->transnoentitiesnoconv("SeparatorThousand") != "SeparatorThousand")
|
||
| 4413 | $thousand = Globals::$langs->transnoentitiesnoconv("SeparatorThousand");
|
||
| 4414 | if ($thousand == 'None') |
||
| 4415 | $thousand = ''; |
||
| 4416 | elseif ($thousand == 'Space') |
||
| 4417 | $thousand = ' '; |
||
| 4418 | //print "amount=".$amount." html=".$form." trunc=".$trunc." nbdecimal=".$nbdecimal." dec='".$dec."' thousand='".$thousand."'<br>"; |
||
| 4419 | // Convert value to universal number format (no thousand separator, '.' as decimal separator) |
||
| 4420 | if ($alreadysqlnb != 1) { // If not a PHP number or unknown, we change format
|
||
| 4421 | //print 'PP'.$amount.' - '.$dec.' - '.$thousand.' - '.intval($amount).'<br>'; |
||
| 4422 | // Convert amount to format with dolibarr dec and thousand (this is because PHP convert a number |
||
| 4423 | // to format defined by LC_NUMERIC after a calculation and we want source format to be like defined by Dolibarr setup. |
||
| 4424 | if (is_numeric($amount)) {
|
||
| 4425 | // We put in temps value of decimal ("0.00001"). Works with 0 and 2.0E-5 and 9999.10
|
||
| 4426 | $temps = sprintf("%0.10F", $amount - intval($amount)); // temps=0.0000000000 or 0.0000200000 or 9999.1000000000
|
||
| 4427 | $temps = preg_replace('/([\.1-9])0+$/', '\\1', $temps); // temps=0. or 0.00002 or 9999.1
|
||
| 4428 | $nbofdec = max(0, AlDolUtils::dol_strlen($temps) - 2); // -2 to remove "0." |
||
| 4429 | $amount = number_format($amount, $nbofdec, $dec, $thousand); |
||
| 4430 | } |
||
| 4431 | //print "QQ".$amount.'<br>'; |
||
| 4432 | // Now make replace (the main goal of function) |
||
| 4433 | if ($thousand != ',' && $thousand != '.') |
||
| 4434 | $amount = str_replace(',', '.', $amount); // To accept 2 notations for french users
|
||
| 4435 | $amount = str_replace(' ', '', $amount); // To avoid spaces
|
||
| 4436 | $amount = str_replace($thousand, '', $amount); // Replace of thousand before replace of dec to avoid pb if thousand is . |
||
| 4437 | $amount = str_replace($dec, '.', $amount); |
||
| 4438 | } |
||
| 4439 | |||
| 4440 | // Now, make a rounding if required |
||
| 4441 | if ($rounding) {
|
||
| 4442 | $nbofdectoround = ''; |
||
| 4443 | if ($rounding == 'MU') |
||
| 4444 | $nbofdectoround = Globals::$conf->global->MAIN_MAX_DECIMALS_UNIT; |
||
| 4445 | elseif ($rounding == 'MT') |
||
| 4446 | $nbofdectoround = Globals::$conf->global->MAIN_MAX_DECIMALS_TOT; |
||
| 4447 | elseif ($rounding == 'MS') |
||
| 4448 | $nbofdectoround = empty(Globals::$conf->global->MAIN_MAX_DECIMALS_STOCK) ? 5 : Globals::$conf->global->MAIN_MAX_DECIMALS_STOCK; |
||
| 4449 | elseif (is_numeric($rounding)) |
||
| 4450 | $nbofdectoround = $rounding; |
||
| 4451 | //print "RR".$amount.' - '.$nbofdectoround.'<br>'; |
||
| 4452 | if (AlDolUtils::dol_strlen($nbofdectoround)) |
||
| 4453 | $amount = round($amount, $nbofdectoround); // $nbofdectoround can be 0. |
||
| 4454 | else |
||
| 4455 | return 'ErrorBadParameterProvidedToFunction'; |
||
| 4456 | //print 'SS'.$amount.' - '.$nbofdec.' - '.$dec.' - '.$thousand.' - '.$nbofdectoround.'<br>'; |
||
| 4457 | // Convert amount to format with dolibarr dec and thousand (this is because PHP convert a number |
||
| 4458 | // to format defined by LC_NUMERIC after a calculation and we want source format to be defined by Dolibarr setup. |
||
| 4459 | if (is_numeric($amount)) {
|
||
| 4460 | // We put in temps value of decimal ("0.00001"). Works with 0 and 2.0E-5 and 9999.10
|
||
| 4461 | $temps = sprintf("%0.10F", $amount - intval($amount)); // temps=0.0000000000 or 0.0000200000 or 9999.1000000000
|
||
| 4462 | $temps = preg_replace('/([\.1-9])0+$/', '\\1', $temps); // temps=0. or 0.00002 or 9999.1
|
||
| 4463 | $nbofdec = max(0, AlDolUtils::dol_strlen($temps) - 2); // -2 to remove "0." |
||
| 4464 | $amount = number_format($amount, min($nbofdec, $nbofdectoround), $dec, $thousand); // Convert amount to format with dolibarr dec and thousand |
||
| 4465 | } |
||
| 4466 | //print "TT".$amount.'<br>'; |
||
| 4467 | // Always make replace because each math static function (like round) replace |
||
| 4468 | // with local values and we want a number that has a SQL string format x.y |
||
| 4469 | if ($thousand != ',' && $thousand != '.') |
||
| 4470 | $amount = str_replace(',', '.', $amount); // To accept 2 notations for french users
|
||
| 4471 | $amount = str_replace(' ', '', $amount); // To avoid spaces
|
||
| 4472 | $amount = str_replace($thousand, '', $amount); // Replace of thousand before replace of dec to avoid pb if thousand is . |
||
| 4473 | $amount = str_replace($dec, '.', $amount); |
||
| 4474 | } |
||
| 4475 | |||
| 4476 | return $amount; |
||
| 4477 | } |
||
| 4478 | |||
| 4479 | /** |
||
| 4480 | * Output a dimension with best unit |
||
| 4481 | * |
||
| 4482 | * @param float $dimension Dimension |
||
| 4483 | * @param int $unit Unit of dimension (0, -3, ...) |
||
| 4484 | * @param string $type 'weight', 'volume', ... |
||
| 4485 | * @param Translate $outputlangs Translate language object |
||
| 4486 | * @param int $round -1 = non rounding, x = number of decimal |
||
| 4487 | * @param string $forceunitoutput 'no' or numeric (-3, -6, ...) compared to $unit |
||
| 4488 | * @return string String to show dimensions |
||
| 4489 | */ |
||
| 4490 | static function showDimensionInBestUnit($dimension, $unit, $type, $outputlangs, $round = -1, $forceunitoutput = 'no') |
||
| 4491 | {
|
||
| 4492 | require_once DOL_BASE_PATH . '/core/lib/product.lib.php'; |
||
| 4493 | |||
| 4494 | if (($forceunitoutput == 'no' && $dimension < 1 / 10000) || (is_numeric($forceunitoutput) && $forceunitoutput == -6)) {
|
||
| 4495 | $dimension = $dimension * 1000000; |
||
| 4496 | $unit = $unit - 6; |
||
| 4497 | } elseif (($forceunitoutput == 'no' && $dimension < 1 / 10) || (is_numeric($forceunitoutput) && $forceunitoutput == -3)) {
|
||
| 4498 | $dimension = $dimension * 1000; |
||
| 4499 | $unit = $unit - 3; |
||
| 4500 | } elseif (($forceunitoutput == 'no' && $dimension > 100000000) || (is_numeric($forceunitoutput) && $forceunitoutput == 6)) {
|
||
| 4501 | $dimension = $dimension / 1000000; |
||
| 4502 | $unit = $unit + 6; |
||
| 4503 | } elseif (($forceunitoutput == 'no' && $dimension > 100000) || (is_numeric($forceunitoutput) && $forceunitoutput == 3)) {
|
||
| 4504 | $dimension = $dimension / 1000; |
||
| 4505 | $unit = $unit + 3; |
||
| 4506 | } |
||
| 4507 | |||
| 4508 | $ret = price($dimension, 0, $outputlangs, 0, 0, $round) . ' ' . measuring_units_string($unit, $type); |
||
| 4509 | |||
| 4510 | return $ret; |
||
| 4511 | } |
||
| 4512 | |||
| 4513 | /** |
||
| 4514 | * Return localtax rate for a particular vat, when selling a product with vat $vatrate, from a $thirdparty_buyer to a $thirdparty_seller |
||
| 4515 | * Note: This static function applies same rules than get_default_tva |
||
| 4516 | * |
||
| 4517 | * @param float $vatrate Vat rate. Can be '8.5' or '8.5 (VATCODEX)' for example |
||
| 4518 | * @param int $local Local tax to search and return (1 or 2 return only tax rate 1 or tax rate 2) |
||
| 4519 | * @param Societe $thirdparty_buyer Object of buying third party |
||
| 4520 | * @param Societe $thirdparty_seller Object of selling third party ($mysoc if not defined) |
||
| 4521 | * @param int $vatnpr If vat rate is NPR or not |
||
| 4522 | * @return mixed 0 if not found, localtax rate if found |
||
| 4523 | * @see get_default_tva |
||
| 4524 | */ |
||
| 4525 | static function get_localtax($vatrate, $local, $thirdparty_buyer = "", $thirdparty_seller = "", $vatnpr = 0) |
||
| 4526 | {
|
||
| 4527 | // global $db, Globals::$conf, $mysoc; |
||
| 4528 | |||
| 4529 | if (empty($thirdparty_seller) || !is_object($thirdparty_seller)) |
||
| 4530 | $thirdparty_seller = $mysoc; |
||
| 4531 | |||
| 4532 | AlDolUtils::dol_syslog("get_localtax tva=" . $vatrate . " local=" . $local . " thirdparty_buyer id=" . (is_object($thirdparty_buyer) ? $thirdparty_buyer->id : '') . "/country_code=" . (is_object($thirdparty_buyer) ? $thirdparty_buyer->country_code : '') . " thirdparty_seller id=" . $thirdparty_seller->id . "/country_code=" . $thirdparty_seller->country_code . " thirdparty_seller localtax1_assuj=" . $thirdparty_seller->localtax1_assuj . " thirdparty_seller localtax2_assuj=" . $thirdparty_seller->localtax2_assuj);
|
||
| 4533 | |||
| 4534 | $vatratecleaned = $vatrate; |
||
| 4535 | if (preg_match('/^(.*)\s*\((.*)\)$/', $vatrate, $reg)) { // If vat is "xx (yy)"
|
||
| 4536 | $vatratecleaned = trim($reg[1]); |
||
| 4537 | $vatratecode = $reg[2]; |
||
| 4538 | } |
||
| 4539 | |||
| 4540 | /* if ($thirdparty_buyer->country_code != $thirdparty_seller->country_code) |
||
| 4541 | {
|
||
| 4542 | return 0; |
||
| 4543 | } */ |
||
| 4544 | |||
| 4545 | // Some test to guess with no need to make database access |
||
| 4546 | if ($mysoc->country_code == 'ES') { // For spain localtaxes 1 and 2, tax is qualified if buyer use local tax
|
||
| 4547 | if ($local == 1) {
|
||
| 4548 | if (!$mysoc->localtax1_assuj || (string) $vatratecleaned == "0") |
||
| 4549 | return 0; |
||
| 4550 | if ($thirdparty_seller->id == $mysoc->id) {
|
||
| 4551 | if (!$thirdparty_buyer->localtax1_assuj) |
||
| 4552 | return 0; |
||
| 4553 | } |
||
| 4554 | else {
|
||
| 4555 | if (!$thirdparty_seller->localtax1_assuj) |
||
| 4556 | return 0; |
||
| 4557 | } |
||
| 4558 | } |
||
| 4559 | |||
| 4560 | if ($local == 2) {
|
||
| 4561 | //if (! $mysoc->localtax2_assuj || (string) $vatratecleaned == "0") return 0; |
||
| 4562 | if (!$mysoc->localtax2_assuj) |
||
| 4563 | return 0; // If main vat is 0, IRPF may be different than 0. |
||
| 4564 | if ($thirdparty_seller->id == $mysoc->id) {
|
||
| 4565 | if (!$thirdparty_buyer->localtax2_assuj) |
||
| 4566 | return 0; |
||
| 4567 | } |
||
| 4568 | else {
|
||
| 4569 | if (!$thirdparty_seller->localtax2_assuj) |
||
| 4570 | return 0; |
||
| 4571 | } |
||
| 4572 | } |
||
| 4573 | } |
||
| 4574 | else {
|
||
| 4575 | if ($local == 1 && !$thirdparty_seller->localtax1_assuj) |
||
| 4576 | return 0; |
||
| 4577 | if ($local == 2 && !$thirdparty_seller->localtax2_assuj) |
||
| 4578 | return 0; |
||
| 4579 | } |
||
| 4580 | |||
| 4581 | // For some country MAIN_GET_LOCALTAXES_VALUES_FROM_THIRDPARTY is forced to on. |
||
| 4582 | if (in_array($mysoc->country_code, array('ES'))) {
|
||
| 4583 | Globals::$conf->global->MAIN_GET_LOCALTAXES_VALUES_FROM_THIRDPARTY = 1; |
||
| 4584 | } |
||
| 4585 | |||
| 4586 | // Search local taxes |
||
| 4587 | if (!empty(Globals::$conf->global->MAIN_GET_LOCALTAXES_VALUES_FROM_THIRDPARTY)) {
|
||
| 4588 | if ($local == 1) {
|
||
| 4589 | if ($thirdparty_seller != $mysoc) {
|
||
| 4590 | if (!isOnlyOneLocalTax($local)) { // TODO We should provide $vatrate to search on correct line and not always on line with highest vat rate
|
||
| 4591 | return $thirdparty_seller->localtax1_value; |
||
| 4592 | } |
||
| 4593 | } else { // i am the seller
|
||
| 4594 | if (!isOnlyOneLocalTax($local)) { // TODO If seller is me, why not always returning this, even if there is only one locatax vat.
|
||
| 4595 | return Globals::$conf->global->MAIN_INFO_VALUE_LOCALTAX1; |
||
| 4596 | } |
||
| 4597 | } |
||
| 4598 | } |
||
| 4599 | if ($local == 2) {
|
||
| 4600 | if ($thirdparty_seller != $mysoc) {
|
||
| 4601 | if (!isOnlyOneLocalTax($local)) { // TODO We should provide $vatrate to search on correct line and not always on line with highest vat rate
|
||
| 4602 | // TODO We should also return value defined on thirdparty only if defined |
||
| 4603 | return $thirdparty_seller->localtax2_value; |
||
| 4604 | } |
||
| 4605 | } else { // i am the seller
|
||
| 4606 | if (in_array($mysoc->country_code, array('ES'))) {
|
||
| 4607 | return $thirdparty_buyer->localtax2_value; |
||
| 4608 | } else {
|
||
| 4609 | return Globals::$conf->global->MAIN_INFO_VALUE_LOCALTAX2; |
||
| 4610 | } |
||
| 4611 | } |
||
| 4612 | } |
||
| 4613 | } |
||
| 4614 | |||
| 4615 | // By default, search value of local tax on line of common tax |
||
| 4616 | $sql = "SELECT t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type"; |
||
| 4617 | $sql .= " FROM " . MAIN_DB_PREFIX . "c_tva as t, " . MAIN_DB_PREFIX . "c_country as c"; |
||
| 4618 | $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '" . $thirdparty_seller->country_code . "'"; |
||
| 4619 | $sql .= " AND t.taux = " . ((float) $vatratecleaned) . " AND t.active = 1"; |
||
| 4620 | if ($vatratecode) |
||
| 4621 | $sql .= " AND t.code ='" . $vatratecode . "'"; // If we have the code, we use it in priority |
||
| 4622 | else |
||
| 4623 | $sql .= " AND t.recuperableonly ='" . $vatnpr . "'"; |
||
| 4624 | AlDolUtils::dol_syslog("get_localtax", LOG_DEBUG);
|
||
| 4625 | $resql = $db->query($sql); |
||
| 4626 | |||
| 4627 | if ($resql) {
|
||
| 4628 | $obj = $db->fetch_object($resql); |
||
| 4629 | if ($local == 1) |
||
| 4630 | return $obj->localtax1; |
||
| 4631 | elseif ($local == 2) |
||
| 4632 | return $obj->localtax2; |
||
| 4633 | } |
||
| 4634 | |||
| 4635 | return 0; |
||
| 4636 | } |
||
| 4637 | |||
| 4638 | /** |
||
| 4639 | * Return true if LocalTax (1 or 2) is unique. |
||
| 4640 | * Example: If localtax1 is 5 on line with highest common vat rate, return true |
||
| 4641 | * Example: If localtax1 is 5:8:15 on line with highest common vat rate, return false |
||
| 4642 | * |
||
| 4643 | * @param int $local Local tax to test (1 or 2) |
||
| 4644 | * @return boolean True if LocalTax have multiple values, False if not |
||
| 4645 | */ |
||
| 4646 | static function isOnlyOneLocalTax($local) |
||
| 4647 | {
|
||
| 4648 | $tax = get_localtax_by_third($local); |
||
| 4649 | |||
| 4650 | $valors = explode(":", $tax);
|
||
| 4651 | |||
| 4652 | if (count($valors) > 1) {
|
||
| 4653 | return false; |
||
| 4654 | } else {
|
||
| 4655 | return true; |
||
| 4656 | } |
||
| 4657 | } |
||
| 4658 | |||
| 4659 | /** |
||
| 4660 | * Get values of localtaxes (1 or 2) for company country for the common vat with the highest value |
||
| 4661 | * |
||
| 4662 | * @param int $local LocalTax to get |
||
| 4663 | * @return number Values of localtax |
||
| 4664 | */ |
||
| 4665 | static function get_localtax_by_third($local) |
||
| 4666 | {
|
||
| 4667 | // global $db, $mysoc; |
||
| 4668 | $sql = "SELECT t.localtax1, t.localtax2 "; |
||
| 4669 | $sql .= " FROM " . MAIN_DB_PREFIX . "c_tva as t inner join " . MAIN_DB_PREFIX . "c_country as c ON c.rowid=t.fk_pays"; |
||
| 4670 | $sql .= " WHERE c.code = '" . $mysoc->country_code . "' AND t.active = 1 AND t.taux=(";
|
||
| 4671 | $sql .= " SELECT max(tt.taux) FROM " . MAIN_DB_PREFIX . "c_tva as tt inner join " . MAIN_DB_PREFIX . "c_country as c ON c.rowid=tt.fk_pays"; |
||
| 4672 | $sql .= " WHERE c.code = '" . $mysoc->country_code . "' AND tt.active = 1"; |
||
| 4673 | $sql .= " )"; |
||
| 4674 | |||
| 4675 | $resql = $db->query($sql); |
||
| 4676 | if ($resql) {
|
||
| 4677 | $obj = $db->fetch_object($resql); |
||
| 4678 | if ($local == 1) |
||
| 4679 | return $obj->localtax1; |
||
| 4680 | elseif ($local == 2) |
||
| 4681 | return $obj->localtax2; |
||
| 4682 | } |
||
| 4683 | |||
| 4684 | return 0; |
||
| 4685 | } |
||
| 4686 | |||
| 4687 | /** |
||
| 4688 | * Get vat main information from Id. |
||
| 4689 | * You can call getLocalTaxesFromRate after to get other fields. |
||
| 4690 | * |
||
| 4691 | * @param int|string $vatrate VAT ID or Rate. Value can be value or the string with code into parenthesis or rowid if $firstparamisid is 1. Example: '8.5' or '8.5 (8.5NPR)' or 123. |
||
| 4692 | * @param Societe $buyer Company object |
||
| 4693 | * @param Societe $seller Company object |
||
| 4694 | * @param int $firstparamisid 1 if first param is id into table (use this if you can) |
||
| 4695 | * @return array array('rowid'=> , 'code'=> ...)
|
||
| 4696 | * @see getLocalTaxesFromRate |
||
| 4697 | */ |
||
| 4698 | static function getTaxesFromId($vatrate, $buyer = null, $seller = null, $firstparamisid = 1) |
||
| 4699 | {
|
||
| 4700 | // global $db, $mysoc; |
||
| 4701 | |||
| 4702 | AlDolUtils::dol_syslog("getTaxesFromId vat id or rate = " . $vatrate);
|
||
| 4703 | |||
| 4704 | // Search local taxes |
||
| 4705 | $sql = "SELECT t.rowid, t.code, t.taux as rate, t.recuperableonly as npr, t.accountancy_code_sell, t.accountancy_code_buy"; |
||
| 4706 | $sql .= " FROM " . MAIN_DB_PREFIX . "c_tva as t"; |
||
| 4707 | if ($firstparamisid) |
||
| 4708 | $sql .= " WHERE t.rowid = " . (int) $vatrate; |
||
| 4709 | else {
|
||
| 4710 | $vatratecleaned = $vatrate; |
||
| 4711 | $vatratecode = ''; |
||
| 4712 | if (preg_match('/^(.*)\s*\((.*)\)$/', $vatrate, $reg)) { // If vat is "xx (yy)"
|
||
| 4713 | $vatratecleaned = $reg[1]; |
||
| 4714 | $vatratecode = $reg[2]; |
||
| 4715 | } |
||
| 4716 | |||
| 4717 | $sql .= ", " . MAIN_DB_PREFIX . "c_country as c"; |
||
| 4718 | /* if ($mysoc->country_code == 'ES') $sql.= " WHERE t.fk_pays = c.rowid AND c.code = '".$buyer->country_code."'"; // vat in spain use the buyer country ?? |
||
| 4719 | else $sql.= " WHERE t.fk_pays = c.rowid AND c.code = '".$seller->country_code."'"; */ |
||
| 4720 | $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '" . $seller->country_code . "'"; |
||
| 4721 | $sql .= " AND t.taux = " . ((float) $vatratecleaned) . " AND t.active = 1"; |
||
| 4722 | if ($vatratecode) |
||
| 4723 | $sql .= " AND t.code = '" . $vatratecode . "'"; |
||
| 4724 | } |
||
| 4725 | |||
| 4726 | $resql = $db->query($sql); |
||
| 4727 | if ($resql) {
|
||
| 4728 | $obj = $db->fetch_object($resql); |
||
| 4729 | if ($obj) |
||
| 4730 | return array('rowid' => $obj->rowid, 'code' => $obj->code, 'rate' => $obj->rate, 'npr' => $obj->npr, 'accountancy_code_sell' => $obj->accountancy_code_sell, 'accountancy_code_buy' => $obj->accountancy_code_buy);
|
||
| 4731 | else |
||
| 4732 | return array(); |
||
| 4733 | } else |
||
| 4734 | dol_print_error($db); |
||
| 4735 | |||
| 4736 | return array(); |
||
| 4737 | } |
||
| 4738 | |||
| 4739 | /** |
||
| 4740 | * Get type and rate of localtaxes for a particular vat rate/country of a thirdparty. |
||
| 4741 | * This does not take into account the seller setup if subject to vat or not, only country. |
||
| 4742 | * TODO |
||
| 4743 | * This static function is ALSO called to retrieve type for building PDF. Such call of static function must be removed. |
||
| 4744 | * Instead this static function must be called when adding a line to get the array of localtax and type, and then |
||
| 4745 | * provide it to the static function calcul_price_total. |
||
| 4746 | * |
||
| 4747 | * @param int|string $vatrate VAT ID or Rate+Code. Value can be value or the string with code into parenthesis or rowid if $firstparamisid is 1. Example: '8.5' or '8.5 (8.5NPR)' or 123. |
||
| 4748 | * @param int $local Number of localtax (1 or 2, or 0 to return 1 & 2) |
||
| 4749 | * @param Societe $buyer Company object |
||
| 4750 | * @param Societe $seller Company object |
||
| 4751 | * @param int $firstparamisid 1 if first param is ID into table instead of Rate+code (use this if you can) |
||
| 4752 | * @return array array(localtax_type1(1-6/0 if not found), rate localtax1, localtax_type2, rate localtax2, accountancycodecust, accountancycodesupp) |
||
| 4753 | * @see getTaxesFromId |
||
| 4754 | */ |
||
| 4755 | static function getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid = 0) |
||
| 4756 | {
|
||
| 4757 | // global $db, $mysoc; |
||
| 4758 | |||
| 4759 | AlDolUtils::dol_syslog("getLocalTaxesFromRate vatrate=" . $vatrate . " local=" . $local);
|
||
| 4760 | |||
| 4761 | // Search local taxes |
||
| 4762 | $sql = "SELECT t.localtax1, t.localtax1_type, t.localtax2, t.localtax2_type, t.accountancy_code_sell, t.accountancy_code_buy"; |
||
| 4763 | $sql .= " FROM " . MAIN_DB_PREFIX . "c_tva as t"; |
||
| 4764 | if ($firstparamisid) |
||
| 4765 | $sql .= " WHERE t.rowid = " . (int) $vatrate; |
||
| 4766 | else {
|
||
| 4767 | $vatratecleaned = $vatrate; |
||
| 4768 | $vatratecode = ''; |
||
| 4769 | if (preg_match('/^(.*)\s*\((.*)\)$/', $vatrate, $reg)) { // If vat is "x.x (yy)"
|
||
| 4770 | $vatratecleaned = $reg[1]; |
||
| 4771 | $vatratecode = $reg[2]; |
||
| 4772 | } |
||
| 4773 | |||
| 4774 | $sql .= ", " . MAIN_DB_PREFIX . "c_country as c"; |
||
| 4775 | if ($mysoc->country_code == 'ES') |
||
| 4776 | $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '" . $buyer->country_code . "'"; // local tax in spain use the buyer country ?? |
||
| 4777 | else |
||
| 4778 | $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '" . $seller->country_code . "'"; |
||
| 4779 | $sql .= " AND t.taux = " . ((float) $vatratecleaned) . " AND t.active = 1"; |
||
| 4780 | if ($vatratecode) |
||
| 4781 | $sql .= " AND t.code = '" . $vatratecode . "'"; |
||
| 4782 | } |
||
| 4783 | |||
| 4784 | $resql = $db->query($sql); |
||
| 4785 | if ($resql) {
|
||
| 4786 | $obj = $db->fetch_object($resql); |
||
| 4787 | if ($local == 1) {
|
||
| 4788 | return array($obj->localtax1_type, get_localtax($vatrate, $local, $buyer, $seller), $obj->accountancy_code_sell, $obj->accountancy_code_buy); |
||
| 4789 | } elseif ($local == 2) {
|
||
| 4790 | return array($obj->localtax2_type, get_localtax($vatrate, $local, $buyer, $seller), $obj->accountancy_code_sell, $obj->accountancy_code_buy); |
||
| 4791 | } else {
|
||
| 4792 | return array($obj->localtax1_type, get_localtax($vatrate, 1, $buyer, $seller), $obj->localtax2_type, get_localtax($vatrate, 2, $buyer, $seller), $obj->accountancy_code_sell, $obj->accountancy_code_buy); |
||
| 4793 | } |
||
| 4794 | } |
||
| 4795 | |||
| 4796 | return 0; |
||
| 4797 | } |
||
| 4798 | |||
| 4799 | /** |
||
| 4800 | * Return vat rate of a product in a particular selling country or default country vat if product is unknown |
||
| 4801 | * Function called by get_default_tva |
||
| 4802 | * |
||
| 4803 | * @param int $idprod Id of product or 0 if not a predefined product |
||
| 4804 | * @param Societe $thirdparty_seller Thirdparty with a ->country_code defined (FR, US, IT, ...) |
||
| 4805 | * @param int $idprodfournprice Id product_fournisseur_price (for "supplier" proposal/order/invoice) |
||
| 4806 | * @return float|string Vat rate to use with format 5.0 or '5.0 (XXX)' |
||
| 4807 | * @see get_product_localtax_for_country |
||
| 4808 | */ |
||
| 4809 | static function get_product_vat_for_country($idprod, $thirdparty_seller, $idprodfournprice = 0) |
||
| 4810 | {
|
||
| 4811 | // global $db, Globals::$conf, $mysoc; |
||
| 4812 | |||
| 4813 | require_once DOL_BASE_PATH . '/product/class/product.class.php'; |
||
| 4814 | |||
| 4815 | $ret = 0; |
||
| 4816 | $found = 0; |
||
| 4817 | |||
| 4818 | if ($idprod > 0) {
|
||
| 4819 | // Load product |
||
| 4820 | $product = new Product($db); |
||
| 4821 | $result = $product->fetch($idprod); |
||
| 4822 | |||
| 4823 | if ($mysoc->country_code == $thirdparty_seller->country_code) { // If selling country is ours
|
||
| 4824 | if ($idprodfournprice > 0) { // We want vat for product for a "supplier" object
|
||
| 4825 | $product->get_buyprice($idprodfournprice, 0, 0, 0); |
||
| 4826 | $ret = $product->vatrate_supplier; |
||
| 4827 | if ($product->default_vat_code) |
||
| 4828 | $ret .= ' (' . $product->default_vat_code . ')';
|
||
| 4829 | } |
||
| 4830 | else {
|
||
| 4831 | $ret = $product->tva_tx; // Default vat of product we defined |
||
| 4832 | if ($product->default_vat_code) |
||
| 4833 | $ret .= ' (' . $product->default_vat_code . ')';
|
||
| 4834 | } |
||
| 4835 | $found = 1; |
||
| 4836 | } |
||
| 4837 | else {
|
||
| 4838 | // TODO Read default product vat according to countrycode and product. Vat for couple countrycode/product is a feature not implemeted yet. |
||
| 4839 | // May be usefull/required if hidden option SERVICE_ARE_ECOMMERCE_200238EC is on |
||
| 4840 | } |
||
| 4841 | } |
||
| 4842 | |||
| 4843 | if (!$found) {
|
||
| 4844 | if (empty(Globals::$conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS)) {
|
||
| 4845 | // If vat of product for the country not found or not defined, we return the first higher vat of country. |
||
| 4846 | $sql = "SELECT t.taux as vat_rate, t.code as default_vat_code"; |
||
| 4847 | $sql .= " FROM " . MAIN_DB_PREFIX . "c_tva as t, " . MAIN_DB_PREFIX . "c_country as c"; |
||
| 4848 | $sql .= " WHERE t.active=1 AND t.fk_pays = c.rowid AND c.code='" . $thirdparty_seller->country_code . "'"; |
||
| 4849 | $sql .= " ORDER BY t.taux DESC, t.code ASC, t.recuperableonly ASC"; |
||
| 4850 | $sql .= $db->plimit(1); |
||
| 4851 | |||
| 4852 | $resql = $db->query($sql); |
||
| 4853 | if ($resql) {
|
||
| 4854 | $obj = $db->fetch_object($resql); |
||
| 4855 | if ($obj) {
|
||
| 4856 | $ret = $obj->vat_rate; |
||
| 4857 | if ($obj->default_vat_code) |
||
| 4858 | $ret .= ' (' . $obj->default_vat_code . ')';
|
||
| 4859 | } |
||
| 4860 | $db->free($sql); |
||
| 4861 | } else |
||
| 4862 | dol_print_error($db); |
||
| 4863 | } else |
||
| 4864 | $ret = Globals::$conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS; // Forced value if autodetect fails |
||
| 4865 | } |
||
| 4866 | |||
| 4867 | AlDolUtils::dol_syslog("get_product_vat_for_country: ret=" . $ret);
|
||
| 4868 | return $ret; |
||
| 4869 | } |
||
| 4870 | |||
| 4871 | /** |
||
| 4872 | * Return localtax vat rate of a product in a particular selling country or default country vat if product is unknown |
||
| 4873 | * |
||
| 4874 | * @param int $idprod Id of product |
||
| 4875 | * @param int $local 1 for localtax1, 2 for localtax 2 |
||
| 4876 | * @param Societe $thirdparty_seller Thirdparty with a ->country_code defined (FR, US, IT, ...) |
||
| 4877 | * @return int <0 if KO, Vat rate if OK |
||
| 4878 | * @see get_product_vat_for_country |
||
| 4879 | */ |
||
| 4880 | static function get_product_localtax_for_country($idprod, $local, $thirdparty_seller) |
||
| 4881 | {
|
||
| 4882 | // global $db, $mysoc; |
||
| 4883 | |||
| 4884 | if (!class_exists('Product')) {
|
||
| 4885 | require_once DOL_BASE_PATH . 'product/class/product.class.php'; |
||
| 4886 | } |
||
| 4887 | |||
| 4888 | $ret = 0; |
||
| 4889 | $found = 0; |
||
| 4890 | |||
| 4891 | if ($idprod > 0) {
|
||
| 4892 | // Load product |
||
| 4893 | $product = new Product($db); |
||
| 4894 | $result = $product->fetch($idprod); |
||
| 4895 | |||
| 4896 | if ($mysoc->country_code == $thirdparty_seller->country_code) { // If selling country is ours
|
||
| 4897 | /* Not defined yet, so we don't use this |
||
| 4898 | if ($local==1) $ret=$product->localtax1_tx; |
||
| 4899 | elseif ($local==2) $ret=$product->localtax2_tx; |
||
| 4900 | $found=1; |
||
| 4901 | */ |
||
| 4902 | } else {
|
||
| 4903 | // TODO Read default product vat according to countrycode and product |
||
| 4904 | } |
||
| 4905 | } |
||
| 4906 | |||
| 4907 | if (!$found) {
|
||
| 4908 | // If vat of product for the country not found or not defined, we return higher vat of country. |
||
| 4909 | $sql = "SELECT taux as vat_rate, localtax1, localtax2"; |
||
| 4910 | $sql .= " FROM " . MAIN_DB_PREFIX . "c_tva as t, " . MAIN_DB_PREFIX . "c_country as c"; |
||
| 4911 | $sql .= " WHERE t.active=1 AND t.fk_pays = c.rowid AND c.code='" . $thirdparty_seller->country_code . "'"; |
||
| 4912 | $sql .= " ORDER BY t.taux DESC, t.recuperableonly ASC"; |
||
| 4913 | $sql .= $db->plimit(1); |
||
| 4914 | |||
| 4915 | $resql = $db->query($sql); |
||
| 4916 | if ($resql) {
|
||
| 4917 | $obj = $db->fetch_object($resql); |
||
| 4918 | if ($obj) {
|
||
| 4919 | if ($local == 1) |
||
| 4920 | $ret = $obj->localtax1; |
||
| 4921 | elseif ($local == 2) |
||
| 4922 | $ret = $obj->localtax2; |
||
| 4923 | } |
||
| 4924 | } else |
||
| 4925 | dol_print_error($db); |
||
| 4926 | } |
||
| 4927 | |||
| 4928 | AlDolUtils::dol_syslog("get_product_localtax_for_country: ret=" . $ret);
|
||
| 4929 | return $ret; |
||
| 4930 | } |
||
| 4931 | |||
| 4932 | /** |
||
| 4933 | * Function that return vat rate of a product line (according to seller, buyer and product vat rate) |
||
| 4934 | * Si vendeur non assujeti a TVA, TVA par defaut=0. Fin de regle. |
||
| 4935 | * Si le (pays vendeur = pays acheteur) alors TVA par defaut=TVA du produit vendu. Fin de regle. |
||
| 4936 | * Si (vendeur et acheteur dans Communaute europeenne) et (bien vendu = moyen de transports neuf comme auto, bateau, avion) alors TVA par defaut=0 (La TVA doit etre paye par acheteur au centre d'impots de son pays et non au vendeur). Fin de regle. |
||
| 4937 | * Si (vendeur et acheteur dans Communaute europeenne) et (acheteur = particulier ou entreprise sans num TVA intra) alors TVA par defaut=TVA du produit vendu. Fin de regle |
||
| 4938 | * Si (vendeur et acheteur dans Communaute europeenne) et (acheteur = entreprise avec num TVA) intra alors TVA par defaut=0. Fin de regle |
||
| 4939 | * Sinon TVA proposee par defaut=0. Fin de regle. |
||
| 4940 | * |
||
| 4941 | * @param Societe $thirdparty_seller Objet societe vendeuse |
||
| 4942 | * @param Societe $thirdparty_buyer Objet societe acheteuse |
||
| 4943 | * @param int $idprod Id product |
||
| 4944 | * @param int $idprodfournprice Id product_fournisseur_price (for supplier order/invoice) |
||
| 4945 | * @return float|string Vat rate to use with format 5.0 or '5.0 (XXX)', -1 if we can't guess it |
||
| 4946 | * @see get_default_npr, get_default_localtax |
||
| 4947 | */ |
||
| 4948 | static function get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod = 0, $idprodfournprice = 0) |
||
| 4949 | {
|
||
| 4950 | // global Globals::$conf; |
||
| 4951 | |||
| 4952 | require_once DOL_BASE_PATH . '/core/lib/company.lib.php'; |
||
| 4953 | |||
| 4954 | // Note: possible values for tva_assuj are 0/1 or franchise/reel |
||
| 4955 | $seller_use_vat = ((is_numeric($thirdparty_seller->tva_assuj) && !$thirdparty_seller->tva_assuj) || (!is_numeric($thirdparty_seller->tva_assuj) && $thirdparty_seller->tva_assuj == 'franchise')) ? 0 : 1; |
||
| 4956 | |||
| 4957 | $seller_country_code = $thirdparty_seller->country_code; |
||
| 4958 | $seller_in_cee = isInEEC($thirdparty_seller); |
||
| 4959 | |||
| 4960 | $buyer_country_code = $thirdparty_buyer->country_code; |
||
| 4961 | $buyer_in_cee = isInEEC($thirdparty_buyer); |
||
| 4962 | |||
| 4963 | AlDolUtils::dol_syslog("get_default_tva: seller use vat=" . $seller_use_vat . ", seller country=" . $seller_country_code . ", seller in cee=" . $seller_in_cee . ", buyer vat number=" . $thirdparty_buyer->tva_intra . " buyer country=" . $buyer_country_code . ", buyer in cee=" . $buyer_in_cee . ", idprod=" . $idprod . ", idprodfournprice=" . $idprodfournprice . ", SERVICE_ARE_ECOMMERCE_200238EC=" . (!empty(Globals::$conf->global->SERVICES_ARE_ECOMMERCE_200238EC) ? Globals::$conf->global->SERVICES_ARE_ECOMMERCE_200238EC : ''));
|
||
| 4964 | |||
| 4965 | // If services are eServices according to EU Council Directive 2002/38/EC (http://ec.europa.eu/taxation_customs/taxation/vat/traders/e-commerce/article_1610_en.htm) |
||
| 4966 | // we use the buyer VAT. |
||
| 4967 | if (!empty(Globals::$conf->global->SERVICE_ARE_ECOMMERCE_200238EC)) {
|
||
| 4968 | if ($seller_in_cee && $buyer_in_cee && !$thirdparty_buyer->isACompany()) {
|
||
| 4969 | //print 'VATRULE 0'; |
||
| 4970 | return get_product_vat_for_country($idprod, $thirdparty_buyer, $idprodfournprice); |
||
| 4971 | } |
||
| 4972 | } |
||
| 4973 | |||
| 4974 | // If seller does not use VAT |
||
| 4975 | if (!$seller_use_vat) {
|
||
| 4976 | //print 'VATRULE 1'; |
||
| 4977 | return 0; |
||
| 4978 | } |
||
| 4979 | |||
| 4980 | // Le test ci-dessus ne devrait pas etre necessaire. Me signaler l'exemple du cas juridique concerne si le test suivant n'est pas suffisant. |
||
| 4981 | // Si le (pays vendeur = pays acheteur) alors la TVA par defaut=TVA du produit vendu. Fin de regle. |
||
| 4982 | if (($seller_country_code == $buyer_country_code) || (in_array($seller_country_code, array('FR,MC')) && in_array($buyer_country_code, array('FR', 'MC')))) { // Warning ->country_code not always defined
|
||
| 4983 | //print 'VATRULE 2'; |
||
| 4984 | return get_product_vat_for_country($idprod, $thirdparty_seller, $idprodfournprice); |
||
| 4985 | } |
||
| 4986 | |||
| 4987 | // Si (vendeur et acheteur dans Communaute europeenne) et (bien vendu = moyen de transports neuf comme auto, bateau, avion) alors TVA par defaut=0 (La TVA doit etre paye par l'acheteur au centre d'impots de son pays et non au vendeur). Fin de regle. |
||
| 4988 | // Not supported |
||
| 4989 | // Si (vendeur et acheteur dans Communaute europeenne) et (acheteur = entreprise) alors TVA par defaut=0. Fin de regle |
||
| 4990 | // Si (vendeur et acheteur dans Communaute europeenne) et (acheteur = particulier) alors TVA par defaut=TVA du produit vendu. Fin de regle |
||
| 4991 | if (($seller_in_cee && $buyer_in_cee)) {
|
||
| 4992 | $isacompany = $thirdparty_buyer->isACompany(); |
||
| 4993 | if ($isacompany) {
|
||
| 4994 | //print 'VATRULE 3'; |
||
| 4995 | return 0; |
||
| 4996 | } else {
|
||
| 4997 | //print 'VATRULE 4'; |
||
| 4998 | return get_product_vat_for_country($idprod, $thirdparty_seller, $idprodfournprice); |
||
| 4999 | } |
||
| 5000 | } |
||
| 5001 | |||
| 5002 | // Si (vendeur en France et acheteur hors Communaute europeenne et acheteur particulier) alors TVA par defaut=TVA du produit vendu. Fin de regle |
||
| 5003 | if (!empty(Globals::$conf->global->MAIN_USE_VAT_OF_PRODUCT_FOR_INDIVIDUAL_CUSTOMER_OUT_OF_EEC) && empty($buyer_in_cee) && !$thirdparty_buyer->isACompany()) {
|
||
| 5004 | return get_product_vat_for_country($idprod, $thirdparty_seller, $idprodfournprice); |
||
| 5005 | } |
||
| 5006 | |||
| 5007 | // Sinon la TVA proposee par defaut=0. Fin de regle. |
||
| 5008 | // Rem: Cela signifie qu'au moins un des 2 est hors Communaute europeenne et que le pays differe |
||
| 5009 | //print 'VATRULE 5'; |
||
| 5010 | return 0; |
||
| 5011 | } |
||
| 5012 | |||
| 5013 | /** |
||
| 5014 | * Fonction qui renvoie si tva doit etre tva percue recuperable |
||
| 5015 | * |
||
| 5016 | * @param Societe $thirdparty_seller Thirdparty seller |
||
| 5017 | * @param Societe $thirdparty_buyer Thirdparty buyer |
||
| 5018 | * @param int $idprod Id product |
||
| 5019 | * @param int $idprodfournprice Id supplier price for product |
||
| 5020 | * @return float 0 or 1 |
||
| 5021 | * @see get_default_tva, get_default_localtax |
||
| 5022 | */ |
||
| 5023 | static function get_default_npr(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod = 0, $idprodfournprice = 0) |
||
| 5024 | {
|
||
| 5025 | // global $db; |
||
| 5026 | |||
| 5027 | if ($idprodfournprice > 0) {
|
||
| 5028 | if (!class_exists('ProductFournisseur'))
|
||
| 5029 | require_once DOL_BASE_PATH . '/fourn/class/fournisseur.product.class.php'; |
||
| 5030 | $prodprice = new ProductFournisseur($db); |
||
| 5031 | $prodprice->fetch_product_fournisseur_price($idprodfournprice); |
||
| 5032 | return $prodprice->fourn_tva_npr; |
||
| 5033 | } |
||
| 5034 | elseif ($idprod > 0) {
|
||
| 5035 | if (!class_exists('Product'))
|
||
| 5036 | require_once DOL_BASE_PATH . 'product/class/product.class.php'; |
||
| 5037 | $prod = new Product($db); |
||
| 5038 | $prod->fetch($idprod); |
||
| 5039 | return $prod->tva_npr; |
||
| 5040 | } |
||
| 5041 | |||
| 5042 | return 0; |
||
| 5043 | } |
||
| 5044 | |||
| 5045 | /** |
||
| 5046 | * Function that return localtax of a product line (according to seller, buyer and product vat rate) |
||
| 5047 | * Si vendeur non assujeti a TVA, TVA par defaut=0. Fin de regle. |
||
| 5048 | * Si le (pays vendeur = pays acheteur) alors TVA par defaut=TVA du produit vendu. Fin de regle. |
||
| 5049 | * Sinon TVA proposee par defaut=0. Fin de regle. |
||
| 5050 | * |
||
| 5051 | * @param Societe $thirdparty_seller Thirdparty seller |
||
| 5052 | * @param Societe $thirdparty_buyer Thirdparty buyer |
||
| 5053 | * @param int $local Localtax to process (1 or 2) |
||
| 5054 | * @param int $idprod Id product |
||
| 5055 | * @return integer localtax, -1 si ne peut etre determine |
||
| 5056 | * @see get_default_tva, get_default_npr |
||
| 5057 | */ |
||
| 5058 | static function get_default_localtax($thirdparty_seller, $thirdparty_buyer, $local, $idprod = 0) |
||
| 5059 | {
|
||
| 5060 | // global $mysoc; |
||
| 5061 | |||
| 5062 | if (!is_object($thirdparty_seller)) |
||
| 5063 | return -1; |
||
| 5064 | if (!is_object($thirdparty_buyer)) |
||
| 5065 | return -1; |
||
| 5066 | |||
| 5067 | if ($local == 1) { // Localtax 1
|
||
| 5068 | if ($mysoc->country_code == 'ES') {
|
||
| 5069 | if (is_numeric($thirdparty_buyer->localtax1_assuj) && !$thirdparty_buyer->localtax1_assuj) |
||
| 5070 | return 0; |
||
| 5071 | } |
||
| 5072 | else {
|
||
| 5073 | // Si vendeur non assujeti a Localtax1, localtax1 par default=0 |
||
| 5074 | if (is_numeric($thirdparty_seller->localtax1_assuj) && !$thirdparty_seller->localtax1_assuj) |
||
| 5075 | return 0; |
||
| 5076 | if (!is_numeric($thirdparty_seller->localtax1_assuj) && $thirdparty_seller->localtax1_assuj == 'localtax1off') |
||
| 5077 | return 0; |
||
| 5078 | } |
||
| 5079 | } |
||
| 5080 | elseif ($local == 2) { //I Localtax 2
|
||
| 5081 | // Si vendeur non assujeti a Localtax2, localtax2 par default=0 |
||
| 5082 | if (is_numeric($thirdparty_seller->localtax2_assuj) && !$thirdparty_seller->localtax2_assuj) |
||
| 5083 | return 0; |
||
| 5084 | if (!is_numeric($thirdparty_seller->localtax2_assuj) && $thirdparty_seller->localtax2_assuj == 'localtax2off') |
||
| 5085 | return 0; |
||
| 5086 | } |
||
| 5087 | |||
| 5088 | if ($thirdparty_seller->country_code == $thirdparty_buyer->country_code) {
|
||
| 5089 | return get_product_localtax_for_country($idprod, $local, $thirdparty_seller); |
||
| 5090 | } |
||
| 5091 | |||
| 5092 | return 0; |
||
| 5093 | } |
||
| 5094 | |||
| 5095 | /** |
||
| 5096 | * Return yes or no in current language |
||
| 5097 | * |
||
| 5098 | * @param string $yesno Value to test (1, 'yes', 'true' or 0, 'no', 'false') |
||
| 5099 | * @param integer $case 1=Yes/No, 0=yes/no, 2=Disabled checkbox, 3=Disabled checkbox + Yes/No |
||
| 5100 | * @param int $color 0=texte only, 1=Text is formated with a color font style ('ok' or 'error'), 2=Text is formated with 'ok' color.
|
||
| 5101 | * @return string HTML string |
||
| 5102 | */ |
||
| 5103 | static function yn($yesno, $case = 1, $color = 0) |
||
| 5104 | {
|
||
| 5105 | // global Globals::$langs; |
||
| 5106 | $result = 'unknown'; |
||
| 5107 | $classname = ''; |
||
| 5108 | if ($yesno == 1 || strtolower($yesno) == 'yes' || strtolower($yesno) == 'true') { // A mettre avant test sur no a cause du == 0
|
||
| 5109 | $result = Globals::$langs->trans('yes');
|
||
| 5110 | if ($case == 1 || $case == 3) |
||
| 5111 | $result = Globals::$langs->trans("Yes");
|
||
| 5112 | if ($case == 2) |
||
| 5113 | $result = '<input type="checkbox" value="1" checked disabled>'; |
||
| 5114 | if ($case == 3) |
||
| 5115 | $result = '<input type="checkbox" value="1" checked disabled> ' . $result; |
||
| 5116 | |||
| 5117 | $classname = 'ok'; |
||
| 5118 | } |
||
| 5119 | elseif ($yesno == 0 || strtolower($yesno) == 'no' || strtolower($yesno) == 'false') {
|
||
| 5120 | $result = Globals::$langs->trans("no");
|
||
| 5121 | if ($case == 1 || $case == 3) |
||
| 5122 | $result = Globals::$langs->trans("No");
|
||
| 5123 | if ($case == 2) |
||
| 5124 | $result = '<input type="checkbox" value="0" disabled>'; |
||
| 5125 | if ($case == 3) |
||
| 5126 | $result = '<input type="checkbox" value="0" disabled> ' . $result; |
||
| 5127 | |||
| 5128 | if ($color == 2) |
||
| 5129 | $classname = 'ok'; |
||
| 5130 | else |
||
| 5131 | $classname = 'error'; |
||
| 5132 | } |
||
| 5133 | if ($color) |
||
| 5134 | return '<font class="' . $classname . '">' . $result . '</font>'; |
||
| 5135 | return $result; |
||
| 5136 | } |
||
| 5137 | |||
| 5138 | /** |
||
| 5139 | * Return a path to have a the directory according to object where files are stored. |
||
| 5140 | * New usage: Globals::$conf->module->multidir_output[$object->entity].'/'.get_exdir(0, 0, 0, 1, $object, $modulepart) |
||
| 5141 | * or: Globals::$conf->module->dir_output.'/'.get_exdir(0, 0, 0, 1, $object, $modulepart) if multidir_output not defined. |
||
| 5142 | * Example our with new usage: $object is invoice -> 'INYYMM-ABCD' |
||
| 5143 | * Example our with old usage: '015' with level 3->"0/1/5/", '015' with level 1->"5/", 'ABC-1' with level 3 ->"0/0/1/" |
||
| 5144 | * |
||
| 5145 | * @param string $num Id of object (deprecated, $object will be used in future) |
||
| 5146 | * @param int $level Level of subdirs to return (1, 2 or 3 levels). (deprecated,// global option will be used in future) |
||
| 5147 | * @param int $alpha 0=Keep number only to forge path, 1=Use alpha part afer the - (By default, use 0). (deprecated,// global option will be used in future) |
||
| 5148 | * @param int $withoutslash 0=With slash at end (except if '/', we return ''), 1=without slash at end |
||
| 5149 | * @param Object $object Object |
||
| 5150 | * @param string $modulepart Type of object ('invoice_supplier, 'donation', 'invoice', ...')
|
||
| 5151 | * @return string Dir to use ending. Example '' or '1/' or '1/2/' |
||
| 5152 | */ |
||
| 5153 | static function get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart) |
||
| 5154 | {
|
||
| 5155 | // global Globals::$conf; |
||
| 5156 | |||
| 5157 | $path = ''; |
||
| 5158 | |||
| 5159 | $arrayforoldpath = array('cheque', 'user', 'category', 'holiday', 'supplier_invoice', 'invoice_supplier', 'mailing', 'supplier_payment');
|
||
| 5160 | if (!empty(Globals::$conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) |
||
| 5161 | $arrayforoldpath[] = 'product'; |
||
| 5162 | if (!empty($level) && in_array($modulepart, $arrayforoldpath)) {
|
||
| 5163 | // This part should be removed once all code is using "get_exdir" to forge path, with all parameters provided. |
||
| 5164 | if (empty($alpha)) |
||
| 5165 | $num = preg_replace('/([^0-9])/i', '', $num);
|
||
| 5166 | else |
||
| 5167 | $num = preg_replace('/^.*\-/i', '', $num);
|
||
| 5168 | $num = substr("000" . $num, -$level);
|
||
| 5169 | if ($level == 1) |
||
| 5170 | $path = substr($num, 0, 1); |
||
| 5171 | if ($level == 2) |
||
| 5172 | $path = substr($num, 1, 1) . '/' . substr($num, 0, 1); |
||
| 5173 | if ($level == 3) |
||
| 5174 | $path = substr($num, 2, 1) . '/' . substr($num, 1, 1) . '/' . substr($num, 0, 1); |
||
| 5175 | } |
||
| 5176 | else {
|
||
| 5177 | // TODO |
||
| 5178 | // We will enhance here a common way of forging path for document storage |
||
| 5179 | // Here, object->id, object->ref and modulepart are required. |
||
| 5180 | //var_dump($modulepart); |
||
| 5181 | if (in_array($modulepart, array('thirdparty', 'contact', 'member', 'propal', 'proposal', 'commande', 'order', 'facture', 'invoice',
|
||
| 5182 | 'supplier_order', 'supplier_proposal', 'shipment', 'contract', 'expensereport'))) {
|
||
| 5183 | $path = ($object->ref ? $object->ref : $object->id); |
||
| 5184 | } |
||
| 5185 | } |
||
| 5186 | |||
| 5187 | if (empty($withoutslash) && !empty($path)) |
||
| 5188 | $path .= '/'; |
||
| 5189 | |||
| 5190 | return $path; |
||
| 5191 | } |
||
| 5192 | |||
| 5193 | /** |
||
| 5194 | * Creation of a directory (this can create recursive subdir) |
||
| 5195 | * |
||
| 5196 | * @param string $dir Directory to create (Separator must be '/'. Example: '/mydir/mysubdir') |
||
| 5197 | * @param string $dataroot Data root directory (To avoid having the data root in the loop. Using this will also lost the warning on first dir PHP has no permission when open_basedir is used) |
||
| 5198 | * @param int $newmask Mask for new file (Defaults to Globals::$conf->global->MAIN_UMASK or 0755 if unavailable). Example: '0444' |
||
| 5199 | * @return int < 0 if KO, 0 = already exists, > 0 if OK |
||
| 5200 | */ |
||
| 5201 | static function dol_mkdir($dir, $dataroot = '', $newmask = null) |
||
| 5202 | {
|
||
| 5203 | // global Globals::$conf; |
||
| 5204 | |||
| 5205 | AlDolUtils::dol_syslog("functions.lib::dol_mkdir: dir=" . $dir, LOG_INFO);
|
||
| 5206 | |||
| 5207 | $dir_osencoded = dol_osencode($dir); |
||
| 5208 | if (@is_dir($dir_osencoded)) |
||
| 5209 | return 0; |
||
| 5210 | |||
| 5211 | $nberr = 0; |
||
| 5212 | $nbcreated = 0; |
||
| 5213 | |||
| 5214 | $ccdir = ''; |
||
| 5215 | if (!empty($dataroot)) {
|
||
| 5216 | // Remove data root from loop |
||
| 5217 | $dir = str_replace($dataroot . '/', '', $dir); |
||
| 5218 | $ccdir = $dataroot . '/'; |
||
| 5219 | } |
||
| 5220 | |||
| 5221 | $cdir = explode("/", $dir);
|
||
| 5222 | $num = count($cdir); |
||
| 5223 | for ($i = 0; $i < $num; $i++) {
|
||
| 5224 | if ($i > 0) |
||
| 5225 | $ccdir .= '/' . $cdir[$i]; |
||
| 5226 | else |
||
| 5227 | $ccdir .= $cdir[$i]; |
||
| 5228 | if (preg_match("/^.:$/", $ccdir, $regs))
|
||
| 5229 | continue; // Si chemin Windows incomplet, on poursuit par rep suivant |
||
| 5230 | |||
| 5231 | |||
| 5232 | |||
| 5233 | |||
| 5234 | |||
| 5235 | |||
| 5236 | |||
| 5237 | |||
| 5238 | |||
| 5239 | |||
| 5240 | |||
| 5241 | |||
| 5242 | |||
| 5243 | |||
| 5244 | |||
| 5245 | |||
| 5246 | |||
| 5247 | |||
| 5248 | |||
| 5249 | |||
| 5250 | |||
| 5251 | |||
| 5252 | |||
| 5253 | |||
| 5254 | |||
| 5255 | |||
| 5256 | |||
| 5257 | |||
| 5258 | |||
| 5259 | |||
| 5260 | |||
| 5261 | |||
| 5262 | |||
| 5263 | |||
| 5264 | |||
| 5265 | |||
| 5266 | |||
| 5267 | |||
| 5268 | |||
| 5269 | |||
| 5270 | |||
| 5271 | |||
| 5272 | |||
| 5273 | |||
| 5274 | |||
| 5275 | |||
| 5276 | |||
| 5277 | |||
| 5278 | |||
| 5279 | |||
| 5280 | |||
| 5281 | |||
| 5282 | |||
| 5283 | // Attention, le is_dir() peut echouer bien que le rep existe. |
||
| 5284 | // (ex selon config de open_basedir) |
||
| 5285 | if ($ccdir) {
|
||
| 5286 | $ccdir_osencoded = dol_osencode($ccdir); |
||
| 5287 | if (!@is_dir($ccdir_osencoded)) {
|
||
| 5288 | AlDolUtils::dol_syslog("functions.lib::dol_mkdir: Directory '" . $ccdir . "' does not exists or is outside open_basedir PHP setting.", LOG_DEBUG);
|
||
| 5289 | |||
| 5290 | umask(0); |
||
| 5291 | $dirmaskdec = octdec($newmask); |
||
| 5292 | if (empty($newmask)) {
|
||
| 5293 | $dirmaskdec = empty(Globals::$conf->global->MAIN_UMASK) ? octdec('0755') : octdec(Globals::$conf->global->MAIN_UMASK);
|
||
| 5294 | } |
||
| 5295 | $dirmaskdec |= octdec('0111'); // Set x bit required for directories
|
||
| 5296 | if (!@mkdir($ccdir_osencoded, $dirmaskdec)) {
|
||
| 5297 | // Si le is_dir a renvoye une fausse info, alors on passe ici. |
||
| 5298 | AlDolUtils::dol_syslog("functions.lib::dol_mkdir: Fails to create directory '" . $ccdir . "' or directory already exists.", LOG_WARNING);
|
||
| 5299 | $nberr++; |
||
| 5300 | } else {
|
||
| 5301 | AlDolUtils::dol_syslog("functions.lib::dol_mkdir: Directory '" . $ccdir . "' created", LOG_DEBUG);
|
||
| 5302 | $nberr = 0; // On remet a zero car si on arrive ici, cela veut dire que les echecs precedents peuvent etre ignore |
||
| 5303 | $nbcreated++; |
||
| 5304 | } |
||
| 5305 | } else {
|
||
| 5306 | $nberr = 0; // On remet a zero car si on arrive ici, cela veut dire que les echecs precedents peuvent etre ignores |
||
| 5307 | } |
||
| 5308 | } |
||
| 5309 | } |
||
| 5310 | return ($nberr ? -$nberr : $nbcreated); |
||
| 5311 | } |
||
| 5312 | |||
| 5313 | /** |
||
| 5314 | * Return picto saying a field is required |
||
| 5315 | * |
||
| 5316 | * @return string Chaine avec picto obligatoire |
||
| 5317 | */ |
||
| 5318 | static function picto_required() |
||
| 5319 | {
|
||
| 5320 | return '<span class="fieldrequired">*</span>'; |
||
| 5321 | } |
||
| 5322 | |||
| 5323 | /** |
||
| 5324 | * Clean a string from all HTML tags and entities. |
||
| 5325 | * This static function differs from strip_tags because: |
||
| 5326 | * - <br> are replaced with \n if removelinefeed=0 or 1 |
||
| 5327 | * - if entities are found, they are decoded BEFORE the strip |
||
| 5328 | * - you can decide to convert line feed into a space |
||
| 5329 | * |
||
| 5330 | * @param string $stringtoclean String to clean |
||
| 5331 | * @param integer $removelinefeed 1=Replace all new lines by 1 space, 0=Only ending new lines are removed others are replaced with \n, 2=Ending new lines are removed but others are kept with a same number of \n than nb of <br> when there is both "...<br>\n..." |
||
| 5332 | * @param string $pagecodeto Encoding of input/output string |
||
| 5333 | * @param integer $strip_tags 0=Use internal strip, 1=Use strip_tags() php static function (bugged when text contains a < char that is not for a html tag) |
||
| 5334 | * @return string String cleaned |
||
| 5335 | * |
||
| 5336 | * @see DolUtils::dol_escape_htmltag strip_tags dol_string_onlythesehtmltags dol_string_neverthesehtmltags |
||
| 5337 | */ |
||
| 5338 | static function dol_string_nohtmltag($stringtoclean, $removelinefeed = 1, $pagecodeto = 'UTF-8', $strip_tags = 0) |
||
| 5339 | {
|
||
| 5340 | if ($removelinefeed == 2) |
||
| 5341 | $stringtoclean = preg_replace('/<br[^>]*>\n+/ims', '<br>', $stringtoclean);
|
||
| 5342 | $temp = preg_replace('/<br[^>]*>/i', "\n", $stringtoclean);
|
||
| 5343 | |||
| 5344 | if ($strip_tags) {
|
||
| 5345 | $temp = strip_tags($temp); |
||
| 5346 | } else {
|
||
| 5347 | $pattern = "/<[^<>]+>/"; |
||
| 5348 | // Exemple of $temp: <a href="/myurl" title="<u>A title</u>">0000-021</a> |
||
| 5349 | $temp = preg_replace($pattern, "", $temp); // pass 1 |
||
| 5350 | // $temp after pass 1: <a href="/myurl" title="A title">0000-021 |
||
| 5351 | $temp = preg_replace($pattern, "", $temp); // pass 2 |
||
| 5352 | // $temp after pass 2: 0000-021 |
||
| 5353 | } |
||
| 5354 | |||
| 5355 | $temp = dol_html_entity_decode($temp, ENT_COMPAT, $pagecodeto); |
||
| 5356 | |||
| 5357 | // Supprime aussi les retours |
||
| 5358 | if ($removelinefeed == 1) |
||
| 5359 | $temp = str_replace(array("\r\n", "\r", "\n"), " ", $temp);
|
||
| 5360 | |||
| 5361 | // et les espaces doubles |
||
| 5362 | while (strpos($temp, " ")) {
|
||
| 5363 | $temp = str_replace(" ", " ", $temp);
|
||
| 5364 | } |
||
| 5365 | |||
| 5366 | return trim($temp); |
||
| 5367 | } |
||
| 5368 | |||
| 5369 | /** |
||
| 5370 | * Clean a string to keep only desirable HTML tags. |
||
| 5371 | * |
||
| 5372 | * @param string $stringtoclean String to clean |
||
| 5373 | * @return string String cleaned |
||
| 5374 | * |
||
| 5375 | * @see DolUtils::dol_escape_htmltag strip_tags dol_string_nohtmltag dol_string_neverthesehtmltags |
||
| 5376 | */ |
||
| 5377 | static function dol_string_onlythesehtmltags($stringtoclean) |
||
| 5378 | {
|
||
| 5379 | $allowed_tags = array( |
||
| 5380 | "html", "head", "meta", "body", "article", "a", "b", "br", "div", "em", "font", "img", "ins", "hr", "i", "li", "link", |
||
| 5381 | "ol", "p", "s", "section", "span", "strong", "title", |
||
| 5382 | "table", "tr", "th", "td", "u", "ul" |
||
| 5383 | ); |
||
| 5384 | |||
| 5385 | $allowed_tags_string = join("><", $allowed_tags);
|
||
| 5386 | $allowed_tags_string = preg_replace('/^>/', '', $allowed_tags_string);
|
||
| 5387 | $allowed_tags_string = preg_replace('/<$/', '', $allowed_tags_string);
|
||
| 5388 | |||
| 5389 | $temp = strip_tags($stringtoclean, $allowed_tags_string); |
||
| 5390 | |||
| 5391 | return $temp; |
||
| 5392 | } |
||
| 5393 | |||
| 5394 | /** |
||
| 5395 | * Clean a string from some undesirable HTML tags. |
||
| 5396 | * |
||
| 5397 | * @param string $stringtoclean String to clean |
||
| 5398 | * @param array $disallowed_tags Array of tags not allowed |
||
| 5399 | * @return string String cleaned |
||
| 5400 | * |
||
| 5401 | * @see DolUtils::dol_escape_htmltag strip_tags dol_string_nohtmltag dol_string_onlythesehtmltags |
||
| 5402 | */ |
||
| 5403 | static function dol_string_neverthesehtmltags($stringtoclean, $disallowed_tags = array('textarea'))
|
||
| 5404 | {
|
||
| 5405 | $temp = $stringtoclean; |
||
| 5406 | foreach ($disallowed_tags as $tagtoremove) {
|
||
| 5407 | $temp = preg_replace('/<\/?' . $tagtoremove . '>/', '', $temp);
|
||
| 5408 | $temp = preg_replace('/<\/?' . $tagtoremove . '\s+[^>]*>/', '', $temp);
|
||
| 5409 | } |
||
| 5410 | return $temp; |
||
| 5411 | } |
||
| 5412 | |||
| 5413 | /** |
||
| 5414 | * Return first line of text. Cut will depends if content is HTML or not. |
||
| 5415 | * |
||
| 5416 | * @param string $text Input text |
||
| 5417 | * @param int $nboflines Nb of lines to get (default is 1 = first line only) |
||
| 5418 | * @return string Output text |
||
| 5419 | * @see dol_nboflines_bis, dol_string_nohtmltag, AlDolUtils::dol_escape_htmltag |
||
| 5420 | */ |
||
| 5421 | static function dolGetFirstLineOfText($text, $nboflines = 1) |
||
| 5422 | {
|
||
| 5423 | if ($nboflines == 1) {
|
||
| 5424 | if (AlDolUtils::dol_textishtml($text)) {
|
||
| 5425 | $firstline = preg_replace('/<br[^>]*>.*$/s', '', $text); // The s pattern modifier means the . can match newline characters
|
||
| 5426 | $firstline = preg_replace('/<div[^>]*>.*$/s', '', $firstline); // The s pattern modifier means the . can match newline characters
|
||
| 5427 | } else {
|
||
| 5428 | $firstline = preg_replace('/[\n\r].*/', '', $text);
|
||
| 5429 | } |
||
| 5430 | return $firstline . ((strlen($firstline) != strlen($text)) ? '...' : ''); |
||
| 5431 | } else {
|
||
| 5432 | $ishtml = 0; |
||
| 5433 | if (AlDolUtils::dol_textishtml($text)) {
|
||
| 5434 | $text = preg_replace('/\n/', '', $text);
|
||
| 5435 | $ishtml = 1; |
||
| 5436 | $repTable = array("\t" => " ", "\n" => " ", "\r" => " ", "\0" => " ", "\x0B" => " ");
|
||
| 5437 | } else {
|
||
| 5438 | $repTable = array("\t" => " ", "\n" => "<br>", "\r" => " ", "\0" => " ", "\x0B" => " ");
|
||
| 5439 | } |
||
| 5440 | |||
| 5441 | $text = strtr($text, $repTable); |
||
| 5442 | if ($charset == 'UTF-8') {
|
||
| 5443 | $pattern = '/(<br[^>]*>)/Uu'; |
||
| 5444 | } // /U is to have UNGREEDY regex to limit to one html tag. /u is for UTF8 support |
||
| 5445 | else |
||
| 5446 | $pattern = '/(<br[^>]*>)/U'; // /U is to have UNGREEDY regex to limit to one html tag. |
||
| 5447 | $a = preg_split($pattern, $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); |
||
| 5448 | |||
| 5449 | $firstline = ''; |
||
| 5450 | $i = 0; |
||
| 5451 | $nba = count($a); // 2x nb of lines in $a because $a contains also a line for each new line separator |
||
| 5452 | while (($i < $nba) && ($i < ($nboflines * 2))) {
|
||
| 5453 | if ($i % 2 == 0) |
||
| 5454 | $firstline .= $a[$i]; |
||
| 5455 | elseif (($i < (($nboflines * 2) - 1)) && ($i < ($nba - 1))) |
||
| 5456 | $firstline .= ($ishtml ? "<br>\n" : "\n"); |
||
| 5457 | $i++; |
||
| 5458 | } |
||
| 5459 | unset($a); |
||
| 5460 | return $firstline . (($i < $nba) ? '...' : ''); |
||
| 5461 | } |
||
| 5462 | } |
||
| 5463 | |||
| 5464 | /** |
||
| 5465 | * Replace CRLF in string with a HTML BR tag |
||
| 5466 | * |
||
| 5467 | * @param string $stringtoencode String to encode |
||
| 5468 | * @param int $nl2brmode 0=Adding br before \n, 1=Replacing \n by br |
||
| 5469 | * @param bool $forxml false=Use <br>, true=Use <br /> |
||
| 5470 | * @return string String encoded |
||
| 5471 | * @see dol_nboflines, dolGetFirstLineOfText |
||
| 5472 | */ |
||
| 5473 | static function dol_nl2br($stringtoencode, $nl2brmode = 0, $forxml = false) |
||
| 5474 | {
|
||
| 5475 | if (!$nl2brmode) {
|
||
| 5476 | return nl2br($stringtoencode, $forxml); |
||
| 5477 | } else {
|
||
| 5478 | $ret = preg_replace('/(\r\n|\r|\n)/i', ($forxml ? '<br />' : '<br>'), $stringtoencode);
|
||
| 5479 | return $ret; |
||
| 5480 | } |
||
| 5481 | } |
||
| 5482 | |||
| 5483 | /** |
||
| 5484 | * This static function is called to encode a string into a HTML string but differs from htmlentities because |
||
| 5485 | * a detection is done before to see if text is already HTML or not. Also, all entities but &,<,> are converted. |
||
| 5486 | * This permits to encode special chars to entities with no double encoding for already encoded HTML strings. |
||
| 5487 | * This static function also remove last EOL or BR if $removelasteolbr=1 (default). |
||
| 5488 | * For PDF usage, you can show text by 2 ways: |
||
| 5489 | * - writeHTMLCell -> param must be encoded into HTML. |
||
| 5490 | * - MultiCell -> param must not be encoded into HTML. |
||
| 5491 | * Because writeHTMLCell convert also \n into <br>, if function |
||
| 5492 | * is used to build PDF, nl2brmode must be 1. |
||
| 5493 | * |
||
| 5494 | * @param string $stringtoencode String to encode |
||
| 5495 | * @param int $nl2brmode 0=Adding br before \n, 1=Replacing \n by br (for use with FPDF writeHTMLCell static function for example) |
||
| 5496 | * @param string $pagecodefrom Pagecode stringtoencode is encoded |
||
| 5497 | * @param int $removelasteolbr 1=Remove last br or lasts \n (default), 0=Do nothing |
||
| 5498 | * @return string String encoded |
||
| 5499 | */ |
||
| 5500 | static function dol_htmlentitiesbr($stringtoencode, $nl2brmode = 0, $pagecodefrom = 'UTF-8', $removelasteolbr = 1) |
||
| 5501 | {
|
||
| 5502 | $newstring = $stringtoencode; |
||
| 5503 | if (AlDolUtils::dol_textishtml($stringtoencode)) { // Check if text is already HTML or not
|
||
| 5504 | $newstring = preg_replace('/<br(\s[\sa-zA-Z_="]*)?\/?>/i', '<br>', $newstring); // Replace "<br type="_moz" />" by "<br>". It's same and avoid pb with FPDF.
|
||
| 5505 | if ($removelasteolbr) |
||
| 5506 | $newstring = preg_replace('/<br>$/i', '', $newstring); // Remove last <br> (remove only last one)
|
||
| 5507 | $newstring = strtr($newstring, array('&' => '__and__', '<' => '__lt__', '>' => '__gt__', '"' => '__dquot__'));
|
||
| 5508 | $newstring = AlDolUtils::dol_htmlentities($newstring, ENT_COMPAT, $pagecodefrom); // Make entity encoding |
||
| 5509 | $newstring = strtr($newstring, array('__and__' => '&', '__lt__' => '<', '__gt__' => '>', '__dquot__' => '"'));
|
||
| 5510 | } |
||
| 5511 | else {
|
||
| 5512 | if ($removelasteolbr) |
||
| 5513 | $newstring = preg_replace('/(\r\n|\r|\n)$/i', '', $newstring); // Remove last \n (may remove several)
|
||
| 5514 | $newstring = dol_nl2br(AlDolUtils::dol_htmlentities($newstring, ENT_COMPAT, $pagecodefrom), $nl2brmode); |
||
| 5515 | } |
||
| 5516 | // Other substitutions that htmlentities does not do |
||
| 5517 | //$newstring=str_replace(chr(128),'€',$newstring); // 128 = 0x80. Not in html entity table. // Seems useles with TCPDF. Make bug with UTF8 languages |
||
| 5518 | return $newstring; |
||
| 5519 | } |
||
| 5520 | |||
| 5521 | /** |
||
| 5522 | * This static function is called to decode a HTML string (it decodes entities and br tags) |
||
| 5523 | * |
||
| 5524 | * @param string $stringtodecode String to decode |
||
| 5525 | * @param string $pagecodeto Page code for result |
||
| 5526 | * @return string String decoded |
||
| 5527 | */ |
||
| 5528 | static function dol_htmlentitiesbr_decode($stringtodecode, $pagecodeto = 'UTF-8') |
||
| 5529 | {
|
||
| 5530 | $ret = dol_html_entity_decode($stringtodecode, ENT_COMPAT, $pagecodeto); |
||
| 5531 | $ret = preg_replace('/' . "\r\n" . '<br(\s[\sa-zA-Z_="]*)?\/?>/i', "<br>", $ret);
|
||
| 5532 | $ret = preg_replace('/<br(\s[\sa-zA-Z_="]*)?\/?>' . "\r\n" . '/i', "\r\n", $ret);
|
||
| 5533 | $ret = preg_replace('/<br(\s[\sa-zA-Z_="]*)?\/?>' . "\n" . '/i', "\n", $ret);
|
||
| 5534 | $ret = preg_replace('/<br(\s[\sa-zA-Z_="]*)?\/?>/i', "\n", $ret);
|
||
| 5535 | return $ret; |
||
| 5536 | } |
||
| 5537 | |||
| 5538 | /** |
||
| 5539 | * This static function remove all ending \n and br at end |
||
| 5540 | * |
||
| 5541 | * @param string $stringtodecode String to decode |
||
| 5542 | * @return string String decoded |
||
| 5543 | */ |
||
| 5544 | static function dol_htmlcleanlastbr($stringtodecode) |
||
| 5545 | {
|
||
| 5546 | $ret = preg_replace('/(<br>|<br(\s[\sa-zA-Z_="]*)?\/?>|' . "\n" . '|' . "\r" . ')+$/i', "", $stringtodecode);
|
||
| 5547 | return $ret; |
||
| 5548 | } |
||
| 5549 | |||
| 5550 | /** |
||
| 5551 | * Replace html_entity_decode functions to manage errors |
||
| 5552 | * |
||
| 5553 | * @param string $a Operand a |
||
| 5554 | * @param string $b Operand b (ENT_QUOTES=convert simple and double quotes) |
||
| 5555 | * @param string $c Operand c |
||
| 5556 | * @return string String decoded |
||
| 5557 | */ |
||
| 5558 | static function dol_html_entity_decode($a, $b, $c = 'UTF-8') |
||
| 5559 | {
|
||
| 5560 | return html_entity_decode($a, $b, $c); |
||
| 5561 | } |
||
| 5562 | |||
| 5563 | /** |
||
| 5564 | * Replace htmlentities functions. |
||
| 5565 | * Goal of this static function is to be sure to have default values of htmlentities that match what we need. |
||
| 5566 | * |
||
| 5567 | * @param string $string The input string to encode |
||
| 5568 | * @param int $flags Flags (see PHP doc above) |
||
| 5569 | * @param string $encoding Encoding page code |
||
| 5570 | * @param bool $double_encode When double_encode is turned off, PHP will not encode existing html entities |
||
| 5571 | * @return string $ret Encoded string |
||
| 5572 | */ |
||
| 5573 | static function dol_htmlentities($string, $flags = null, $encoding = 'UTF-8', $double_encode = false) |
||
| 5574 | {
|
||
| 5575 | return htmlentities($string, $flags, $encoding, $double_encode); |
||
| 5576 | } |
||
| 5577 | |||
| 5578 | /** |
||
| 5579 | * Check if a string is a correct iso string |
||
| 5580 | * If not, it will we considered not HTML encoded even if it is by FPDF. |
||
| 5581 | * Example, if string contains euro symbol that has ascii code 128 |
||
| 5582 | * |
||
| 5583 | * @param string $s String to check |
||
| 5584 | * @return int 0 if bad iso, 1 if good iso |
||
| 5585 | */ |
||
| 5586 | static function dol_string_is_good_iso($s) |
||
| 5587 | {
|
||
| 5588 | $len = AlDolUtils::dol_strlen($s); |
||
| 5589 | $ok = 1; |
||
| 5590 | for ($scursor = 0; $scursor < $len; $scursor++) {
|
||
| 5591 | $ordchar = ord($s{$scursor});
|
||
| 5592 | //print $scursor.'-'.$ordchar.'<br>'; |
||
| 5593 | if ($ordchar < 32 && $ordchar != 13 && $ordchar != 10) {
|
||
| 5594 | $ok = 0; |
||
| 5595 | break; |
||
| 5596 | } |
||
| 5597 | if ($ordchar > 126 && $ordchar < 160) {
|
||
| 5598 | $ok = 0; |
||
| 5599 | break; |
||
| 5600 | } |
||
| 5601 | } |
||
| 5602 | return $ok; |
||
| 5603 | } |
||
| 5604 | |||
| 5605 | /** |
||
| 5606 | * Return nb of lines of a clear text |
||
| 5607 | * |
||
| 5608 | * @param string $s String to check |
||
| 5609 | * @param int $maxchar Not yet used |
||
| 5610 | * @return int Number of lines |
||
| 5611 | * @see dol_nboflines_bis, dolGetFirstLineOfText |
||
| 5612 | */ |
||
| 5613 | static function dol_nboflines($s, $maxchar = 0) |
||
| 5621 | } |
||
| 5622 | |||
| 5623 | /** |
||
| 5624 | * Return nb of lines of a formated text with \n and <br> (WARNING: string must not have mixed \n and br separators) |
||
| 5625 | * |
||
| 5626 | * @param string $text Text |
||
| 5627 | * @param int $maxlinesize Largeur de ligne en caracteres (ou 0 si pas de limite - defaut) |
||
| 5628 | * @param string $charset Give the charset used to encode the $text variable in memory. |
||
| 5629 | * @return int Number of lines |
||
| 5630 | * @see dol_nboflines, dolGetFirstLineOfText |
||
| 5631 | */ |
||
| 5632 | static function dol_nboflines_bis($text, $maxlinesize = 0, $charset = 'UTF-8') |
||
| 5633 | {
|
||
| 5634 | $repTable = array("\t" => " ", "\n" => "<br>", "\r" => " ", "\0" => " ", "\x0B" => " ");
|
||
| 5635 | if (AlDolUtils::dol_textishtml($text)) |
||
| 5636 | $repTable = array("\t" => " ", "\n" => " ", "\r" => " ", "\0" => " ", "\x0B" => " ");
|
||
| 5637 | |||
| 5638 | $text = strtr($text, $repTable); |
||
| 5639 | if ($charset == 'UTF-8') {
|
||
| 5640 | $pattern = '/(<br[^>]*>)/Uu'; |
||
| 5641 | } // /U is to have UNGREEDY regex to limit to one html tag. /u is for UTF8 support |
||
| 5642 | else |
||
| 5643 | $pattern = '/(<br[^>]*>)/U'; // /U is to have UNGREEDY regex to limit to one html tag. |
||
| 5644 | $a = preg_split($pattern, $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); |
||
| 5645 | |||
| 5646 | $nblines = (int) floor((count($a) + 1) / 2); |
||
| 5647 | // count possible auto line breaks |
||
| 5648 | if ($maxlinesize) {
|
||
| 5649 | foreach ($a as $line) {
|
||
| 5650 | if (AlDolUtils::dol_strlen($line) > $maxlinesize) {
|
||
| 5651 | //$line_dec = html_entity_decode(strip_tags($line)); |
||
| 5652 | $line_dec = html_entity_decode($line); |
||
| 5653 | if (AlDolUtils::dol_strlen($line_dec) > $maxlinesize) {
|
||
| 5654 | $line_dec = wordwrap($line_dec, $maxlinesize, '\n', true); |
||
| 5655 | $nblines += substr_count($line_dec, '\n'); |
||
| 5656 | } |
||
| 5657 | } |
||
| 5658 | } |
||
| 5659 | } |
||
| 5660 | |||
| 5661 | unset($a); |
||
| 5662 | return $nblines; |
||
| 5663 | } |
||
| 5664 | |||
| 5665 | /** |
||
| 5666 | * Same static function than microtime in PHP 5 but compatible with PHP4 |
||
| 5667 | * |
||
| 5668 | * @return float Time (millisecondes) with microsecondes in decimal part |
||
| 5669 | * @deprecated Dolibarr does not support PHP4, you should use native function |
||
| 5670 | * @see microtime() |
||
| 5671 | */ |
||
| 5672 | static function dol_microtime_float() |
||
| 5677 | } |
||
| 5678 | |||
| 5679 | /** |
||
| 5680 | * Return if a text is a html content |
||
| 5681 | * |
||
| 5682 | * @param string $msg Content to check |
||
| 5683 | * @param int $option 0=Full detection, 1=Fast check |
||
| 5684 | * @return boolean true/false |
||
| 5685 | * @see dol_concatdesc |
||
| 5686 | */ |
||
| 5687 | static function dol_textishtml($msg, $option = 0) |
||
| 5688 | {
|
||
| 5689 | if ($option == 1) {
|
||
| 5690 | if (preg_match('/<html/i', $msg))
|
||
| 5691 | return true; |
||
| 5692 | elseif (preg_match('/<body/i', $msg))
|
||
| 5693 | return true; |
||
| 5694 | elseif (preg_match('/<br/i', $msg))
|
||
| 5695 | return true; |
||
| 5696 | return false; |
||
| 5697 | } |
||
| 5698 | else {
|
||
| 5699 | if (preg_match('/<html/i', $msg))
|
||
| 5700 | return true; |
||
| 5701 | elseif (preg_match('/<body/i', $msg))
|
||
| 5702 | return true; |
||
| 5703 | elseif (preg_match('/<(b|em|i|u)>/i', $msg))
|
||
| 5704 | return true; |
||
| 5705 | elseif (preg_match('/<br\/>/i', $msg))
|
||
| 5706 | return true; |
||
| 5707 | elseif (preg_match('/<(br|div|font|li|p|span|strong|table)>/i', $msg))
|
||
| 5708 | return true; |
||
| 5709 | elseif (preg_match('/<(br|div|font|li|p|span|strong|table)\s+[^<>\/]*>/i', $msg))
|
||
| 5710 | return true; |
||
| 5711 | elseif (preg_match('/<(br|div|font|li|p|span|strong|table)\s+[^<>\/]*\/>/i', $msg))
|
||
| 5712 | return true; |
||
| 5713 | elseif (preg_match('/<img\s+[^<>]*src[^<>]*>/i', $msg))
|
||
| 5714 | return true; // must accept <img src="http://example.com/aaa.png" /> |
||
| 5715 | elseif (preg_match('/<a\s+[^<>]*href[^<>]*>/i', $msg))
|
||
| 5716 | return true; // must accept <a href="http://example.com/aaa.png" /> |
||
| 5717 | elseif (preg_match('/<h[0-9]>/i', $msg))
|
||
| 5718 | return true; |
||
| 5719 | elseif (preg_match('/&[A-Z0-9]{1,6};/i', $msg))
|
||
| 5720 | return true; // Html entities names (http://www.w3schools.com/tags/ref_entities.asp) |
||
| 5721 | elseif (preg_match('/&#[0-9]{2,3};/i', $msg))
|
||
| 5722 | return true; // Html entities numbers (http://www.w3schools.com/tags/ref_entities.asp) |
||
| 5723 | |||
| 5724 | return false; |
||
| 5725 | } |
||
| 5726 | } |
||
| 5727 | |||
| 5728 | /** |
||
| 5729 | * Concat 2 descriptions with a new line between them (second operand after first one with appropriate new line separator) |
||
| 5730 | * text1 html + text2 html => text1 + '<br>' + text2 |
||
| 5731 | * text1 html + text2 txt => text1 + '<br>' + dol_nl2br(text2) |
||
| 5732 | * text1 txt + text2 html => dol_nl2br(text1) + '<br>' + text2 |
||
| 5733 | * text1 txt + text2 txt => text1 + '\n' + text2 |
||
| 5734 | * |
||
| 5735 | * @param string $text1 Text 1 |
||
| 5736 | * @param string $text2 Text 2 |
||
| 5737 | * @param bool $forxml false=Use <br>instead of \n if html content detected, true=Use <br /> instead of \n if html content detected |
||
| 5738 | * @param bool $invert invert order of description lines if CONF CHANGE_ORDER_CONCAT_DESCRIPTION is active |
||
| 5739 | * @return string Text 1 + new line + Text2 |
||
| 5740 | * @see AlDolUtils::dol_textishtml |
||
| 5741 | */ |
||
| 5742 | static function dol_concatdesc($text1, $text2, $forxml = false, $invert = false) |
||
| 5743 | {
|
||
| 5744 | if (!empty($invert)) {
|
||
| 5745 | $tmp = $text1; |
||
| 5746 | $text1 = $text2; |
||
| 5747 | $text2 = $tmp; |
||
| 5748 | } |
||
| 5749 | |||
| 5750 | $ret = ''; |
||
| 5751 | $ret .= (!DolUtils::dol_textishtml($text1) && AlDolUtils::dol_textishtml($text2)) ? dol_nl2br($text1, 0, $forxml) : $text1; |
||
| 5752 | $ret .= (!empty($text1) && !empty($text2)) ? ((AlDolUtils::dol_textishtml($text1) || AlDolUtils::dol_textishtml($text2)) ? ($forxml ? "<br \>\n" : "<br>\n") : "\n") : ""; |
||
| 5753 | $ret .= (AlDolUtils::dol_textishtml($text1) && !DolUtils::dol_textishtml($text2)) ? dol_nl2br($text2, 0, $forxml) : $text2; |
||
| 5754 | return $ret; |
||
| 5755 | } |
||
| 5756 | |||
| 5757 | /** |
||
| 5758 | * Return array of possible common substitutions. This includes several families like: 'system', 'mycompany', 'object', 'objectamount', 'date', 'user' |
||
| 5759 | * |
||
| 5760 | * @param Translate $outputlangs Output language |
||
| 5761 | * @param int $onlykey 1=Do not calculate some heavy values of keys (performance enhancement when we need only the keys), 2=Values are trunc and html sanitized (to use for help tooltip) |
||
| 5762 | * @param array $exclude Array of family keys we want to exclude. For example array('system', 'mycompany', 'object', 'objectamount', 'date', 'user', ...)
|
||
| 5763 | * @param Object $object Object for keys on object |
||
| 5764 | * @return array Array of substitutions |
||
| 5765 | * @see setSubstitFromObject |
||
| 5766 | */ |
||
| 5767 | static function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, $object = null) |
||
| 5768 | {
|
||
| 5769 | // global $db, Globals::$conf, $mysoc, $user, $extrafields; |
||
| 5770 | |||
| 5771 | $substitutionarray = array(); |
||
| 5772 | |||
| 5773 | if (empty($exclude) || !in_array('user', $exclude)) {
|
||
| 5774 | // Add SIGNATURE into substitutionarray first, so, when we will make the substitution, |
||
| 5775 | // this will include signature content first and then replace var found into content of signature |
||
| 5776 | $signature = $user->signature; |
||
| 5777 | $substitutionarray = array_merge($substitutionarray, array( |
||
| 5778 | '__USER_SIGNATURE__' => (string) (($signature && empty(Globals::$conf->global->MAIN_MAIL_DO_NOT_USE_SIGN)) ? ($onlykey == 2 ? dol_trunc(dol_string_nohtmltag($signature), 30) : $signature) : '') |
||
| 5779 | ) |
||
| 5780 | ); |
||
| 5781 | // For backward compatibility |
||
| 5782 | if ($onlykey != 2) {
|
||
| 5783 | $substitutionarray['__SIGNATURE__'] = (string) (($signature && empty(Globals::$conf->global->MAIN_MAIL_DO_NOT_USE_SIGN)) ? ($onlykey == 2 ? dol_trunc(dol_string_nohtmltag($signature), 30) : $signature) : ''); |
||
| 5784 | } |
||
| 5785 | |||
| 5786 | $substitutionarray = array_merge($substitutionarray, array( |
||
| 5787 | '__USER_ID__' => (string) $user->id, |
||
| 5788 | '__USER_LOGIN__' => (string) $user->login, |
||
| 5789 | '__USER_LASTNAME__' => (string) $user->lastname, |
||
| 5790 | '__USER_FIRSTNAME__' => (string) $user->firstname, |
||
| 5791 | '__USER_FULLNAME__' => (string) $user->getFullName($outputlangs), |
||
| 5792 | '__USER_SUPERVISOR_ID__' => (string) ($user->fk_user ? $user->fk_user : '0'), |
||
| 5793 | '__USER_REMOTE_IP__' => (string) getUserRemoteIP() |
||
| 5794 | ) |
||
| 5795 | ); |
||
| 5796 | } |
||
| 5797 | if ((empty($exclude) || !in_array('mycompany', $exclude)) && is_object($mysoc)) {
|
||
| 5798 | $substitutionarray = array_merge($substitutionarray, array( |
||
| 5799 | '__MYCOMPANY_NAME__' => $mysoc->name, |
||
| 5800 | '__MYCOMPANY_EMAIL__' => $mysoc->email, |
||
| 5801 | '__MYCOMPANY_PROFID1__' => $mysoc->idprof1, |
||
| 5802 | '__MYCOMPANY_PROFID2__' => $mysoc->idprof2, |
||
| 5803 | '__MYCOMPANY_PROFID3__' => $mysoc->idprof3, |
||
| 5804 | '__MYCOMPANY_PROFID4__' => $mysoc->idprof4, |
||
| 5805 | '__MYCOMPANY_PROFID5__' => $mysoc->idprof5, |
||
| 5806 | '__MYCOMPANY_PROFID6__' => $mysoc->idprof6, |
||
| 5807 | '__MYCOMPANY_CAPITAL__' => $mysoc->capital, |
||
| 5808 | '__MYCOMPANY_FULLADDRESS__' => $mysoc->getFullAddress(1, ', '), |
||
| 5809 | '__MYCOMPANY_ADDRESS__' => $mysoc->address, |
||
| 5810 | '__MYCOMPANY_ZIP__' => $mysoc->zip, |
||
| 5811 | '__MYCOMPANY_TOWN__' => $mysoc->town, |
||
| 5812 | '__MYCOMPANY_COUNTRY__' => $mysoc->country, |
||
| 5813 | '__MYCOMPANY_COUNTRY_ID__' => $mysoc->country_id, |
||
| 5814 | '__MYCOMPANY_CURRENCY_CODE__' => Globals::$conf->currency |
||
| 5815 | )); |
||
| 5816 | } |
||
| 5817 | |||
| 5818 | if (($onlykey || is_object($object)) && (empty($exclude) || !in_array('object', $exclude))) {
|
||
| 5819 | if ($onlykey) {
|
||
| 5820 | $substitutionarray['__ID__'] = '__ID__'; |
||
| 5821 | $substitutionarray['__REF__'] = '__REF__'; |
||
| 5822 | $substitutionarray['__REFCLIENT__'] = '__REFCLIENT__'; |
||
| 5823 | $substitutionarray['__REFSUPPLIER__'] = '__REFSUPPLIER__'; |
||
| 5824 | $substitutionarray['__EXTRAFIELD_XXX__'] = '__EXTRAFIELD_XXX__'; |
||
| 5825 | |||
| 5826 | $substitutionarray['__THIRDPARTY_ID__'] = '__THIRDPARTY_ID__'; |
||
| 5827 | $substitutionarray['__THIRDPARTY_NAME__'] = '__THIRDPARTY_NAME__'; |
||
| 5828 | $substitutionarray['__THIRDPARTY_NAME_ALIAS__'] = '__THIRDPARTY_NAME_ALIAS__'; |
||
| 5829 | $substitutionarray['__THIRDPARTY_EMAIL__'] = '__THIRDPARTY_EMAIL__'; |
||
| 5830 | |||
| 5831 | if (is_object($object) && $object->element == 'member') {
|
||
| 5832 | $substitutionarray['__MEMBER_ID__'] = '__MEMBER_ID__'; |
||
| 5833 | $substitutionarray['__MEMBER_CIVILITY__'] = '__MEMBER_CIVILITY__'; |
||
| 5834 | $substitutionarray['__MEMBER_FIRSTNAME__'] = '__MEMBER_FIRSTNAME__'; |
||
| 5835 | $substitutionarray['__MEMBER_LASTNAME__'] = '__MEMBER_LASTNAME__'; |
||
| 5836 | } |
||
| 5837 | $substitutionarray['__PROJECT_ID__'] = '__PROJECT_ID__'; |
||
| 5838 | $substitutionarray['__PROJECT_REF__'] = '__PROJECT_REF__'; |
||
| 5839 | $substitutionarray['__PROJECT_NAME__'] = '__PROJECT_NAME__'; |
||
| 5840 | |||
| 5841 | $substitutionarray['__CONTRACT_HIGHEST_PLANNED_START_DATE__'] = 'Highest date planned for a service start'; |
||
| 5842 | $substitutionarray['__CONTRACT_HIGHEST_PLANNED_START_DATETIME__'] = 'Highest date and hour planned for service start'; |
||
| 5843 | $substitutionarray['__CONTRACT_LOWEST_EXPIRATION_DATE__'] = 'Lowest data for planned expiration of service'; |
||
| 5844 | $substitutionarray['__CONTRACT_LOWEST_EXPIRATION_DATETIME__'] = 'Lowest date and hour for planned expiration of service'; |
||
| 5845 | |||
| 5846 | $substitutionarray['__ONLINE_PAYMENT_URL__'] = 'UrlToPayOnlineIfApplicable'; |
||
| 5847 | $substitutionarray['__ONLINE_PAYMENT_TEXT_AND_URL__'] = 'TextAndUrlToPayOnlineIfApplicable'; |
||
| 5848 | $substitutionarray['__SECUREKEYPAYMENT__'] = 'Security key (if key is not unique per record)'; |
||
| 5849 | $substitutionarray['__SECUREKEYPAYMENT_MEMBER__'] = 'Security key for payment on a member subscription (one key per member)'; |
||
| 5850 | $substitutionarray['__SECUREKEYPAYMENT_ORDER__'] = 'Security key for payment on an order'; |
||
| 5851 | $substitutionarray['__SECUREKEYPAYMENT_INVOICE__'] = 'Security key for payment on an invoice'; |
||
| 5852 | $substitutionarray['__SECUREKEYPAYMENT_CONTRACTLINE__'] = 'Security key for payment on a a service'; |
||
| 5853 | |||
| 5854 | $substitutionarray['__DIRECTDOWNLOAD_URL_PROPOSAL__'] = 'Direct download url of a proposal'; |
||
| 5855 | $substitutionarray['__DIRECTDOWNLOAD_URL_ORDER__'] = 'Direct download url of an order'; |
||
| 5856 | $substitutionarray['__DIRECTDOWNLOAD_URL_INVOICE__'] = 'Direct download url of an invoice'; |
||
| 5857 | |||
| 5858 | if (is_object($object) && $object->element == 'shipping') {
|
||
| 5859 | $substitutionarray['__SHIPPINGTRACKNUM__'] = 'Shipping tacking number'; |
||
| 5860 | $substitutionarray['__SHIPPINGTRACKNUMURL__'] = 'Shipping tracking url'; |
||
| 5861 | } |
||
| 5862 | } else {
|
||
| 5863 | $substitutionarray['__ID__'] = $object->id; |
||
| 5864 | $substitutionarray['__REF__'] = $object->ref; |
||
| 5865 | $substitutionarray['__REFCLIENT__'] = (isset($object->ref_client) ? $object->ref_client : (isset($object->ref_customer) ? $object->ref_customer : '')); |
||
| 5866 | $substitutionarray['__REFSUPPLIER__'] = (isset($object->ref_supplier) ? $object->ref_supplier : ''); |
||
| 5867 | |||
| 5868 | // TODO Remove this |
||
| 5869 | $msgishtml = 0; |
||
| 5870 | |||
| 5871 | $birthday = AlDolUtils::dol_print_date($object->birth, 'day'); |
||
| 5872 | |||
| 5873 | $substitutionarray['__MEMBER_ID__'] = $object->id; |
||
| 5874 | if (method_exists($object, 'getCivilityLabel')) |
||
| 5875 | $substitutionarray['__MEMBER_CIVILITY__'] = $object->getCivilityLabel(); |
||
| 5876 | $substitutionarray['__MEMBER_FIRSTNAME__'] = $msgishtml ? AlDolUtils::dol_htmlentitiesbr($object->firstname) : $object->firstname; |
||
| 5877 | $substitutionarray['__MEMBER_LASTNAME__'] = $msgishtml ? AlDolUtils::dol_htmlentitiesbr($object->lastname) : $object->lastname; |
||
| 5878 | if (method_exists($object, 'getFullName')) |
||
| 5879 | $substitutionarray['__MEMBER_FULLNAME__'] = $msgishtml ? AlDolUtils::dol_htmlentitiesbr($object->getFullName($outputlangs)) : $object->getFullName($outputlangs); |
||
| 5880 | $substitutionarray['__MEMBER_COMPANY__'] = $msgishtml ? AlDolUtils::dol_htmlentitiesbr($object->societe) : $object->societe; |
||
| 5881 | $substitutionarray['__MEMBER_ADDRESS__'] = $msgishtml ? AlDolUtils::dol_htmlentitiesbr($object->address) : $object->address; |
||
| 5882 | $substitutionarray['__MEMBER_ZIP__'] = $msgishtml ? AlDolUtils::dol_htmlentitiesbr($object->zip) : $object->zip; |
||
| 5883 | $substitutionarray['__MEMBER_TOWN__'] = $msgishtml ? AlDolUtils::dol_htmlentitiesbr($object->town) : $object->town; |
||
| 5884 | $substitutionarray['__MEMBER_COUNTRY__'] = $msgishtml ? AlDolUtils::dol_htmlentitiesbr($object->country) : $object->country; |
||
| 5885 | $substitutionarray['__MEMBER_EMAIL__'] = $msgishtml ? AlDolUtils::dol_htmlentitiesbr($object->email) : $object->email; |
||
| 5886 | $substitutionarray['__MEMBER_BIRTH__'] = $msgishtml ? AlDolUtils::dol_htmlentitiesbr($birthday) : $birthday; |
||
| 5887 | $substitutionarray['__MEMBER_PHOTO__'] = $msgishtml ? AlDolUtils::dol_htmlentitiesbr($object->photo) : $object->photo; |
||
| 5888 | $substitutionarray['__MEMBER_LOGIN__'] = $msgishtml ? AlDolUtils::dol_htmlentitiesbr($object->login) : $object->login; |
||
| 5889 | $substitutionarray['__MEMBER_PASSWORD__'] = $msgishtml ? AlDolUtils::dol_htmlentitiesbr($object->pass) : $object->pass; |
||
| 5890 | $substitutionarray['__MEMBER_PHONE__'] = $msgishtml ? AlDolUtils::dol_htmlentitiesbr($object->phone) : $object->phone; |
||
| 5891 | $substitutionarray['__MEMBER_PHONEPRO__'] = $msgishtml ? AlDolUtils::dol_htmlentitiesbr($object->phone_perso) : $object->phone_perso; |
||
| 5892 | $substitutionarray['__MEMBER_PHONEMOBILE__'] = $msgishtml ? AlDolUtils::dol_htmlentitiesbr($object->phone_mobile) : $object->phone_mobile; |
||
| 5893 | $substitutionarray['__MEMBER_FIRST_SUBSCRIPTION_DATE__'] = AlDolUtils::dol_print_date($object->first_subscription_date, 'dayrfc'); |
||
| 5894 | $substitutionarray['__MEMBER_FIRST_SUBSCRIPTION_DATE_START__'] = AlDolUtils::dol_print_date($object->first_subscription_date_start, 'dayrfc'); |
||
| 5895 | $substitutionarray['__MEMBER_FIRST_SUBSCRIPTION_DATE_END__'] = AlDolUtils::dol_print_date($object->first_subscription_date_end, 'dayrfc'); |
||
| 5896 | $substitutionarray['__MEMBER_LAST_SUBSCRIPTION_DATE__'] = AlDolUtils::dol_print_date($object->last_subscription_date, 'dayrfc'); |
||
| 5897 | $substitutionarray['__MEMBER_LAST_SUBSCRIPTION_DATE_START__'] = AlDolUtils::dol_print_date($object->last_subscription_date_start, 'dayrfc'); |
||
| 5898 | $substitutionarray['__MEMBER_LAST_SUBSCRIPTION_DATE_END__'] = AlDolUtils::dol_print_date($object->last_subscription_date_end, 'dayrfc'); |
||
| 5899 | |||
| 5900 | if (is_object($object) && $object->element == 'societe') {
|
||
| 5901 | $substitutionarray['__THIRDPARTY_ID__'] = (is_object($object) ? $object->id : ''); |
||
| 5902 | $substitutionarray['__THIRDPARTY_NAME__'] = (is_object($object) ? $object->name : ''); |
||
| 5903 | $substitutionarray['__THIRDPARTY_NAME_ALIAS__'] = (is_object($object) ? $object->name_alias : ''); |
||
| 5904 | $substitutionarray['__THIRDPARTY_EMAIL__'] = (is_object($object) ? $object->email : ''); |
||
| 5905 | } elseif (is_object($object->thirdparty) && $object->thirdparty->id > 0) {
|
||
| 5906 | $substitutionarray['__THIRDPARTY_ID__'] = (is_object($object->thirdparty) ? $object->thirdparty->id : ''); |
||
| 5907 | $substitutionarray['__THIRDPARTY_NAME__'] = (is_object($object->thirdparty) ? $object->thirdparty->name : ''); |
||
| 5908 | $substitutionarray['__THIRDPARTY_NAME_ALIAS__'] = (is_object($object->thirdparty) ? $object->thirdparty->name_alias : ''); |
||
| 5909 | $substitutionarray['__THIRDPARTY_EMAIL__'] = (is_object($object->thirdparty) ? $object->thirdparty->email : ''); |
||
| 5910 | } |
||
| 5911 | |||
| 5912 | if (is_object($object->projet) && $object->projet->id > 0) {
|
||
| 5913 | $substitutionarray['__PROJECT_ID__'] = (is_object($object->projet) ? $object->projet->id : ''); |
||
| 5914 | $substitutionarray['__PROJECT_REF__'] = (is_object($object->projet) ? $object->projet->ref : ''); |
||
| 5915 | $substitutionarray['__PROJECT_NAME__'] = (is_object($object->projet) ? $object->projet->title : ''); |
||
| 5916 | } |
||
| 5917 | |||
| 5918 | if (is_object($object) && $object->element == 'shipping') {
|
||
| 5919 | $substitutionarray['__SHIPPINGTRACKNUM__'] = $object->tracking_number; |
||
| 5920 | $substitutionarray['__SHIPPINGTRACKNUMURL__'] = $object->tracking_url; |
||
| 5921 | } |
||
| 5922 | |||
| 5923 | if (is_object($object) && $object->element == 'contrat' && is_array($object->lines)) {
|
||
| 5924 | $dateplannedstart = ''; |
||
| 5925 | $datenextexpiration = ''; |
||
| 5926 | foreach ($object->lines as $line) {
|
||
| 5927 | if ($line->date_ouverture_prevue > $dateplannedstart) |
||
| 5928 | $dateplannedstart = $line->date_ouverture_prevue; |
||
| 5929 | if ($line->statut == 4 && $line->date_fin_prevue && (!$datenextexpiration || $line->date_fin_prevue < $datenextexpiration)) |
||
| 5930 | $datenextexpiration = $line->date_fin_prevue; |
||
| 5931 | } |
||
| 5932 | $substitutionarray['__CONTRACT_HIGHEST_PLANNED_START_DATE__'] = AlDolUtils::dol_print_date($dateplannedstart, 'dayrfc'); |
||
| 5933 | $substitutionarray['__CONTRACT_HIGHEST_PLANNED_START_DATETIME__'] = AlDolUtils::dol_print_date($dateplannedstart, 'standard'); |
||
| 5934 | $substitutionarray['__CONTRACT_LOWEST_EXPIRATION_DATE__'] = AlDolUtils::dol_print_date($datenextexpiration, 'dayrfc'); |
||
| 5935 | $substitutionarray['__CONTRACT_LOWEST_EXPIRATION_DATETIME__'] = AlDolUtils::dol_print_date($datenextexpiration, 'standard'); |
||
| 5936 | } |
||
| 5937 | |||
| 5938 | // Create dynamic tags for __EXTRAFIELD_FIELD__ |
||
| 5939 | if ($object->table_element && $object->id > 0) {
|
||
| 5940 | if (!is_object($extrafields)) |
||
| 5941 | $extrafields = new ExtraFields($db); |
||
| 5942 | $extrafields->fetch_name_optionals_label($object->table_element, true); |
||
| 5943 | |||
| 5944 | if ($object->fetch_optionals() > 0) {
|
||
| 5945 | if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label']) > 0) {
|
||
| 5946 | foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) {
|
||
| 5947 | $substitutionarray['__EXTRAFIELD_' . strtoupper($key) . '__'] = $object->array_options['options_' . $key]; |
||
| 5948 | } |
||
| 5949 | } |
||
| 5950 | } |
||
| 5951 | } |
||
| 5952 | |||
| 5953 | // Complete substitution array with the url to make online payment |
||
| 5954 | $paymenturl = ''; |
||
| 5955 | if (empty($substitutionarray['__REF__'])) {
|
||
| 5956 | $paymenturl = ''; |
||
| 5957 | } else {
|
||
| 5958 | // Set the online payment url link into __ONLINE_PAYMENT_URL__ key |
||
| 5959 | require_once DOL_BASE_PATH . '/core/lib/payments.lib.php'; |
||
| 5960 | $outputlangs->loadLangs(array('paypal', 'other'));
|
||
| 5961 | $typeforonlinepayment = 'free'; |
||
| 5962 | if (is_object($object) && $object->element == 'commande') |
||
| 5963 | $typeforonlinepayment = 'order'; |
||
| 5964 | if (is_object($object) && $object->element == 'facture') |
||
| 5965 | $typeforonlinepayment = 'invoice'; |
||
| 5966 | if (is_object($object) && $object->element == 'member') |
||
| 5967 | $typeforonlinepayment = 'member'; |
||
| 5968 | $url = getOnlinePaymentUrl(0, $typeforonlinepayment, $substitutionarray['__REF__']); |
||
| 5969 | $paymenturl = $url; |
||
| 5970 | } |
||
| 5971 | |||
| 5972 | $substitutionarray['__ONLINE_PAYMENT_TEXT_AND_URL__'] = ($paymenturl ? str_replace('\n', "\n", $outputlangs->trans("PredefinedMailContentLink", $paymenturl)) : '');
|
||
| 5973 | $substitutionarray['__ONLINE_PAYMENT_URL__'] = $paymenturl; |
||
| 5974 | |||
| 5975 | if (!empty(Globals::$conf->global->PROPOSAL_ALLOW_EXTERNAL_DOWNLOAD) && is_object($object) && $object->element == 'propal') {
|
||
| 5976 | $substitutionarray['__DIRECTDOWNLOAD_URL_PROPOSAL__'] = $object->getLastMainDocLink($object->element); |
||
| 5977 | } else |
||
| 5978 | $substitutionarray['__DIRECTDOWNLOAD_URL_PROPOSAL__'] = ''; |
||
| 5979 | if (!empty(Globals::$conf->global->ORDER_ALLOW_EXTERNAL_DOWNLOAD) && is_object($object) && $object->element == 'commande') {
|
||
| 5980 | $substitutionarray['__DIRECTDOWNLOAD_URL_ORDER__'] = $object->getLastMainDocLink($object->element); |
||
| 5981 | } else |
||
| 5982 | $substitutionarray['__DIRECTDOWNLOAD_URL_ORDER__'] = ''; |
||
| 5983 | if (!empty(Globals::$conf->global->INVOICE_ALLOW_EXTERNAL_DOWNLOAD) && is_object($object) && $object->element == 'facture') {
|
||
| 5984 | $substitutionarray['__DIRECTDOWNLOAD_URL_INVOICE__'] = $object->getLastMainDocLink($object->element); |
||
| 5985 | } else |
||
| 5986 | $substitutionarray['__DIRECTDOWNLOAD_URL_INVOICE__'] = ''; |
||
| 5987 | } |
||
| 5988 | } |
||
| 5989 | if (empty($exclude) || !in_array('objectamount', $exclude)) {
|
||
| 5990 | $substitutionarray['__DATE_YMD__'] = is_object($object) ? (isset($object->date) ? AlDolUtils::dol_print_date($object->date, 'day', 0, $outputlangs) : '') : ''; |
||
| 5991 | $substitutionarray['__DATE_DUE_YMD__'] = is_object($object) ? (isset($object->date_lim_reglement) ? AlDolUtils::dol_print_date($object->date_lim_reglement, 'day', 0, $outputlangs) : '') : ''; |
||
| 5992 | |||
| 5993 | $substitutionarray['__AMOUNT__'] = is_object($object) ? $object->total_ttc : ''; |
||
| 5994 | $substitutionarray['__AMOUNT_EXCL_TAX__'] = is_object($object) ? $object->total_ht : ''; |
||
| 5995 | $substitutionarray['__AMOUNT_VAT__'] = is_object($object) ? ($object->total_vat ? $object->total_vat : $object->total_tva) : ''; |
||
| 5996 | if ($onlykey != 2 || $mysoc->useLocalTax(1)) |
||
| 5997 | $substitutionarray['__AMOUNT_TAX2__'] = is_object($object) ? $object->total_localtax1 : ''; |
||
| 5998 | if ($onlykey != 2 || $mysoc->useLocalTax(2)) |
||
| 5999 | $substitutionarray['__AMOUNT_TAX3__'] = is_object($object) ? $object->total_localtax2 : ''; |
||
| 6000 | |||
| 6001 | $substitutionarray['__AMOUNT_FORMATED__'] = is_object($object) ? price($object->total_ttc, 0, $outputlangs, 0, 0, -1, Globals::$conf->currency) : ''; |
||
| 6002 | $substitutionarray['__AMOUNT_EXCL_TAX_FORMATED__'] = is_object($object) ? price($object->total_ht, 0, $outputlangs, 0, 0, -1, Globals::$conf->currency) : ''; |
||
| 6003 | $substitutionarray['__AMOUNT_VAT_FORMATED__'] = is_object($object) ? ($object->total_vat ? price($object->total_vat, 0, $outputlangs, 0, 0, -1, Globals::$conf->currency) : price($object->total_tva, 0, $outputlangs, 0, 0, -1, Globals::$conf->currency)) : ''; |
||
| 6004 | if ($onlykey != 2 || $mysoc->useLocalTax(1)) |
||
| 6005 | $substitutionarray['__AMOUNT_TAX2_FORMATED__'] = is_object($object) ? price($object->total_localtax1, 0, $outputlangs, 0, 0, -1, Globals::$conf->currency) : ''; |
||
| 6006 | if ($onlykey != 2 || $mysoc->useLocalTax(2)) |
||
| 6007 | $substitutionarray['__AMOUNT_TAX3_FORMATED__'] = is_object($object) ? price($object->total_localtax2, 0, $outputlangs, 0, 0, -1, Globals::$conf->currency) : ''; |
||
| 6008 | |||
| 6009 | // TODO Add keys for foreign multicurrency |
||
| 6010 | // For backward compatibility |
||
| 6011 | if ($onlykey != 2) {
|
||
| 6012 | $substitutionarray['__TOTAL_TTC__'] = is_object($object) ? $object->total_ttc : ''; |
||
| 6013 | $substitutionarray['__TOTAL_HT__'] = is_object($object) ? $object->total_ht : ''; |
||
| 6014 | $substitutionarray['__TOTAL_VAT__'] = is_object($object) ? ($object->total_vat ? $object->total_vat : $object->total_tva) : ''; |
||
| 6015 | } |
||
| 6016 | } |
||
| 6017 | |||
| 6018 | //var_dump($substitutionarray['__AMOUNT_FORMATED__']); |
||
| 6019 | if (empty($exclude) || !in_array('date', $exclude)) {
|
||
| 6020 | include_once DOL_BASE_PATH . '/core/lib/date.lib.php'; |
||
| 6021 | |||
| 6022 | $tmp = dol_getdate(dol_now(), true); |
||
| 6023 | $tmp2 = dol_get_prev_day($tmp['mday'], $tmp['mon'], $tmp['year']); |
||
| 6024 | $tmp3 = dol_get_prev_month($tmp['mon'], $tmp['year']); |
||
| 6025 | $tmp4 = dol_get_next_day($tmp['mday'], $tmp['mon'], $tmp['year']); |
||
| 6026 | $tmp5 = dol_get_next_month($tmp['mon'], $tmp['year']); |
||
| 6027 | |||
| 6028 | $substitutionarray = array_merge($substitutionarray, array( |
||
| 6029 | '__DAY__' => (string) $tmp['mday'], |
||
| 6030 | '__DAY_TEXT__' => $outputlangs->trans('Day' . $tmp['wday']), // Monday
|
||
| 6031 | '__DAY_TEXT_SHORT__' => $outputlangs->trans($tmp['weekday'] . 'Min'), // Mon |
||
| 6032 | '__DAY_TEXT_MIN__' => $outputlangs->trans('Short' . $tmp['weekday']), // M
|
||
| 6033 | '__MONTH__' => (string) $tmp['mon'], |
||
| 6034 | '__MONTH_TEXT__' => $outputlangs->trans('Month' . sprintf("%02d", $tmp['mon'])),
|
||
| 6035 | '__MONTH_TEXT_SHORT__' => $outputlangs->trans('MonthShort' . sprintf("%02d", $tmp['mon'])),
|
||
| 6036 | '__MONTH_TEXT_MIN__' => $outputlangs->trans('MonthVeryShort' . sprintf("%02d", $tmp['mon'])),
|
||
| 6037 | '__YEAR__' => (string) $tmp['year'], |
||
| 6038 | '__PREVIOUS_DAY__' => (string) $tmp2['day'], |
||
| 6039 | '__PREVIOUS_MONTH__' => (string) $tmp3['month'], |
||
| 6040 | '__PREVIOUS_YEAR__' => (string) ($tmp['year'] - 1), |
||
| 6041 | '__NEXT_DAY__' => (string) $tmp4['day'], |
||
| 6042 | '__NEXT_MONTH__' => (string) $tmp5['month'], |
||
| 6043 | '__NEXT_YEAR__' => (string) ($tmp['year'] + 1), |
||
| 6044 | )); |
||
| 6045 | } |
||
| 6046 | |||
| 6047 | if (!empty(Globals::$conf->multicompany->enabled)) {
|
||
| 6048 | $substitutionarray = array_merge($substitutionarray, array('__ENTITY_ID__' => Globals::$conf->entity));
|
||
| 6049 | } |
||
| 6050 | if (empty($exclude) || !in_array('system', $exclude)) {
|
||
| 6051 | $substitutionarray['__DOL_MAIN_URL_ROOT__'] = DOL_MAIN_URL_ROOT; |
||
| 6052 | $substitutionarray['__(AnyTranslationKey)__'] = $outputlangs->trans('TranslationOfKey');
|
||
| 6053 | $substitutionarray['__[AnyConstantKey]__'] = $outputlangs->trans('ValueOfConstantKey');
|
||
| 6054 | } |
||
| 6055 | |||
| 6056 | return $substitutionarray; |
||
| 6057 | } |
||
| 6058 | |||
| 6059 | /** |
||
| 6060 | * Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=>newval), |
||
| 6061 | * and texts like __(TranslationKey|langfile)__ and __[ConstantKey]__ are also replaced. |
||
| 6062 | * Example of usage: |
||
| 6063 | * $substitutionarray = getCommonSubstitutionArray(Globals::$langs, 0, null, $thirdparty); |
||
| 6064 | * complete_substitutions_array($substitutionarray, Globals::$langs, $thirdparty); |
||
| 6065 | * $mesg = make_substitutions($mesg, $substitutionarray, Globals::$langs); |
||
| 6066 | * |
||
| 6067 | * @param string $text Source string in which we must do substitution |
||
| 6068 | * @param array $substitutionarray Array with key->val to substitute. Example: array('__MYKEY__' => 'MyVal', ...)
|
||
| 6069 | * @param Translate $outputlangs Output language |
||
| 6070 | * @return string Output string after substitutions |
||
| 6071 | * @see complete_substitutions_array, getCommonSubstitutionArray |
||
| 6072 | */ |
||
| 6073 | static function make_substitutions($text, $substitutionarray, $outputlangs = null) |
||
| 6074 | {
|
||
| 6075 | // global Globals::$conf, Globals::$langs; |
||
| 6076 | |||
| 6077 | if (!is_array($substitutionarray)) |
||
| 6078 | return 'ErrorBadParameterSubstitutionArrayWhenCalling_make_substitutions'; |
||
| 6079 | |||
| 6080 | if (empty($outputlangs)) |
||
| 6081 | $outputlangs = Globals::$langs; |
||
| 6082 | |||
| 6083 | // Make substitution for language keys |
||
| 6084 | if (is_object($outputlangs)) {
|
||
| 6085 | while (preg_match('/__\(([^\)]+)\)__/', $text, $reg)) {
|
||
| 6086 | $msgishtml = 0; |
||
| 6087 | if (AlDolUtils::dol_textishtml($text, 1)) |
||
| 6088 | $msgishtml = 1; |
||
| 6089 | |||
| 6090 | // If key is __(TranslationKey|langfile)__, then force load of langfile.lang |
||
| 6091 | $tmp = explode('|', $reg[1]);
|
||
| 6092 | if (!empty($tmp[1])) |
||
| 6093 | $outputlangs->load($tmp[1]); |
||
| 6094 | |||
| 6095 | $text = preg_replace('/__\(' . preg_quote($reg[1], '/') . '\)__/', $msgishtml ? AlDolUtils::dol_htmlentitiesbr($outputlangs->transnoentitiesnoconv($reg[1])) : $outputlangs->transnoentitiesnoconv($reg[1]), $text);
|
||
| 6096 | } |
||
| 6097 | } |
||
| 6098 | |||
| 6099 | // Make substitution for constant keys. Must be after the substitution of translation, so if text of translation contains a constant, |
||
| 6100 | // it is also converted. |
||
| 6101 | while (preg_match('/__\[([^\]]+)\]__/', $text, $reg)) {
|
||
| 6102 | $msgishtml = 0; |
||
| 6103 | if (AlDolUtils::dol_textishtml($text, 1)) |
||
| 6104 | $msgishtml = 1; |
||
| 6105 | |||
| 6106 | $keyfound = $reg[1]; |
||
| 6107 | if (preg_match('/(_pass|password|secret|_key|key$)/i', $keyfound))
|
||
| 6108 | $newval = '*****forbidden*****'; |
||
| 6109 | else |
||
| 6110 | $newval = empty(Globals::$conf->global->$keyfound) ? '' : Globals::$conf->global->$keyfound; |
||
| 6111 | $text = preg_replace('/__\[' . preg_quote($keyfound, '/') . '\]__/', $msgishtml ? AlDolUtils::dol_htmlentitiesbr($newval) : $newval, $text);
|
||
| 6112 | } |
||
| 6113 | |||
| 6114 | // Make substitition for array $substitutionarray |
||
| 6115 | foreach ($substitutionarray as $key => $value) {
|
||
| 6116 | if ($key == '__SIGNATURE__' && (!empty(Globals::$conf->global->MAIN_MAIL_DO_NOT_USE_SIGN))) |
||
| 6117 | $value = ''; // Protection |
||
| 6118 | if ($key == '__USER_SIGNATURE__' && (!empty(Globals::$conf->global->MAIN_MAIL_DO_NOT_USE_SIGN))) |
||
| 6119 | $value = ''; // Protection |
||
| 6120 | |||
| 6121 | $text = str_replace("$key", "$value", $text); // We must keep the " to work when value is 123.5 for example
|
||
| 6122 | } |
||
| 6123 | |||
| 6124 | return $text; |
||
| 6125 | } |
||
| 6126 | |||
| 6127 | /** |
||
| 6128 | * Complete the $substitutionarray with more entries coming from external module that had set the "substitutions=1" into module_part array. |
||
| 6129 | * In this case, method completesubstitutionarray provided by module is called. |
||
| 6130 | * |
||
| 6131 | * @param array $substitutionarray Array substitution old value => new value value |
||
| 6132 | * @param Translate $outputlangs Output language |
||
| 6133 | * @param Object $object Source object |
||
| 6134 | * @param mixed $parameters Add more parameters (useful to pass product lines) |
||
| 6135 | * @param string $callfunc What is the name of the custom static function that will be called? (default: completesubstitutionarray) |
||
| 6136 | * @return void |
||
| 6137 | * @see make_substitutions |
||
| 6138 | */ |
||
| 6139 | static function complete_substitutions_array(&$substitutionarray, $outputlangs, $object = null, $parameters = null, $callfunc = "completesubstitutionarray") |
||
| 6140 | {
|
||
| 6141 | // global Globals::$conf, $user; |
||
| 6142 | |||
| 6143 | require_once DOL_BASE_PATH . '/core/lib/files.lib.php'; |
||
| 6144 | |||
| 6145 | // Add a substitution key for each extrafields, using key __EXTRA_XXX__ |
||
| 6146 | // TODO Remove this. Already available into the getCommonSubstitutionArray used to build the substitution array. |
||
| 6147 | /* if (is_object($object) && is_array($object->array_options)) |
||
| 6148 | {
|
||
| 6149 | foreach($object->array_options as $key => $val) |
||
| 6150 | {
|
||
| 6151 | $keyshort=preg_replace('/^(options|extra)_/','',$key);
|
||
| 6152 | $substitutionarray['__EXTRAFIELD_'.$keyshort.'__']=$val; |
||
| 6153 | // For backward compatibiliy |
||
| 6154 | $substitutionarray['%EXTRA_'.$keyshort.'%']=$val; |
||
| 6155 | } |
||
| 6156 | } */ |
||
| 6157 | |||
| 6158 | // Check if there is external substitution to do, requested by plugins |
||
| 6159 | $dirsubstitutions = array_merge(array(), (array) Globals::$conf->modules_parts['substitutions']); |
||
| 6160 | |||
| 6161 | foreach ($dirsubstitutions as $reldir) {
|
||
| 6162 | $dir = dol_buildpath($reldir, 0); |
||
| 6163 | |||
| 6164 | // Check if directory exists |
||
| 6165 | if (!dol_is_dir($dir)) |
||
| 6166 | continue; |
||
| 6167 | |||
| 6168 | $substitfiles = dol_dir_list($dir, 'files', 0, 'functions_'); |
||
| 6169 | foreach ($substitfiles as $substitfile) {
|
||
| 6170 | if (preg_match('/functions_(.*)\.lib\.php/i', $substitfile['name'], $reg)) {
|
||
| 6171 | $module = $reg[1]; |
||
| 6172 | |||
| 6173 | AlDolUtils::dol_syslog("Library " . $substitfile['name'] . " found into " . $dir);
|
||
| 6174 | // Include the user's functions file |
||
| 6175 | require_once $dir . $substitfile['name']; |
||
| 6176 | // Call the user's function, and only if it is defined |
||
| 6177 | $function_name = $module . "_" . $callfunc; |
||
| 6178 | if (function_exists($function_name)) |
||
| 6179 | $function_name($substitutionarray, $outputlangs, $object, $parameters); |
||
| 6180 | } |
||
| 6181 | } |
||
| 6182 | } |
||
| 6183 | } |
||
| 6184 | |||
| 6185 | /** |
||
| 6186 | * Format output for start and end date |
||
| 6187 | * |
||
| 6188 | * @param int $date_start Start date |
||
| 6189 | * @param int $date_end End date |
||
| 6190 | * @param string $format Output format |
||
| 6191 | * @param Translate $outputlangs Output language |
||
| 6192 | * @return void |
||
| 6193 | */ |
||
| 6194 | static function print_date_range($date_start, $date_end, $format = '', $outputlangs = '') |
||
| 6195 | {
|
||
| 6196 | print get_date_range($date_start, $date_end, $format, $outputlangs); |
||
| 6197 | } |
||
| 6198 | |||
| 6199 | /** |
||
| 6200 | * Format output for start and end date |
||
| 6201 | * |
||
| 6202 | * @param int $date_start Start date |
||
| 6203 | * @param int $date_end End date |
||
| 6204 | * @param string $format Output format |
||
| 6205 | * @param Translate $outputlangs Output language |
||
| 6206 | * @param integer $withparenthesis 1=Add parenthesis, 0=non parenthesis |
||
| 6207 | * @return string String |
||
| 6208 | */ |
||
| 6209 | static function get_date_range($date_start, $date_end, $format = '', $outputlangs = '', $withparenthesis = 1) |
||
| 6210 | {
|
||
| 6211 | // global Globals::$langs; |
||
| 6212 | |||
| 6213 | $out = ''; |
||
| 6214 | |||
| 6215 | if (!is_object($outputlangs)) |
||
| 6216 | $outputlangs = Globals::$langs; |
||
| 6217 | |||
| 6218 | if ($date_start && $date_end) {
|
||
| 6219 | $out .= ($withparenthesis ? ' (' : '') . $outputlangs->transnoentitiesnoconv('DateFromTo', AlDolUtils::dol_print_date($date_start, $format, false, $outputlangs), AlDolUtils::dol_print_date($date_end, $format, false, $outputlangs)) . ($withparenthesis ? ')' : '');
|
||
| 6220 | } |
||
| 6221 | if ($date_start && !$date_end) {
|
||
| 6222 | $out .= ($withparenthesis ? ' (' : '') . $outputlangs->transnoentitiesnoconv('DateFrom', AlDolUtils::dol_print_date($date_start, $format, false, $outputlangs)) . ($withparenthesis ? ')' : '');
|
||
| 6223 | } |
||
| 6224 | if (!$date_start && $date_end) {
|
||
| 6225 | $out .= ($withparenthesis ? ' (' : '') . $outputlangs->transnoentitiesnoconv('DateUntil', AlDolUtils::dol_print_date($date_end, $format, false, $outputlangs)) . ($withparenthesis ? ')' : '');
|
||
| 6226 | } |
||
| 6227 | |||
| 6228 | return $out; |
||
| 6229 | } |
||
| 6230 | |||
| 6231 | /** |
||
| 6232 | * Return firstname and lastname in correct order |
||
| 6233 | * |
||
| 6234 | * @param string $firstname Firstname |
||
| 6235 | * @param string $lastname Lastname |
||
| 6236 | * @param int $nameorder -1=Auto, 0=Lastname+Firstname, 1=Firstname+Lastname, 2=Firstname |
||
| 6237 | * @return string Firstname + lastname or Lastname + firstname |
||
| 6238 | */ |
||
| 6239 | static function dolGetFirstLastname($firstname, $lastname, $nameorder = -1) |
||
| 6240 | {
|
||
| 6241 | // global Globals::$conf; |
||
| 6242 | |||
| 6243 | $ret = ''; |
||
| 6244 | // If order not defined, we use the setup |
||
| 6245 | if ($nameorder < 0) |
||
| 6246 | $nameorder = (empty(Globals::$conf->global->MAIN_FIRSTNAME_NAME_POSITION) ? 1 : 0); |
||
| 6247 | if ($nameorder && ((string) $nameorder != '2')) {
|
||
| 6248 | $ret .= $firstname; |
||
| 6249 | if ($firstname && $lastname) |
||
| 6250 | $ret .= ' '; |
||
| 6251 | $ret .= $lastname; |
||
| 6252 | } |
||
| 6253 | else if ($nameorder == 2) {
|
||
| 6254 | $ret .= $firstname; |
||
| 6255 | } else {
|
||
| 6256 | $ret .= $lastname; |
||
| 6257 | if ($firstname && $lastname) |
||
| 6258 | $ret .= ' '; |
||
| 6259 | $ret .= $firstname; |
||
| 6260 | } |
||
| 6261 | return $ret; |
||
| 6262 | } |
||
| 6263 | |||
| 6264 | /** |
||
| 6265 | * Set event message in dol_events session object. Will be output by calling dol_htmloutput_events. |
||
| 6266 | * Note: Calling dol_htmloutput_events is done into pages by standard llxFooter() function. |
||
| 6267 | * Note: Prefer to use setEventMessages instead. |
||
| 6268 | * |
||
| 6269 | * @param mixed $mesgs Message string or array |
||
| 6270 | * @param string $style Which style to use ('mesgs' by default, 'warnings', 'errors')
|
||
| 6271 | * @return void |
||
| 6272 | * @see dol_htmloutput_events |
||
| 6273 | */ |
||
| 6274 | static function setEventMessage($mesgs, $style = 'mesgs') |
||
| 6275 | {
|
||
| 6276 | //DolUtils::dol_syslog(__FUNCTION__ . " is deprecated", LOG_WARNING); This is not deprecated, it is used by setEventMessages function |
||
| 6277 | if (!is_array($mesgs)) { // If mesgs is a string
|
||
| 6278 | if ($mesgs) |
||
| 6279 | $_SESSION['dol_events'][$style][] = $mesgs; |
||
| 6280 | } |
||
| 6281 | else { // If mesgs is an array
|
||
| 6282 | foreach ($mesgs as $mesg) {
|
||
| 6283 | if ($mesg) |
||
| 6284 | $_SESSION['dol_events'][$style][] = $mesg; |
||
| 6285 | } |
||
| 6286 | } |
||
| 6287 | } |
||
| 6288 | |||
| 6289 | /** |
||
| 6290 | * Set event messages in dol_events session object. Will be output by calling dol_htmloutput_events. |
||
| 6291 | * Note: Calling dol_htmloutput_events is done into pages by standard llxFooter() function. |
||
| 6292 | * |
||
| 6293 | * @param string $mesg Message string |
||
| 6294 | * @param array $mesgs Message array |
||
| 6295 | * @param string $style Which style to use ('mesgs' by default, 'warnings', 'errors')
|
||
| 6296 | * @return void |
||
| 6297 | * @see dol_htmloutput_events |
||
| 6298 | */ |
||
| 6299 | static function setEventMessages($mesg, $mesgs, $style = 'mesgs') |
||
| 6300 | {
|
||
| 6301 | if (empty($mesg) && empty($mesgs)) {
|
||
| 6302 | AlDolUtils::dol_syslog("Try to add a message in stack with empty message", LOG_WARNING);
|
||
| 6303 | } else {
|
||
| 6304 | if (!in_array((string) $style, array('mesgs', 'warnings', 'errors')))
|
||
| 6305 | dol_print_error('', 'Bad parameter style=' . $style . ' for setEventMessages');
|
||
| 6306 | if (empty($mesgs)) |
||
| 6307 | setEventMessage($mesg, $style); |
||
| 6308 | else {
|
||
| 6309 | if (!empty($mesg) && !in_array($mesg, $mesgs)) |
||
| 6310 | setEventMessage($mesg, $style); // Add message string if not already into array |
||
| 6311 | setEventMessage($mesgs, $style); |
||
| 6312 | } |
||
| 6313 | } |
||
| 6314 | } |
||
| 6315 | |||
| 6316 | /** |
||
| 6317 | * Print formated messages to output (Used to show messages on html output). |
||
| 6318 | * Note: Calling dol_htmloutput_events is done into pages by standard llxFooter() function, so there is |
||
| 6319 | * no need to call it explicitely. |
||
| 6320 | * |
||
| 6321 | * @param int $disabledoutputofmessages Clear all messages stored into session without diplaying them |
||
| 6322 | * @return void |
||
| 6323 | * @see dol_htmloutput_mesg |
||
| 6324 | */ |
||
| 6325 | static function dol_htmloutput_events($disabledoutputofmessages = 0) |
||
| 6326 | {
|
||
| 6327 | // Show mesgs |
||
| 6328 | if (isset($_SESSION['dol_events']['mesgs'])) {
|
||
| 6329 | if (empty($disabledoutputofmessages)) |
||
| 6330 | dol_htmloutput_mesg('', $_SESSION['dol_events']['mesgs']);
|
||
| 6331 | unset($_SESSION['dol_events']['mesgs']); |
||
| 6332 | } |
||
| 6333 | |||
| 6334 | // Show errors |
||
| 6335 | if (isset($_SESSION['dol_events']['errors'])) {
|
||
| 6336 | if (empty($disabledoutputofmessages)) |
||
| 6337 | dol_htmloutput_mesg('', $_SESSION['dol_events']['errors'], 'error');
|
||
| 6338 | unset($_SESSION['dol_events']['errors']); |
||
| 6339 | } |
||
| 6340 | |||
| 6341 | // Show warnings |
||
| 6342 | if (isset($_SESSION['dol_events']['warnings'])) {
|
||
| 6343 | if (empty($disabledoutputofmessages)) |
||
| 6344 | dol_htmloutput_mesg('', $_SESSION['dol_events']['warnings'], 'warning');
|
||
| 6345 | unset($_SESSION['dol_events']['warnings']); |
||
| 6346 | } |
||
| 6347 | } |
||
| 6348 | |||
| 6349 | /** |
||
| 6350 | * Get formated messages to output (Used to show messages on html output). |
||
| 6351 | * This include also the translation of the message key. |
||
| 6352 | * |
||
| 6353 | * @param string $mesgstring Message string or message key |
||
| 6354 | * @param string[] $mesgarray Array of message strings or message keys |
||
| 6355 | * @param string $style Style of message output ('ok' or 'error')
|
||
| 6356 | * @param int $keepembedded Set to 1 in error message must be kept embedded into its html place (this disable jnotify) |
||
| 6357 | * @return string Return html output |
||
| 6358 | * |
||
| 6359 | * @see dol_print_error |
||
| 6360 | * @see dol_htmloutput_errors |
||
| 6361 | * @see setEventMessages |
||
| 6362 | */ |
||
| 6363 | static function get_htmloutput_mesg($mesgstring = '', $mesgarray = '', $style = 'ok', $keepembedded = 0) |
||
| 6364 | {
|
||
| 6365 | // global Globals::$conf, Globals::$langs; |
||
| 6366 | |||
| 6367 | $ret = 0; |
||
| 6368 | $return = ''; |
||
| 6369 | $out = ''; |
||
| 6370 | $divstart = $divend = ''; |
||
| 6371 | |||
| 6372 | // If inline message with no format, we add it. |
||
| 6373 | if ((empty(Globals::$conf->use_javascript_ajax) || !empty(Globals::$conf->global->MAIN_DISABLE_JQUERY_JNOTIFY) || $keepembedded) && !preg_match('/<div class=".*">/i', $out)) {
|
||
| 6374 | $divstart = '<div class="' . $style . ' clearboth">'; |
||
| 6375 | $divend = '</div>'; |
||
| 6376 | } |
||
| 6377 | |||
| 6378 | if ((is_array($mesgarray) && count($mesgarray)) || $mesgstring) {
|
||
| 6379 | Globals::$langs->load("errors");
|
||
| 6380 | $out .= $divstart; |
||
| 6381 | if (is_array($mesgarray) && count($mesgarray)) {
|
||
| 6382 | foreach ($mesgarray as $message) {
|
||
| 6383 | $ret++; |
||
| 6384 | $out .= Globals::$langs->trans($message); |
||
| 6385 | if ($ret < count($mesgarray)) |
||
| 6386 | $out .= "<br>\n"; |
||
| 6387 | } |
||
| 6388 | } |
||
| 6389 | if ($mesgstring) {
|
||
| 6390 | Globals::$langs->load("errors");
|
||
| 6391 | $ret++; |
||
| 6392 | $out .= Globals::$langs->trans($mesgstring); |
||
| 6393 | } |
||
| 6394 | $out .= $divend; |
||
| 6395 | } |
||
| 6396 | |||
| 6397 | if ($out) {
|
||
| 6398 | if (!empty(Globals::$conf->use_javascript_ajax) && empty(Globals::$conf->global->MAIN_DISABLE_JQUERY_JNOTIFY) && empty($keepembedded)) {
|
||
| 6399 | $return = '<script type="text/javascript"> |
||
| 6400 | $(document).ready(function() {
|
||
| 6401 | var block = ' . (!empty(Globals::$conf->global->MAIN_USE_JQUERY_BLOCKUI) ? "true" : "false") . ' |
||
| 6402 | if (block) {
|
||
| 6403 | $.dolEventValid("","' . dol_escape_js($out) . '");
|
||
| 6404 | } else {
|
||
| 6405 | /* jnotify(message, preset of message type, keepmessage) */ |
||
| 6406 | $.jnotify("' . dol_escape_js($out) . '",
|
||
| 6407 | "' . ($style == "ok" ? 3000 : $style) . '", |
||
| 6408 | ' . ($style == "ok" ? "false" : "true") . ', |
||
| 6409 | { remove: static function (){} } );
|
||
| 6410 | } |
||
| 6411 | }); |
||
| 6412 | </script>'; |
||
| 6413 | } else {
|
||
| 6414 | $return = $out; |
||
| 6415 | } |
||
| 6416 | } |
||
| 6417 | |||
| 6418 | return $return; |
||
| 6419 | } |
||
| 6420 | |||
| 6421 | /** |
||
| 6422 | * Get formated error messages to output (Used to show messages on html output). |
||
| 6423 | * |
||
| 6424 | * @param string $mesgstring Error message |
||
| 6425 | * @param array $mesgarray Error messages array |
||
| 6426 | * @param int $keepembedded Set to 1 in error message must be kept embedded into its html place (this disable jnotify) |
||
| 6427 | * @return string Return html output |
||
| 6428 | * |
||
| 6429 | * @see dol_print_error |
||
| 6430 | * @see dol_htmloutput_mesg |
||
| 6431 | */ |
||
| 6432 | static function get_htmloutput_errors($mesgstring = '', $mesgarray = array(), $keepembedded = 0) |
||
| 6433 | {
|
||
| 6434 | return get_htmloutput_mesg($mesgstring, $mesgarray, 'error', $keepembedded); |
||
| 6435 | } |
||
| 6436 | |||
| 6437 | /** |
||
| 6438 | * Print formated messages to output (Used to show messages on html output). |
||
| 6439 | * |
||
| 6440 | * @param string $mesgstring Message string or message key |
||
| 6441 | * @param string[] $mesgarray Array of message strings or message keys |
||
| 6442 | * @param string $style Which style to use ('ok', 'warning', 'error')
|
||
| 6443 | * @param int $keepembedded Set to 1 if message must be kept embedded into its html place (this disable jnotify) |
||
| 6444 | * @return void |
||
| 6445 | * |
||
| 6446 | * @see dol_print_error |
||
| 6447 | * @see dol_htmloutput_errors |
||
| 6448 | * @see setEventMessages |
||
| 6449 | */ |
||
| 6450 | static function dol_htmloutput_mesg($mesgstring = '', $mesgarray = array(), $style = 'ok', $keepembedded = 0) |
||
| 6451 | {
|
||
| 6452 | if (empty($mesgstring) && (!is_array($mesgarray) || count($mesgarray) == 0)) |
||
| 6453 | return; |
||
| 6454 | |||
| 6455 | $iserror = 0; |
||
| 6456 | $iswarning = 0; |
||
| 6457 | if (is_array($mesgarray)) {
|
||
| 6458 | foreach ($mesgarray as $val) {
|
||
| 6459 | if ($val && preg_match('/class="error"/i', $val)) {
|
||
| 6460 | $iserror++; |
||
| 6461 | break; |
||
| 6462 | } |
||
| 6463 | if ($val && preg_match('/class="warning"/i', $val)) {
|
||
| 6464 | $iswarning++; |
||
| 6465 | break; |
||
| 6466 | } |
||
| 6467 | } |
||
| 6468 | } else if ($mesgstring && preg_match('/class="error"/i', $mesgstring))
|
||
| 6469 | $iserror++; |
||
| 6470 | else if ($mesgstring && preg_match('/class="warning"/i', $mesgstring))
|
||
| 6471 | $iswarning++; |
||
| 6472 | if ($style == 'error') |
||
| 6473 | $iserror++; |
||
| 6474 | if ($style == 'warning') |
||
| 6475 | $iswarning++; |
||
| 6476 | |||
| 6477 | if ($iserror || $iswarning) {
|
||
| 6478 | // Remove div from texts |
||
| 6479 | $mesgstring = preg_replace('/<\/div><div class="(error|warning)">/', '<br>', $mesgstring);
|
||
| 6480 | $mesgstring = preg_replace('/<div class="(error|warning)">/', '', $mesgstring);
|
||
| 6481 | $mesgstring = preg_replace('/<\/div>/', '', $mesgstring);
|
||
| 6482 | // Remove div from texts array |
||
| 6483 | if (is_array($mesgarray)) {
|
||
| 6484 | $newmesgarray = array(); |
||
| 6485 | foreach ($mesgarray as $val) {
|
||
| 6486 | $tmpmesgstring = preg_replace('/<\/div><div class="(error|warning)">/', '<br>', $val);
|
||
| 6487 | $tmpmesgstring = preg_replace('/<div class="(error|warning)">/', '', $tmpmesgstring);
|
||
| 6488 | $tmpmesgstring = preg_replace('/<\/div>/', '', $tmpmesgstring);
|
||
| 6489 | $newmesgarray[] = $tmpmesgstring; |
||
| 6490 | } |
||
| 6491 | $mesgarray = $newmesgarray; |
||
| 6492 | } |
||
| 6493 | print get_htmloutput_mesg($mesgstring, $mesgarray, ($iserror ? 'error' : 'warning'), $keepembedded); |
||
| 6494 | } else |
||
| 6495 | print get_htmloutput_mesg($mesgstring, $mesgarray, 'ok', $keepembedded); |
||
| 6496 | } |
||
| 6497 | |||
| 6498 | /** |
||
| 6499 | * Print formated error messages to output (Used to show messages on html output). |
||
| 6500 | * |
||
| 6501 | * @param string $mesgstring Error message |
||
| 6502 | * @param array $mesgarray Error messages array |
||
| 6503 | * @param int $keepembedded Set to 1 in error message must be kept embedded into its html place (this disable jnotify) |
||
| 6504 | * @return void |
||
| 6505 | * |
||
| 6506 | * @see dol_print_error |
||
| 6507 | * @see dol_htmloutput_mesg |
||
| 6508 | */ |
||
| 6509 | static function dol_htmloutput_errors($mesgstring = '', $mesgarray = array(), $keepembedded = 0) |
||
| 6510 | {
|
||
| 6511 | dol_htmloutput_mesg($mesgstring, $mesgarray, 'error', $keepembedded); |
||
| 6512 | } |
||
| 6513 | |||
| 6514 | /** |
||
| 6515 | * Advanced sort array by second index function, which produces ascending (default) |
||
| 6516 | * or descending output and uses optionally natural case insensitive sorting (which |
||
| 6517 | * can be optionally case sensitive as well). |
||
| 6518 | * |
||
| 6519 | * @param array $array Array to sort (array of array('key','otherkey1','otherkey2'...))
|
||
| 6520 | * @param string $index Key in array to use for sorting criteria |
||
| 6521 | * @param int $order Sort order ('asc' or 'desc')
|
||
| 6522 | * @param int $natsort 1=use "natural" sort (natsort), 0=use "standard" sort (asort) |
||
| 6523 | * @param int $case_sensitive 1=sort is case sensitive, 0=not case sensitive |
||
| 6524 | * @param int $keepindex If 0 and index key of array to sort is a numeric, than index will be rewrote. If 1 or index key is not numeric, key for index is kept after sorting. |
||
| 6525 | * @return array Sorted array |
||
| 6526 | */ |
||
| 6527 | static function dol_sort_array(&$array, $index, $order = 'asc', $natsort = 0, $case_sensitive = 0, $keepindex = 0) |
||
| 6528 | {
|
||
| 6529 | // Clean parameters |
||
| 6530 | $order = strtolower($order); |
||
| 6531 | |||
| 6532 | if (is_array($array)) {
|
||
| 6533 | $sizearray = count($array); |
||
| 6534 | if ($sizearray > 0) {
|
||
| 6535 | $temp = array(); |
||
| 6536 | foreach (array_keys($array) as $key) |
||
| 6537 | $temp[$key] = $array[$key][$index]; |
||
| 6538 | |||
| 6539 | if (!$natsort) |
||
| 6540 | ($order == 'asc') ? asort($temp) : arsort($temp); |
||
| 6541 | else {
|
||
| 6542 | ($case_sensitive) ? natsort($temp) : natcasesort($temp); |
||
| 6543 | if ($order != 'asc') |
||
| 6544 | $temp = array_reverse($temp, true); |
||
| 6545 | } |
||
| 6546 | |||
| 6547 | $sorted = array(); |
||
| 6548 | |||
| 6549 | foreach (array_keys($temp) as $key) {
|
||
| 6550 | (is_numeric($key) && empty($keepindex)) ? $sorted[] = $array[$key] : $sorted[$key] = $array[$key]; |
||
| 6551 | } |
||
| 6552 | |||
| 6553 | return $sorted; |
||
| 6554 | } |
||
| 6555 | } |
||
| 6556 | return $array; |
||
| 6557 | } |
||
| 6558 | |||
| 6559 | /** |
||
| 6560 | * Check if a string is in UTF8 |
||
| 6561 | * |
||
| 6562 | * @param string $str String to check |
||
| 6563 | * @return boolean True if string is UTF8 or ISO compatible with UTF8, False if not (ISO with special char or Binary) |
||
| 6564 | */ |
||
| 6565 | static function utf8_check($str) |
||
| 6566 | {
|
||
| 6567 | // We must use here a binary strlen static function (so not AlDolUtils::dol_strlen) |
||
| 6568 | $strLength = AlDolUtils::dol_strlen($str); |
||
| 6569 | for ($i = 0; $i < $strLength; $i++) {
|
||
| 6570 | if (ord($str[$i]) < 0x80) |
||
| 6571 | continue; // 0bbbbbbb |
||
| 6572 | elseif ((ord($str[$i]) & 0xE0) == 0xC0) |
||
| 6573 | $n = 1; // 110bbbbb |
||
| 6574 | elseif ((ord($str[$i]) & 0xF0) == 0xE0) |
||
| 6575 | $n = 2; // 1110bbbb |
||
| 6576 | elseif ((ord($str[$i]) & 0xF8) == 0xF0) |
||
| 6577 | $n = 3; // 11110bbb |
||
| 6578 | elseif ((ord($str[$i]) & 0xFC) == 0xF8) |
||
| 6579 | $n = 4; // 111110bb |
||
| 6580 | elseif ((ord($str[$i]) & 0xFE) == 0xFC) |
||
| 6581 | $n = 5; // 1111110b |
||
| 6582 | else |
||
| 6583 | return false; // Does not match any model |
||
| 6584 | for ($j = 0; $j < $n; $j++) { // n bytes matching 10bbbbbb follow ?
|
||
| 6585 | if (( ++$i == strlen($str)) || ((ord($str[$i]) & 0xC0) != 0x80)) |
||
| 6586 | return false; |
||
| 6587 | } |
||
| 6588 | } |
||
| 6589 | return true; |
||
| 6590 | } |
||
| 6591 | |||
| 6592 | /** |
||
| 6593 | * Return a string encoded into OS filesystem encoding. This static function is used to define |
||
| 6594 | * value to pass to filesystem PHP functions. |
||
| 6595 | * |
||
| 6596 | * @param string $str String to encode (UTF-8) |
||
| 6597 | * @return string Encoded string (UTF-8, ISO-8859-1) |
||
| 6598 | */ |
||
| 6599 | function dol_osencode($str) |
||
| 6600 | {
|
||
| 6601 | // global Globals::$conf; |
||
| 6602 | |||
| 6603 | $tmp = ini_get("unicode.filesystem_encoding"); // Disponible avec PHP 6.0
|
||
| 6604 | if (empty($tmp) && !empty($_SERVER["WINDIR"])) |
||
| 6605 | $tmp = 'iso-8859-1'; // By default for windows |
||
| 6606 | if (empty($tmp)) |
||
| 6607 | $tmp = 'utf-8'; // By default for other |
||
| 6608 | if (!empty(Globals::$conf->global->MAIN_FILESYSTEM_ENCODING)) |
||
| 6609 | $tmp = Globals::$conf->global->MAIN_FILESYSTEM_ENCODING; |
||
| 6610 | |||
| 6611 | if ($tmp == 'iso-8859-1') |
||
| 6612 | return utf8_decode($str); |
||
| 6613 | return $str; |
||
| 6614 | } |
||
| 6615 | |||
| 6616 | /** |
||
| 6617 | * Return an id or code from a code or id. |
||
| 6618 | * Store also Code-Id into a cache to speed up next request on same key. |
||
| 6619 | * |
||
| 6620 | * @param DoliDB $db Database handler |
||
| 6621 | * @param string $key Code or Id to get Id or Code |
||
| 6622 | * @param string $tablename Table name without prefix |
||
| 6623 | * @param string $fieldkey Field to search the key into |
||
| 6624 | * @param string $fieldid Field to get |
||
| 6625 | * @param int $entityfilter Filter by entity |
||
| 6626 | * @return int <0 if KO, Id of code if OK |
||
| 6627 | * @see Globals::$langs->getLabelFromKey |
||
| 6628 | */ |
||
| 6629 | static function dol_getIdFromCode($db, $key, $tablename, $fieldkey = 'code', $fieldid = 'id', $entityfilter = 0) |
||
| 6630 | {
|
||
| 6631 | // global $cache_codes; |
||
| 6632 | // If key empty |
||
| 6633 | if ($key == '') |
||
| 6634 | return ''; |
||
| 6635 | |||
| 6636 | // Check in cache |
||
| 6637 | if (isset($cache_codes[$tablename][$key][$fieldid])) { // Can be defined to 0 or ''
|
||
| 6638 | return $cache_codes[$tablename][$key][$fieldid]; // Found in cache |
||
| 6639 | } |
||
| 6640 | |||
| 6641 | AlDolUtils::dol_syslog('dol_getIdFromCode (value not found into cache)', LOG_DEBUG);
|
||
| 6642 | |||
| 6643 | $sql = "SELECT " . $fieldid . " as valuetoget"; |
||
| 6644 | $sql .= " FROM " . MAIN_DB_PREFIX . $tablename; |
||
| 6645 | $sql .= " WHERE " . $fieldkey . " = '" . $db->escape($key) . "'"; |
||
| 6646 | if (!empty($entityfilter)) |
||
| 6647 | $sql .= " AND entity IN (" . getEntity($tablename) . ")";
|
||
| 6648 | |||
| 6649 | $resql = $db->query($sql); |
||
| 6650 | if ($resql) {
|
||
| 6651 | $obj = $db->fetch_object($resql); |
||
| 6652 | if ($obj) |
||
| 6653 | $cache_codes[$tablename][$key][$fieldid] = $obj->valuetoget; |
||
| 6654 | else |
||
| 6655 | $cache_codes[$tablename][$key][$fieldid] = ''; |
||
| 6656 | $db->free($resql); |
||
| 6657 | return $cache_codes[$tablename][$key][$fieldid]; |
||
| 6658 | } |
||
| 6659 | else {
|
||
| 6660 | return -1; |
||
| 6661 | } |
||
| 6662 | } |
||
| 6663 | |||
| 6664 | /** |
||
| 6665 | * Verify if condition in string is ok or not |
||
| 6666 | * |
||
| 6667 | * @param string $strRights String with condition to check |
||
| 6668 | * @return boolean True or False. Return True if strRights is '' |
||
| 6669 | */ |
||
| 6670 | static function verifCond($strRights) |
||
| 6671 | {
|
||
| 6672 | // global $user, Globals::$conf, Globals::$langs; |
||
| 6673 | // global $leftmenu; |
||
| 6674 | // global $rights; // To export to dol_eval function |
||
| 6675 | //print $strRights."<br>\n"; |
||
| 6676 | $rights = true; |
||
| 6677 | if ($strRights != '') {
|
||
| 6678 | $str = 'if(!(' . $strRights . ')) { $rights = false; }';
|
||
| 6679 | self::dol_eval($str); // The dol_eval must contains all the// global $xxx used into a condition |
||
| 6680 | } |
||
| 6681 | return $rights; |
||
| 6682 | } |
||
| 6683 | |||
| 6684 | /** |
||
| 6685 | * Replace eval static function to add more security. |
||
| 6686 | * This static function is called by verifCond() or trans() and transnoentitiesnoconv(). |
||
| 6687 | * |
||
| 6688 | * @param string $s String to evaluate |
||
| 6689 | * @param int $returnvalue 0=No return (used to execute eval($a=something)). 1=Value of eval is returned (used to eval($something)). |
||
| 6690 | * @param int $hideerrors 1=Hide errors |
||
| 6691 | * @return mixed Nothing or return of eval |
||
| 6692 | */ |
||
| 6693 | static function dol_eval($s, $returnvalue = 0, $hideerrors = 1) |
||
| 6694 | {
|
||
| 6695 | // Only// global variables can be changed by eval static function and returned to caller |
||
| 6696 | // global $db, Globals::$langs, $user, Globals::$conf, $website, $websitepage; |
||
| 6697 | // global $action, $mainmenu, $leftmenu; |
||
| 6698 | // global $rights; |
||
| 6699 | // global $object; |
||
| 6700 | // global $mysoc; |
||
| 6701 | // global $obj; // To get $obj used into list when dol_eval is used for computed fields and $obj is not yet $object |
||
| 6702 | // global $soc; // For backward compatibility |
||
| 6703 | //print $s."<br>\n"; |
||
| 6704 | if ($returnvalue) {
|
||
| 6705 | if ($hideerrors) |
||
| 6706 | return @eval('return ' . $s . ';');
|
||
| 6707 | else |
||
| 6708 | return eval('return ' . $s . ';');
|
||
| 6709 | } |
||
| 6710 | else {
|
||
| 6711 | if ($hideerrors) |
||
| 6712 | @eval($s); |
||
| 6713 | else |
||
| 6714 | eval($s); |
||
| 6715 | } |
||
| 6716 | } |
||
| 6717 | |||
| 6718 | /** |
||
| 6719 | * Return if var element is ok |
||
| 6720 | * |
||
| 6721 | * @param string $element Variable to check |
||
| 6722 | * @return boolean Return true of variable is not empty |
||
| 6723 | */ |
||
| 6724 | static function dol_validElement($element) |
||
| 6725 | {
|
||
| 6726 | return (trim($element) != ''); |
||
| 6727 | } |
||
| 6728 | |||
| 6729 | /** |
||
| 6730 | * Return img flag of country for a language code or country code |
||
| 6731 | * |
||
| 6732 | * @param string $codelang Language code (en_IN, fr_CA...) or Country code (IN, FR) |
||
| 6733 | * @param string $moreatt Add more attribute on img tag (For example 'style="float: right"') |
||
| 6734 | * @return string HTML img string with flag. |
||
| 6735 | */ |
||
| 6736 | static function picto_from_langcode($codelang, $moreatt = '') |
||
| 6737 | {
|
||
| 6738 | // global Globals::$langs; |
||
| 6739 | |||
| 6740 | if (empty($codelang)) |
||
| 6741 | return ''; |
||
| 6742 | |||
| 6743 | if ($codelang == 'auto') {
|
||
| 6744 | return '<span class="fa fa-globe"></span>'; |
||
| 6745 | } |
||
| 6746 | |||
| 6747 | $langtocountryflag = array( |
||
| 6748 | 'ar_AR' => '', |
||
| 6749 | 'ca_ES' => 'catalonia', |
||
| 6750 | 'da_DA' => 'dk', |
||
| 6751 | 'fr_CA' => 'mq', |
||
| 6752 | 'sv_SV' => 'se' |
||
| 6753 | ); |
||
| 6754 | |||
| 6755 | if (isset($langtocountryflag[$codelang])) |
||
| 6756 | $flagImage = $langtocountryflag[$codelang]; |
||
| 6757 | else {
|
||
| 6758 | $tmparray = explode('_', $codelang);
|
||
| 6759 | $flagImage = empty($tmparray[1]) ? $tmparray[0] : $tmparray[1]; |
||
| 6760 | } |
||
| 6761 | |||
| 6762 | return img_picto_common($codelang, 'flags/' . strtolower($flagImage) . '.png', $moreatt); |
||
| 6763 | } |
||
| 6764 | |||
| 6765 | /** |
||
| 6766 | * Return default language from country code |
||
| 6767 | * |
||
| 6768 | * @param string $countrycode Country code like 'US', 'FR', 'CA', ... |
||
| 6769 | * @return string Value of locale like 'en_US', 'fr_FR', ... |
||
| 6770 | */ |
||
| 6771 | static function getLanguageCodeFromCountryCode($countrycode) |
||
| 6772 | {
|
||
| 6773 | // global $mysoc; |
||
| 6774 | |||
| 6775 | if (strtoupper($countrycode) == 'MQ') |
||
| 6776 | return 'fr_CA'; |
||
| 6777 | if (strtoupper($countrycode) == 'SE') |
||
| 6778 | return 'sv_SE'; // se_SE is Sami/Sweden, and we want in priority sv_SE for SE country |
||
| 6779 | if (strtoupper($countrycode) == 'CH') {
|
||
| 6780 | if ($mysoc->country_code == 'FR') |
||
| 6781 | return 'fr_CH'; |
||
| 6782 | if ($mysoc->country_code == 'DE') |
||
| 6783 | return 'de_CH'; |
||
| 6784 | } |
||
| 6785 | |||
| 6786 | // Locale list taken from: |
||
| 6787 | // http://stackoverflow.com/questions/3191664/ |
||
| 6788 | // list-of-all-locales-and-their-short-codes |
||
| 6789 | $locales = array( |
||
| 6790 | 'af-ZA', |
||
| 6791 | 'am-ET', |
||
| 6792 | 'ar-AE', |
||
| 6793 | 'ar-BH', |
||
| 6794 | 'ar-DZ', |
||
| 6795 | 'ar-EG', |
||
| 6796 | 'ar-IQ', |
||
| 6797 | 'ar-JO', |
||
| 6798 | 'ar-KW', |
||
| 6799 | 'ar-LB', |
||
| 6800 | 'ar-LY', |
||
| 6801 | 'ar-MA', |
||
| 6802 | 'ar-OM', |
||
| 6803 | 'ar-QA', |
||
| 6804 | 'ar-SA', |
||
| 6805 | 'ar-SY', |
||
| 6806 | 'ar-TN', |
||
| 6807 | 'ar-YE', |
||
| 6808 | 'as-IN', |
||
| 6809 | 'ba-RU', |
||
| 6810 | 'be-BY', |
||
| 6811 | 'bg-BG', |
||
| 6812 | 'bn-BD', |
||
| 6813 | 'bn-IN', |
||
| 6814 | 'bo-CN', |
||
| 6815 | 'br-FR', |
||
| 6816 | 'ca-ES', |
||
| 6817 | 'co-FR', |
||
| 6818 | 'cs-CZ', |
||
| 6819 | 'cy-GB', |
||
| 6820 | 'da-DK', |
||
| 6821 | 'de-AT', |
||
| 6822 | 'de-CH', |
||
| 6823 | 'de-DE', |
||
| 6824 | 'de-LI', |
||
| 6825 | 'de-LU', |
||
| 6826 | 'dv-MV', |
||
| 6827 | 'el-GR', |
||
| 6828 | 'en-AU', |
||
| 6829 | 'en-BZ', |
||
| 6830 | 'en-CA', |
||
| 6831 | 'en-GB', |
||
| 6832 | 'en-IE', |
||
| 6833 | 'en-IN', |
||
| 6834 | 'en-JM', |
||
| 6835 | 'en-MY', |
||
| 6836 | 'en-NZ', |
||
| 6837 | 'en-PH', |
||
| 6838 | 'en-SG', |
||
| 6839 | 'en-TT', |
||
| 6840 | 'en-US', |
||
| 6841 | 'en-ZA', |
||
| 6842 | 'en-ZW', |
||
| 6843 | 'es-AR', |
||
| 6844 | 'es-BO', |
||
| 6845 | 'es-CL', |
||
| 6846 | 'es-CO', |
||
| 6847 | 'es-CR', |
||
| 6848 | 'es-DO', |
||
| 6849 | 'es-EC', |
||
| 6850 | 'es-ES', |
||
| 6851 | 'es-GT', |
||
| 6852 | 'es-HN', |
||
| 6853 | 'es-MX', |
||
| 6854 | 'es-NI', |
||
| 6855 | 'es-PA', |
||
| 6856 | 'es-PE', |
||
| 6857 | 'es-PR', |
||
| 6858 | 'es-PY', |
||
| 6859 | 'es-SV', |
||
| 6860 | 'es-US', |
||
| 6861 | 'es-UY', |
||
| 6862 | 'es-VE', |
||
| 6863 | 'et-EE', |
||
| 6864 | 'eu-ES', |
||
| 6865 | 'fa-IR', |
||
| 6866 | 'fi-FI', |
||
| 6867 | 'fo-FO', |
||
| 6868 | 'fr-BE', |
||
| 6869 | 'fr-CA', |
||
| 6870 | 'fr-CH', |
||
| 6871 | 'fr-FR', |
||
| 6872 | 'fr-LU', |
||
| 6873 | 'fr-MC', |
||
| 6874 | 'fy-NL', |
||
| 6875 | 'ga-IE', |
||
| 6876 | 'gd-GB', |
||
| 6877 | 'gl-ES', |
||
| 6878 | 'gu-IN', |
||
| 6879 | 'he-IL', |
||
| 6880 | 'hi-IN', |
||
| 6881 | 'hr-BA', |
||
| 6882 | 'hr-HR', |
||
| 6883 | 'hu-HU', |
||
| 6884 | 'hy-AM', |
||
| 6885 | 'id-ID', |
||
| 6886 | 'ig-NG', |
||
| 6887 | 'ii-CN', |
||
| 6888 | 'is-IS', |
||
| 6889 | 'it-CH', |
||
| 6890 | 'it-IT', |
||
| 6891 | 'ja-JP', |
||
| 6892 | 'ka-GE', |
||
| 6893 | 'kk-KZ', |
||
| 6894 | 'kl-GL', |
||
| 6895 | 'km-KH', |
||
| 6896 | 'kn-IN', |
||
| 6897 | 'ko-KR', |
||
| 6898 | 'ky-KG', |
||
| 6899 | 'lb-LU', |
||
| 6900 | 'lo-LA', |
||
| 6901 | 'lt-LT', |
||
| 6902 | 'lv-LV', |
||
| 6903 | 'mi-NZ', |
||
| 6904 | 'mk-MK', |
||
| 6905 | 'ml-IN', |
||
| 6906 | 'mn-MN', |
||
| 6907 | 'mr-IN', |
||
| 6908 | 'ms-BN', |
||
| 6909 | 'ms-MY', |
||
| 6910 | 'mt-MT', |
||
| 6911 | 'nb-NO', |
||
| 6912 | 'ne-NP', |
||
| 6913 | 'nl-BE', |
||
| 6914 | 'nl-NL', |
||
| 6915 | 'nn-NO', |
||
| 6916 | 'oc-FR', |
||
| 6917 | 'or-IN', |
||
| 6918 | 'pa-IN', |
||
| 6919 | 'pl-PL', |
||
| 6920 | 'ps-AF', |
||
| 6921 | 'pt-BR', |
||
| 6922 | 'pt-PT', |
||
| 6923 | 'rm-CH', |
||
| 6924 | 'ro-RO', |
||
| 6925 | 'ru-RU', |
||
| 6926 | 'rw-RW', |
||
| 6927 | 'sa-IN', |
||
| 6928 | 'se-FI', |
||
| 6929 | 'se-NO', |
||
| 6930 | 'se-SE', |
||
| 6931 | 'si-LK', |
||
| 6932 | 'sk-SK', |
||
| 6933 | 'sl-SI', |
||
| 6934 | 'sq-AL', |
||
| 6935 | 'sv-FI', |
||
| 6936 | 'sv-SE', |
||
| 6937 | 'sw-KE', |
||
| 6938 | 'ta-IN', |
||
| 6939 | 'te-IN', |
||
| 6940 | 'th-TH', |
||
| 6941 | 'tk-TM', |
||
| 6942 | 'tn-ZA', |
||
| 6943 | 'tr-TR', |
||
| 6944 | 'tt-RU', |
||
| 6945 | 'ug-CN', |
||
| 6946 | 'uk-UA', |
||
| 6947 | 'ur-PK', |
||
| 6948 | 'vi-VN', |
||
| 6949 | 'wo-SN', |
||
| 6950 | 'xh-ZA', |
||
| 6951 | 'yo-NG', |
||
| 6952 | 'zh-CN', |
||
| 6953 | 'zh-HK', |
||
| 6954 | 'zh-MO', |
||
| 6955 | 'zh-SG', |
||
| 6956 | 'zh-TW', |
||
| 6957 | 'zu-ZA', |
||
| 6958 | ); |
||
| 6959 | |||
| 6960 | $buildprimarykeytotest = strtolower($countrycode) . '-' . strtoupper($countrycode); |
||
| 6961 | if (in_array($buildprimarykeytotest, $locales)) |
||
| 6962 | return strtolower($countrycode) . '_' . strtoupper($countrycode); |
||
| 6963 | |||
| 6964 | foreach ($locales as $locale) {
|
||
| 6965 | $locale_language = locale_get_primary_language($locale); |
||
| 6966 | $locale_region = locale_get_region($locale); |
||
| 6967 | if (strtoupper($countrycode) == $locale_region) {
|
||
| 6968 | //var_dump($locale.'-'.$locale_language.'-'.$locale_region); |
||
| 6969 | return strtolower($locale_language) . '_' . strtoupper($locale_region); |
||
| 6970 | } |
||
| 6971 | } |
||
| 6972 | |||
| 6973 | return null; |
||
| 6974 | } |
||
| 6975 | |||
| 6976 | /** |
||
| 6977 | * Complete or removed entries into a head array (used to build tabs). |
||
| 6978 | * For example, with value added by external modules. Such values are declared into Globals::$conf->modules_parts['tab']. |
||
| 6979 | * Or by change using hook completeTabsHead |
||
| 6980 | * |
||
| 6981 | * @param Conf $conf Object conf |
||
| 6982 | * @param Translate Globals::$langs Object langs |
||
| 6983 | * @param object|null $object Object object |
||
| 6984 | * @param array $head Object head |
||
| 6985 | * @param int $h New position to fill |
||
| 6986 | * @param string $type Value for object where objectvalue can be |
||
| 6987 | * 'thirdparty' to add a tab in third party view |
||
| 6988 | * 'intervention' to add a tab in intervention view |
||
| 6989 | * 'supplier_order' to add a tab in supplier order view |
||
| 6990 | * 'supplier_invoice' to add a tab in supplier invoice view |
||
| 6991 | * 'invoice' to add a tab in customer invoice view |
||
| 6992 | * 'order' to add a tab in customer order view |
||
| 6993 | * 'contract' to add a tabl in contract view |
||
| 6994 | * 'product' to add a tab in product view |
||
| 6995 | * 'propal' to add a tab in propal view |
||
| 6996 | * 'user' to add a tab in user view |
||
| 6997 | * 'group' to add a tab in group view |
||
| 6998 | * 'member' to add a tab in fundation member view |
||
| 6999 | * 'categories_x' to add a tab in category view ('x': type of category (0=product, 1=supplier, 2=customer, 3=member)
|
||
| 7000 | * 'ecm' to add a tab for another ecm view |
||
| 7001 | * 'stock' to add a tab for warehouse view |
||
| 7002 | * @param string $mode 'add' to complete head, 'remove' to remove entries |
||
| 7003 | * @return void |
||
| 7004 | */ |
||
| 7005 | static function complete_head_from_modules($conf, $langs, $object, &$head, &$h, $type, $mode = 'add') |
||
| 7006 | {
|
||
| 7007 | // global Globals::$hookManager; |
||
| 7008 | |||
| 7009 | if (isset(Globals::$conf->modules_parts['tabs'][$type]) && is_array(Globals::$conf->modules_parts['tabs'][$type])) {
|
||
| 7010 | foreach (Globals::$conf->modules_parts['tabs'][$type] as $value) {
|
||
| 7011 | |||
| 7012 | $values = explode(':', $value);
|
||
| 7013 | |||
| 7014 | if ($mode == 'add' && !preg_match('/^\-/', $values[1])) {
|
||
| 7015 | if (count($values) == 6) { // new declaration with permissions: $value='objecttype:+tabname1:Title1:langfile@mymodule:$user->rights->mymodule->read:/mymodule/mynewtab1.php?id=__ID__'
|
||
| 7016 | if ($values[0] != $type) |
||
| 7017 | continue; |
||
| 7018 | |||
| 7019 | if (verifCond($values[4])) {
|
||
| 7020 | if ($values[3]) |
||
| 7021 | Globals::$langs->load($values[3]); |
||
| 7022 | if (preg_match('/SUBSTITUTION_([^_]+)/i', $values[2], $reg)) {
|
||
| 7023 | $substitutionarray = array(); |
||
| 7024 | complete_substitutions_array($substitutionarray, Globals::$langs, $object, array('needforkey' => $values[2]));
|
||
| 7025 | $label = make_substitutions($reg[1], $substitutionarray); |
||
| 7026 | } else |
||
| 7027 | $label = Globals::$langs->trans($values[2]); |
||
| 7028 | |||
| 7029 | //$head[$h][0] = dol_buildpath(preg_replace('/__ID__/i', ((is_object($object) && !empty($object->id)) ? $object->id : ''), $values[5]), 1);
|
||
| 7030 | $head[$h][0] = BASE_URI . preg_replace('/__ID__/i', ((is_object($object) && !empty($object->id)) ? $object->id : ''), $values[5]);
|
||
| 7031 | $head[$h][1] = $label; |
||
| 7032 | $head[$h][2] = str_replace('+', '', $values[1]);
|
||
| 7033 | $h++; |
||
| 7034 | } |
||
| 7035 | } |
||
| 7036 | else if (count($values) == 5) { // deprecated
|
||
| 7037 | AlDolUtils::dol_syslog('Passing 5 values in tabs module_parts is deprecated. Please update to 6 with permissions.', LOG_WARNING);
|
||
| 7038 | |||
| 7039 | if ($values[0] != $type) |
||
| 7040 | continue; |
||
| 7041 | if ($values[3]) |
||
| 7042 | Globals::$langs->load($values[3]); |
||
| 7043 | if (preg_match('/SUBSTITUTION_([^_]+)/i', $values[2], $reg)) {
|
||
| 7044 | $substitutionarray = array(); |
||
| 7045 | complete_substitutions_array($substitutionarray, Globals::$langs, $object, array('needforkey' => $values[2]));
|
||
| 7046 | $label = make_substitutions($reg[1], $substitutionarray); |
||
| 7047 | } else |
||
| 7048 | $label = Globals::$langs->trans($values[2]); |
||
| 7049 | |||
| 7050 | $head[$h][0] = dol_buildpath(preg_replace('/__ID__/i', ((is_object($object) && !empty($object->id)) ? $object->id : ''), $values[4]), 1);
|
||
| 7051 | $head[$h][1] = $label; |
||
| 7052 | $head[$h][2] = str_replace('+', '', $values[1]);
|
||
| 7053 | $h++; |
||
| 7054 | } |
||
| 7055 | } |
||
| 7056 | else if ($mode == 'remove' && preg_match('/^\-/', $values[1])) {
|
||
| 7057 | if ($values[0] != $type) |
||
| 7058 | continue; |
||
| 7059 | $tabname = str_replace('-', '', $values[1]);
|
||
| 7060 | foreach ($head as $key => $val) {
|
||
| 7061 | $condition = (!empty($values[3]) ? verifCond($values[3]) : 1); |
||
| 7062 | //var_dump($key.' - '.$tabname.' - '.$head[$key][2].' - '.$values[3].' - '.$condition); |
||
| 7063 | if ($head[$key][2] == $tabname && $condition) {
|
||
| 7064 | unset($head[$key]); |
||
| 7065 | break; |
||
| 7066 | } |
||
| 7067 | } |
||
| 7068 | } |
||
| 7069 | } |
||
| 7070 | } |
||
| 7071 | |||
| 7072 | // No need to make a return $head. Var is modified as a reference |
||
| 7073 | if (!empty(Globals::$hookManager)) {
|
||
| 7074 | $parameters = array('object' => $object, 'mode' => $mode, 'head' => $head);
|
||
| 7075 | $reshook = Globals::$hookManager->executeHooks('completeTabsHead', $parameters);
|
||
| 7076 | if ($reshook > 0) {
|
||
| 7077 | $head = Globals::$hookManager->resArray; |
||
| 7078 | $h = count($head); |
||
| 7079 | } |
||
| 7080 | } |
||
| 7081 | } |
||
| 7082 | |||
| 7083 | /** |
||
| 7084 | * Print common footer : |
||
| 7085 | * conf->global->MAIN_HTML_FOOTER |
||
| 7086 | * js for switch of menu hider |
||
| 7087 | * js for conf->global->MAIN_GOOGLE_AN_ID |
||
| 7088 | * js for conf->global->MAIN_SHOW_TUNING_INFO or $_SERVER["MAIN_SHOW_TUNING_INFO"] |
||
| 7089 | * js for conf->logbuffer |
||
| 7090 | * |
||
| 7091 | * @param string $zone 'private' (for private pages) or 'public' (for public pages) |
||
| 7092 | * @return void |
||
| 7093 | */ |
||
| 7094 | static function printCommonFooter($zone = 'private') |
||
| 7095 | {
|
||
| 7096 | // global Globals::$conf, Globals::$hookManager, $user; |
||
| 7097 | // global $action; |
||
| 7098 | // global $micro_start_time; |
||
| 7099 | |||
| 7100 | if ($zone == 'private') |
||
| 7101 | print "\n" . '<!-- Common footer for private page -->' . "\n"; |
||
| 7102 | else |
||
| 7103 | print "\n" . '<!-- Common footer for public page -->' . "\n"; |
||
| 7104 | |||
| 7105 | // A div to store page_y POST parameter so we can read it using javascript |
||
| 7106 | print "\n<!-- A div to store page_y POST paramater -->\n"; |
||
| 7107 | print '<div id="page_y" style="display: none;">' . filter_input(INPUT_POST, 'page_y') . '</div>' . "\n"; |
||
| 7108 | |||
| 7109 | $parameters = array(); |
||
| 7110 | $reshook = Globals::$hookManager->executeHooks('printCommonFooter', $parameters); // Note that $action and $object may have been modified by some hooks
|
||
| 7111 | if (empty($reshook)) {
|
||
| 7112 | if (!empty(Globals::$conf->global->MAIN_HTML_FOOTER)) |
||
| 7113 | print Globals::$conf->global->MAIN_HTML_FOOTER . "\n"; |
||
| 7114 | |||
| 7115 | print "\n"; |
||
| 7116 | if (!empty(Globals::$conf->use_javascript_ajax)) {
|
||
| 7117 | print '<script type="text/javascript" language="javascript">' . "\n"; |
||
| 7118 | print 'jQuery(document).ready(function() {' . "\n";
|
||
| 7119 | |||
| 7120 | if ($zone == 'private' && empty(Globals::$conf->dol_use_jmobile)) {
|
||
| 7121 | print "\n"; |
||
| 7122 | print '/* JS CODE TO ENABLE to manage handler to switch left menu page (menuhider) */' . "\n"; |
||
| 7123 | print 'jQuery(".menuhider").click(function() {';
|
||
| 7124 | print ' console.log("We click on .menuhider");' . "\n";
|
||
| 7125 | //print " $('.side-nav').animate({width:'toggle'},200);\n"; // OK with eldy theme but not with md
|
||
| 7126 | print " $('.side-nav').toggle()\n";
|
||
| 7127 | print " $('.login_block').toggle()\n";
|
||
| 7128 | print '});' . "\n"; |
||
| 7129 | } |
||
| 7130 | |||
| 7131 | // Management of focus and mandatory for fields |
||
| 7132 | if ($action == 'create' || $action == 'edit' || (empty($action) && (preg_match('/new\.php/', $_SERVER["PHP_SELF"])))) {
|
||
| 7133 | print '/* JS CODE TO ENABLE to manage focus and mandatory form fields */' . "\n"; |
||
| 7134 | $relativepathstring = $_SERVER["PHP_SELF"]; |
||
| 7135 | // Clean $relativepathstring |
||
| 7136 | if (constant('DOL_BASE_URI'))
|
||
| 7137 | $relativepathstring = preg_replace('/^' . preg_quote(constant('DOL_BASE_URI'), '/') . '/', '', $relativepathstring);
|
||
| 7138 | $relativepathstring = preg_replace('/^\//', '', $relativepathstring);
|
||
| 7139 | $relativepathstring = preg_replace('/^custom\//', '', $relativepathstring);
|
||
| 7140 | $tmpqueryarraywehave = explode('&', dol_string_nohtmltag($_SERVER['QUERY_STRING']));
|
||
| 7141 | if (!empty($user->default_values[$relativepathstring]['focus'])) {
|
||
| 7142 | foreach ($user->default_values[$relativepathstring]['focus'] as $defkey => $defval) {
|
||
| 7143 | $qualified = 0; |
||
| 7144 | if ($defkey != '_noquery_') {
|
||
| 7145 | $tmpqueryarraytohave = explode('&', $defkey);
|
||
| 7146 | $foundintru = 0; |
||
| 7147 | foreach ($tmpqueryarraytohave as $tmpquerytohave) {
|
||
| 7148 | if (!in_array($tmpquerytohave, $tmpqueryarraywehave)) |
||
| 7149 | $foundintru = 1; |
||
| 7150 | } |
||
| 7151 | if (!$foundintru) |
||
| 7152 | $qualified = 1; |
||
| 7153 | //var_dump($defkey.'-'.$qualified); |
||
| 7154 | } else |
||
| 7155 | $qualified = 1; |
||
| 7156 | |||
| 7157 | if ($qualified) {
|
||
| 7158 | foreach ($defval as $paramkey => $paramval) {
|
||
| 7159 | // Set focus on field |
||
| 7160 | print 'jQuery("input[name=\'' . $paramkey . '\']").focus();' . "\n";
|
||
| 7161 | print 'jQuery("textarea[name=\'' . $paramkey . '\']").focus();' . "\n";
|
||
| 7162 | print 'jQuery("select[name=\'' . $paramkey . '\']").focus();' . "\n"; // Not really usefull, but we keep it in case of.
|
||
| 7163 | } |
||
| 7164 | } |
||
| 7165 | } |
||
| 7166 | } |
||
| 7167 | if (!empty($user->default_values[$relativepathstring]['mandatory'])) {
|
||
| 7168 | foreach ($user->default_values[$relativepathstring]['mandatory'] as $defkey => $defval) {
|
||
| 7169 | $qualified = 0; |
||
| 7170 | if ($defkey != '_noquery_') {
|
||
| 7171 | $tmpqueryarraytohave = explode('&', $defkey);
|
||
| 7172 | $foundintru = 0; |
||
| 7173 | foreach ($tmpqueryarraytohave as $tmpquerytohave) {
|
||
| 7174 | if (!in_array($tmpquerytohave, $tmpqueryarraywehave)) |
||
| 7175 | $foundintru = 1; |
||
| 7176 | } |
||
| 7177 | if (!$foundintru) |
||
| 7178 | $qualified = 1; |
||
| 7179 | //var_dump($defkey.'-'.$qualified); |
||
| 7180 | } else |
||
| 7181 | $qualified = 1; |
||
| 7182 | |||
| 7183 | if ($qualified) {
|
||
| 7184 | foreach ($defval as $paramkey => $paramval) {
|
||
| 7185 | // Add property 'required' on input |
||
| 7186 | print 'jQuery("input[name=\'' . $paramkey . '\']").prop(\'required\',true);' . "\n";
|
||
| 7187 | print 'jQuery("textarea[name=\'' . $paramkey . '\']").prop(\'required\',true);' . "\n";
|
||
| 7188 | print 'jQuery("select[name=\'' . $paramkey . '\']").prop(\'required\',true);' . "\n"; // required on a select works only if key is "", this does not happen in Dolibarr
|
||
| 7189 | } |
||
| 7190 | } |
||
| 7191 | } |
||
| 7192 | } |
||
| 7193 | } |
||
| 7194 | |||
| 7195 | print '});' . "\n"; |
||
| 7196 | |||
| 7197 | // Google Analytics |
||
| 7198 | // TODO Add a hook here |
||
| 7199 | if (!empty(Globals::$conf->google->enabled) && !empty(Globals::$conf->global->MAIN_GOOGLE_AN_ID)) {
|
||
| 7200 | if ((Globals::$conf->dol_use_jmobile != 4)) {
|
||
| 7201 | print "\n"; |
||
| 7202 | print "/* JS CODE TO ENABLE for google analtics tag */\n"; |
||
| 7203 | print ' var _gaq = _gaq || [];' . "\n"; |
||
| 7204 | print ' _gaq.push([\'_setAccount\', \'' . Globals::$conf->global->MAIN_GOOGLE_AN_ID . '\']);' . "\n"; |
||
| 7205 | print ' _gaq.push([\'_trackPageview\']);' . "\n"; |
||
| 7206 | print '' . "\n"; |
||
| 7207 | print ' (function() {' . "\n";
|
||
| 7208 | print ' var ga = document.createElement(\'script\'); ga.type = \'text/javascript\'; ga.async = true;' . "\n"; |
||
| 7209 | print ' ga.src = (\'https:\' == document.location.protocol ? \'https://ssl\' : \'http://www\') + \'.google-analytics.com/ga.js\';' . "\n"; |
||
| 7210 | print ' var s = document.getElementsByTagName(\'script\')[0]; s.parentNode.insertBefore(ga, s);' . "\n"; |
||
| 7211 | print ' })();' . "\n"; |
||
| 7212 | } |
||
| 7213 | } |
||
| 7214 | |||
| 7215 | // End of tuning |
||
| 7216 | if (!empty($_SERVER['MAIN_SHOW_TUNING_INFO']) || !empty(Globals::$conf->global->MAIN_SHOW_TUNING_INFO)) {
|
||
| 7217 | print "\n"; |
||
| 7218 | print "/* JS CODE TO ENABLE to add memory info */\n"; |
||
| 7219 | print 'window.console && console.log("';
|
||
| 7220 | if (!empty(Globals::$conf->global->MEMCACHED_SERVER)) |
||
| 7221 | print 'MEMCACHED_SERVER=' . Globals::$conf->global->MEMCACHED_SERVER . ' - '; |
||
| 7222 | print 'MAIN_OPTIMIZE_SPEED=' . (isset(Globals::$conf->global->MAIN_OPTIMIZE_SPEED) ? Globals::$conf->global->MAIN_OPTIMIZE_SPEED : 'off'); |
||
| 7223 | if (!empty($micro_start_time)) { // Works only if MAIN_SHOW_TUNING_INFO is defined at $_SERVER level. Not in// global variable.
|
||
| 7224 | $micro_end_time = microtime(true); |
||
| 7225 | print ' - Build time: ' . ceil(1000 * ($micro_end_time - $micro_start_time)) . ' ms'; |
||
| 7226 | } |
||
| 7227 | if (function_exists("memory_get_usage")) {
|
||
| 7228 | print ' - Mem: ' . memory_get_usage(); |
||
| 7229 | } |
||
| 7230 | if (function_exists("xdebug_memory_usage")) {
|
||
| 7231 | print ' - XDebug time: ' . ceil(1000 * xdebug_time_index()) . ' ms'; |
||
| 7232 | print ' - XDebug mem: ' . xdebug_memory_usage(); |
||
| 7233 | print ' - XDebug mem peak: ' . xdebug_peak_memory_usage(); |
||
| 7234 | } |
||
| 7235 | if (function_exists("zend_loader_file_encoded")) {
|
||
| 7236 | print ' - Zend encoded file: ' . (zend_loader_file_encoded() ? 'yes' : 'no'); |
||
| 7237 | } |
||
| 7238 | print '");' . "\n"; |
||
| 7239 | } |
||
| 7240 | |||
| 7241 | print "\n" . '</script>' . "\n"; |
||
| 7242 | } |
||
| 7243 | |||
| 7244 | // Add Xdebug coverage of code |
||
| 7245 | if (defined('XDEBUGCOVERAGE')) {
|
||
| 7246 | print_r(xdebug_get_code_coverage()); |
||
| 7247 | } |
||
| 7248 | |||
| 7249 | // If there is some logs in buffer to show |
||
| 7250 | if (count(Globals::$conf->logbuffer)) {
|
||
| 7251 | print "\n"; |
||
| 7252 | print "<!-- Start of log output\n"; |
||
| 7253 | //print '<div class="hidden">'."\n"; |
||
| 7254 | foreach (Globals::$conf->logbuffer as $logline) {
|
||
| 7255 | print $logline . "<br>\n"; |
||
| 7256 | } |
||
| 7257 | //print '</div>'."\n"; |
||
| 7258 | print "End of log output -->\n"; |
||
| 7259 | } |
||
| 7260 | } |
||
| 7261 | } |
||
| 7262 | |||
| 7263 | /** |
||
| 7264 | * Split a string with 2 keys into key array. |
||
| 7265 | * For example: "A=1;B=2;C=2" is exploded into array('A'=>1,'B'=>2,'C'=>3)
|
||
| 7266 | * |
||
| 7267 | * @param string $string String to explode |
||
| 7268 | * @param string $delimiter Delimiter between each couple of data |
||
| 7269 | * @param string $kv Delimiter between key and value |
||
| 7270 | * @return array Array of data exploded |
||
| 7271 | */ |
||
| 7272 | static function dolExplodeIntoArray($string, $delimiter = ';', $kv = '=') |
||
| 7273 | {
|
||
| 7274 | if ($a = explode($delimiter, $string)) {
|
||
| 7275 | $ka = array(); |
||
| 7276 | foreach ($a as $s) { // each part
|
||
| 7277 | if ($s) {
|
||
| 7278 | if ($pos = strpos($s, $kv)) { // key/value delimiter
|
||
| 7279 | $ka[trim(substr($s, 0, $pos))] = trim(substr($s, $pos + strlen($kv))); |
||
| 7280 | } else { // key delimiter not found
|
||
| 7281 | $ka[] = trim($s); |
||
| 7282 | } |
||
| 7283 | } |
||
| 7284 | } |
||
| 7285 | return $ka; |
||
| 7286 | } |
||
| 7287 | return array(); |
||
| 7288 | } |
||
| 7289 | |||
| 7290 | /** |
||
| 7291 | * Set focus onto field with selector (similar behaviour of 'autofocus' HTML5 tag) |
||
| 7292 | * |
||
| 7293 | * @param string $selector Selector ('#id' or 'input[name="ref"]') to use to find the HTML input field that must get the autofocus. You must use a CSS selector, so unique id preceding with the '#' char.
|
||
| 7294 | * @return string HTML code to set focus |
||
| 7295 | */ |
||
| 7296 | static function dol_set_focus($selector) |
||
| 7297 | {
|
||
| 7298 | print "\n" . '<!-- Set focus onto a specific field -->' . "\n"; |
||
| 7299 | print '<script type="text/javascript" language="javascript">jQuery(document).ready(function() { jQuery("' . dol_escape_js($selector) . '").focus(); });</script>' . "\n";
|
||
| 7300 | } |
||
| 7301 | |||
| 7302 | /** |
||
| 7303 | * Return getmypid() or random PID when static function is disabled |
||
| 7304 | * Some web hosts disable this php static function for security reasons |
||
| 7305 | * and sometimes we can't redeclare function |
||
| 7306 | * |
||
| 7307 | * @return int |
||
| 7308 | */ |
||
| 7309 | static function dol_getmypid() |
||
| 7310 | {
|
||
| 7311 | if (!function_exists('getmypid')) {
|
||
| 7312 | return mt_rand(1, 32768); |
||
| 7313 | } else {
|
||
| 7314 | return getmypid(); |
||
| 7315 | } |
||
| 7316 | } |
||
| 7317 | |||
| 7318 | /** |
||
| 7319 | * Generate natural SQL search string for a criteria (this criteria can be tested on one or several fields) |
||
| 7320 | * |
||
| 7321 | * @param string|string[] $fields String or array of strings, filled with the name of all fields in the SQL query we must check (combined with a OR). Example: array("p.field1","p.field2")
|
||
| 7322 | * @param string $value The value to look for. |
||
| 7323 | * If param $mode is 0, can contains several keywords separated with a space or | |
||
| 7324 | * like "keyword1 keyword2" = We want record field like keyword1 AND field like keyword2 |
||
| 7325 | * or like "keyword1|keyword2" = We want record field like keyword1 OR field like keyword2 |
||
| 7326 | * If param $mode is 1, can contains an operator <, > or = like "<10" or ">=100.5 < 1000" |
||
| 7327 | * If param $mode is 2, can contains a list of int id separated by comma like "1,3,4" |
||
| 7328 | * If param $mode is 3, can contains a list of string separated by comma like "a,b,c" |
||
| 7329 | * @param integer $mode 0=value is list of keyword strings, 1=value is a numeric test (Example ">5.5 <10"), 2=value is a list of ID separated with comma (Example '1,3,4') |
||
| 7330 | * 3=value is list of string separated with comma (Example 'text 1,text 2'), 4=value is a list of ID separated with comma (Example '1,3,4') for search into a multiselect string ('1,2')
|
||
| 7331 | * @param integer $nofirstand 1=Do not output the first 'AND' |
||
| 7332 | * @return string $res The statement to append to the SQL query |
||
| 7333 | */ |
||
| 7334 | static function natural_search($fields, $value, $mode = 0, $nofirstand = 0) |
||
| 7335 | {
|
||
| 7336 | // global $db, Globals::$langs; |
||
| 7337 | |||
| 7338 | $value = trim($value); |
||
| 7339 | |||
| 7340 | if ($mode == 0) {
|
||
| 7341 | $value = preg_replace('/\*/', '%', $value); // Replace * with %
|
||
| 7342 | } |
||
| 7343 | if ($mode == 1) {
|
||
| 7344 | $value = preg_replace('/([<>=]+)\s+([0-9' . preg_quote(Globals::$langs->trans("DecimalSeparator"), '/') . '\-])/', '\1\2', $value); // Clean string '< 10' into '<10' so we can the explode on space to get all tests to do
|
||
| 7345 | } |
||
| 7346 | |||
| 7347 | $value = preg_replace('/\s*\|\s*/', '|', $value);
|
||
| 7348 | |||
| 7349 | $crits = explode(' ', $value);
|
||
| 7350 | $res = ''; |
||
| 7351 | if (!is_array($fields)) |
||
| 7352 | $fields = array($fields); |
||
| 7353 | |||
| 7354 | $nboffields = count($fields); |
||
| 7355 | $end2 = count($crits); |
||
| 7356 | $j = 0; |
||
| 7357 | foreach ($crits as $crit) {
|
||
| 7358 | $i = 0; |
||
| 7359 | $i2 = 0; |
||
| 7360 | $newres = ''; |
||
| 7361 | foreach ($fields as $field) {
|
||
| 7362 | if ($mode == 1) {
|
||
| 7363 | $operator = '='; |
||
| 7364 | $newcrit = preg_replace('/([<>=]+)/', '', trim($crit));
|
||
| 7365 | |||
| 7366 | preg_match('/([<>=]+)/', trim($crit), $reg);
|
||
| 7367 | if ($reg[1]) {
|
||
| 7368 | $operator = $reg[1]; |
||
| 7369 | } |
||
| 7370 | if ($newcrit != '') {
|
||
| 7371 | $numnewcrit = price2num($newcrit); |
||
| 7372 | if (is_numeric($numnewcrit)) {
|
||
| 7373 | $newres .= ($i2 > 0 ? ' OR ' : '') . $field . ' ' . $operator . ' ' . $numnewcrit; |
||
| 7374 | } else {
|
||
| 7375 | $newres .= ($i2 > 0 ? ' OR ' : '') . '1 = 2'; // force false |
||
| 7376 | } |
||
| 7377 | $i2++; // a criteria was added to string |
||
| 7378 | } |
||
| 7379 | } else if ($mode == 2) {
|
||
| 7380 | $newres .= ($i2 > 0 ? ' OR ' : '') . $field . " IN (" . $db->escape(trim($crit)) . ")";
|
||
| 7381 | $i2++; // a criteria was added to string |
||
| 7382 | } else if ($mode == 3) {
|
||
| 7383 | $tmparray = explode(',', trim($crit));
|
||
| 7384 | if (count($tmparray)) {
|
||
| 7385 | $listofcodes = ''; |
||
| 7386 | foreach ($tmparray as $val) {
|
||
| 7387 | if ($val) {
|
||
| 7388 | $listofcodes .= ($listofcodes ? ',' : ''); |
||
| 7389 | $listofcodes .= "'" . $db->escape(trim($val)) . "'"; |
||
| 7390 | } |
||
| 7391 | } |
||
| 7392 | $newres .= ($i2 > 0 ? ' OR ' : '') . $field . " IN (" . $listofcodes . ")";
|
||
| 7393 | $i2++; // a criteria was added to string |
||
| 7394 | } |
||
| 7395 | } else if ($mode == 4) {
|
||
| 7396 | $tmparray = explode(',', trim($crit));
|
||
| 7397 | if (count($tmparray)) {
|
||
| 7398 | $listofcodes = ''; |
||
| 7399 | foreach ($tmparray as $val) {
|
||
| 7400 | if ($val) {
|
||
| 7401 | $newres .= ($i2 > 0 ? ' OR (' : '(') . $field . ' LIKE \'' . $db->escape(trim($val)) . ',%\'';
|
||
| 7402 | $newres .= ' OR ' . $field . ' = \'' . $db->escape(trim($val)) . '\''; |
||
| 7403 | $newres .= ' OR ' . $field . ' LIKE \'%,' . $db->escape(trim($val)) . '\''; |
||
| 7404 | $newres .= ' OR ' . $field . ' LIKE \'%,' . $db->escape(trim($val)) . ',%\''; |
||
| 7405 | $newres .= ')'; |
||
| 7406 | $i2++; |
||
| 7407 | } |
||
| 7408 | } |
||
| 7409 | } |
||
| 7410 | } else { // $mode=0
|
||
| 7411 | $textcrit = ''; |
||
| 7412 | $tmpcrits = explode('|', $crit);
|
||
| 7413 | $i3 = 0; |
||
| 7414 | foreach ($tmpcrits as $tmpcrit) {
|
||
| 7415 | if (empty($tmpcrit)) |
||
| 7416 | continue; |
||
| 7417 | |||
| 7418 | $newres .= (($i2 > 0 || $i3 > 0) ? ' OR ' : ''); |
||
| 7419 | |||
| 7420 | if (preg_match('/\.(id|rowid)$/', $field)) { // Special case for rowid that is sometimes a ref so used as a search field
|
||
| 7421 | $newres .= $field . " = " . (is_numeric(trim($tmpcrit)) ? trim($tmpcrit) : '0'); |
||
| 7422 | } else {
|
||
| 7423 | $newres .= $field . " LIKE '"; |
||
| 7424 | |||
| 7425 | $tmpcrit = trim($tmpcrit); |
||
| 7426 | $tmpcrit2 = $tmpcrit; |
||
| 7427 | $tmpbefore = '%'; |
||
| 7428 | $tmpafter = '%'; |
||
| 7429 | if (preg_match('/^[\^\$]/', $tmpcrit)) {
|
||
| 7430 | $tmpbefore = ''; |
||
| 7431 | $tmpcrit2 = preg_replace('/^[\^\$]/', '', $tmpcrit2);
|
||
| 7432 | } |
||
| 7433 | if (preg_match('/[\^\$]$/', $tmpcrit)) {
|
||
| 7434 | $tmpafter = ''; |
||
| 7435 | $tmpcrit2 = preg_replace('/[\^\$]$/', '', $tmpcrit2);
|
||
| 7436 | } |
||
| 7437 | $newres .= $tmpbefore; |
||
| 7438 | $newres .= $db->escape($tmpcrit2); |
||
| 7439 | $newres .= $tmpafter; |
||
| 7440 | $newres .= "'"; |
||
| 7441 | if ($tmpcrit2 == '') {
|
||
| 7442 | $newres .= ' OR ' . $field . " IS NULL"; |
||
| 7443 | } |
||
| 7444 | } |
||
| 7445 | |||
| 7446 | $i3++; |
||
| 7447 | } |
||
| 7448 | $i2++; // a criteria was added to string |
||
| 7449 | } |
||
| 7450 | $i++; |
||
| 7451 | } |
||
| 7452 | if ($newres) |
||
| 7453 | $res = $res . ($res ? ' AND ' : '') . ($i2 > 1 ? '(' : '') . $newres . ($i2 > 1 ? ')' : '');
|
||
| 7454 | $j++; |
||
| 7455 | } |
||
| 7456 | $res = ($nofirstand ? "" : " AND ") . "(" . $res . ")";
|
||
| 7457 | //print 'xx'.$res.'yy'; |
||
| 7458 | return $res; |
||
| 7459 | } |
||
| 7460 | |||
| 7461 | /** |
||
| 7462 | * Return string with full Url. The file qualified is the one defined by relative path in $object->last_main_doc |
||
| 7463 | * |
||
| 7464 | * @param Object $object Object |
||
| 7465 | * @return string Url string |
||
| 7466 | */ |
||
| 7467 | static function showDirectDownloadLink($object) |
||
| 7468 | {
|
||
| 7469 | // global Globals::$conf, Globals::$langs; |
||
| 7470 | |||
| 7471 | $out = ''; |
||
| 7472 | $url = $object->getLastMainDocLink($object->element); |
||
| 7473 | |||
| 7474 | if ($url) {
|
||
| 7475 | $out .= img_picto('', 'object_globe.png') . ' ' . Globals::$langs->trans("DirectDownloadLink") . '<br>';
|
||
| 7476 | $out .= '<input type="text" id="directdownloadlink" class="quatrevingtpercent" value="' . $url . '">'; |
||
| 7477 | $out .= ajax_autoselect("directdownloadlink", 0);
|
||
| 7478 | } |
||
| 7479 | return $out; |
||
| 7480 | } |
||
| 7481 | |||
| 7482 | /** |
||
| 7483 | * Return the filename of file to get the thumbs |
||
| 7484 | * |
||
| 7485 | * @param string $file Original filename (full or relative path) |
||
| 7486 | * @param string $extName Extension to differenciate thumb file name ('', '_small', '_mini')
|
||
| 7487 | * @param string $extImgTarget Force image extension for thumbs. Use '' to keep same extension than original image (default). |
||
| 7488 | * @return string New file name (full or relative path, including the thumbs/) |
||
| 7489 | */ |
||
| 7490 | static function getImageFileNameForSize($file, $extName, $extImgTarget = '') |
||
| 7491 | {
|
||
| 7492 | $dirName = dirname($file); |
||
| 7493 | if ($dirName == '.') |
||
| 7494 | $dirName = ''; |
||
| 7495 | |||
| 7496 | $fileName = preg_replace('/(\.gif|\.jpeg|\.jpg|\.png|\.bmp)$/i', '', $file); // We remove extension, whatever is its case
|
||
| 7497 | $fileName = basename($fileName); |
||
| 7498 | |||
| 7499 | if (empty($extImgTarget)) |
||
| 7500 | $extImgTarget = (preg_match('/\.jpg$/i', $file) ? '.jpg' : '');
|
||
| 7501 | if (empty($extImgTarget)) |
||
| 7502 | $extImgTarget = (preg_match('/\.jpeg$/i', $file) ? '.jpeg' : '');
|
||
| 7503 | if (empty($extImgTarget)) |
||
| 7504 | $extImgTarget = (preg_match('/\.gif$/i', $file) ? '.gif' : '');
|
||
| 7505 | if (empty($extImgTarget)) |
||
| 7506 | $extImgTarget = (preg_match('/\.png$/i', $file) ? '.png' : '');
|
||
| 7507 | if (empty($extImgTarget)) |
||
| 7508 | $extImgTarget = (preg_match('/\.bmp$/i', $file) ? '.bmp' : '');
|
||
| 7509 | |||
| 7510 | if (!$extImgTarget) |
||
| 7511 | return $file; |
||
| 7512 | |||
| 7513 | $subdir = ''; |
||
| 7514 | if ($extName) |
||
| 7515 | $subdir = 'thumbs/'; |
||
| 7516 | |||
| 7517 | return ($dirName ? $dirName . '/' : '') . $subdir . $fileName . $extName . $extImgTarget; // New filename for thumb |
||
| 7518 | } |
||
| 7519 | |||
| 7520 | /** |
||
| 7521 | * Return URL we can use for advanced preview links |
||
| 7522 | * |
||
| 7523 | * @param string $modulepart propal, facture, facture_fourn, ... |
||
| 7524 | * @param string $relativepath Relative path of docs. |
||
| 7525 | * @param int $alldata Return array with all components (1 is recommended, then use a simple a href link with the class, target and mime attribute added. 'documentpreview' css class is handled by jquery code into main.inc.php) |
||
| 7526 | * @param string $param More param on http links |
||
| 7527 | * @return string|array Output string with href link or array with all components of link |
||
| 7528 | */ |
||
| 7529 | static function getAdvancedPreviewUrl($modulepart, $relativepath, $alldata = 0, $param = '') |
||
| 7530 | {
|
||
| 7531 | // global Globals::$conf, Globals::$langs; |
||
| 7532 | |||
| 7533 | if (empty(Globals::$conf->use_javascript_ajax)) |
||
| 7534 | return ''; |
||
| 7535 | |||
| 7536 | $mime_preview = array('bmp', 'jpeg', 'png', 'gif', 'tiff', 'pdf', 'plain', 'css', 'svg+xml');
|
||
| 7537 | //$mime_preview[]='vnd.oasis.opendocument.presentation'; |
||
| 7538 | //$mime_preview[]='archive'; |
||
| 7539 | $num_mime = array_search(dol_mimetype($relativepath, '', 1), $mime_preview); |
||
| 7540 | |||
| 7541 | if ($alldata == 1) {
|
||
| 7542 | if ($num_mime !== false) |
||
| 7543 | return array('target' => '_blank', 'css' => 'documentpreview', 'url' => DOL_BASE_URI . '/document.php?modulepart=' . $modulepart . '&attachment=0&file=' . urlencode($relativepath) . ($param ? '&' . $param : ''), 'mime' => dol_mimetype($relativepath),);
|
||
| 7544 | else |
||
| 7545 | return array(); |
||
| 7546 | } |
||
| 7547 | |||
| 7548 | // old behavior |
||
| 7549 | if ($num_mime !== false) |
||
| 7550 | return 'javascript:document_preview(\'' . dol_escape_js(DOL_BASE_URI . '/document.php?modulepart=' . $modulepart . '&attachment=0&file=' . urlencode($relativepath) . ($param ? '&' . $param : '')) . '\', \'' . dol_mimetype($relativepath) . '\', \'' . dol_escape_js(Globals::$langs->trans('Preview')) . '\')';
|
||
| 7551 | else |
||
| 7552 | return ''; |
||
| 7553 | } |
||
| 7554 | |||
| 7555 | /** |
||
| 7556 | * Make content of an input box selected when we click into input field. |
||
| 7557 | * |
||
| 7558 | * @param string $htmlname Id of html object |
||
| 7559 | * @param string $addlink Add a 'link to' after |
||
| 7560 | * @return string |
||
| 7561 | */ |
||
| 7562 | static function ajax_autoselect($htmlname, $addlink = '') |
||
| 7563 | {
|
||
| 7564 | // global Globals::$langs; |
||
| 7565 | $out = '<script type="text/javascript"> |
||
| 7566 | jQuery(document).ready(static function () {
|
||
| 7567 | jQuery("#' . $htmlname . '").click(function() { jQuery(this).select(); } );
|
||
| 7568 | }); |
||
| 7569 | </script>'; |
||
| 7570 | if ($addlink) |
||
| 7571 | $out .= ' <a href="' . $addlink . '" target="_blank">' . Globals::$langs->trans("Link") . '</a>';
|
||
| 7572 | return $out; |
||
| 7573 | } |
||
| 7574 | |||
| 7575 | /** |
||
| 7576 | * Return mime type of a file |
||
| 7577 | * |
||
| 7578 | * @param string $file Filename we looking for MIME type |
||
| 7579 | * @param string $default Default mime type if extension not found in known list |
||
| 7580 | * @param int $mode 0=Return full mime, 1=otherwise short mime string, 2=image for mime type, 3=source language, 4=css of font fa |
||
| 7581 | * @return string Return a mime type family (text/xxx, application/xxx, image/xxx, audio, video, archive) |
||
| 7582 | * @see image_format_supported (images.lib.php) |
||
| 7583 | */ |
||
| 7584 | static function dol_mimetype($file, $default = 'application/octet-stream', $mode = 0) |
||
| 7585 | {
|
||
| 7586 | $mime = $default; |
||
| 7587 | $imgmime = 'other.png'; |
||
| 7588 | $famime = 'file-o'; |
||
| 7589 | $srclang = ''; |
||
| 7590 | |||
| 7591 | $tmpfile = preg_replace('/\.noexe$/', '', $file);
|
||
| 7592 | |||
| 7593 | // Text files |
||
| 7594 | if (preg_match('/\.txt$/i', $tmpfile)) {
|
||
| 7595 | $mime = 'text/plain'; |
||
| 7596 | $imgmime = 'text.png'; |
||
| 7597 | $famime = 'file-text-o'; |
||
| 7598 | } |
||
| 7599 | if (preg_match('/\.rtx$/i', $tmpfile)) {
|
||
| 7600 | $mime = 'text/richtext'; |
||
| 7601 | $imgmime = 'text.png'; |
||
| 7602 | $famime = 'file-text-o'; |
||
| 7603 | } |
||
| 7604 | if (preg_match('/\.csv$/i', $tmpfile)) {
|
||
| 7605 | $mime = 'text/csv'; |
||
| 7606 | $imgmime = 'text.png'; |
||
| 7607 | $famime = 'file-text-o'; |
||
| 7608 | } |
||
| 7609 | if (preg_match('/\.tsv$/i', $tmpfile)) {
|
||
| 7610 | $mime = 'text/tab-separated-values'; |
||
| 7611 | $imgmime = 'text.png'; |
||
| 7612 | $famime = 'file-text-o'; |
||
| 7613 | } |
||
| 7614 | if (preg_match('/\.(cf|conf|log)$/i', $tmpfile)) {
|
||
| 7615 | $mime = 'text/plain'; |
||
| 7616 | $imgmime = 'text.png'; |
||
| 7617 | $famime = 'file-text-o'; |
||
| 7618 | } |
||
| 7619 | if (preg_match('/\.ini$/i', $tmpfile)) {
|
||
| 7620 | $mime = 'text/plain'; |
||
| 7621 | $imgmime = 'text.png'; |
||
| 7622 | $srclang = 'ini'; |
||
| 7623 | $famime = 'file-text-o'; |
||
| 7624 | } |
||
| 7625 | if (preg_match('/\.css$/i', $tmpfile)) {
|
||
| 7626 | $mime = 'text/css'; |
||
| 7627 | $imgmime = 'css.png'; |
||
| 7628 | $srclang = 'css'; |
||
| 7629 | $famime = 'file-text-o'; |
||
| 7630 | } |
||
| 7631 | // Certificate files |
||
| 7632 | if (preg_match('/\.(crt|cer|key|pub)$/i', $tmpfile)) {
|
||
| 7633 | $mime = 'text/plain'; |
||
| 7634 | $imgmime = 'text.png'; |
||
| 7635 | $famime = 'file-text-o'; |
||
| 7636 | } |
||
| 7637 | // HTML/XML |
||
| 7638 | if (preg_match('/\.(html|htm|shtml)$/i', $tmpfile)) {
|
||
| 7639 | $mime = 'text/html'; |
||
| 7640 | $imgmime = 'html.png'; |
||
| 7641 | $srclang = 'html'; |
||
| 7642 | $famime = 'file-text-o'; |
||
| 7643 | } |
||
| 7644 | if (preg_match('/\.(xml|xhtml)$/i', $tmpfile)) {
|
||
| 7645 | $mime = 'text/xml'; |
||
| 7646 | $imgmime = 'other.png'; |
||
| 7647 | $srclang = 'xml'; |
||
| 7648 | $famime = 'file-text-o'; |
||
| 7649 | } |
||
| 7650 | // Languages |
||
| 7651 | if (preg_match('/\.bas$/i', $tmpfile)) {
|
||
| 7652 | $mime = 'text/plain'; |
||
| 7653 | $imgmime = 'text.png'; |
||
| 7654 | $srclang = 'bas'; |
||
| 7655 | $famime = 'file-code-o'; |
||
| 7656 | } |
||
| 7657 | if (preg_match('/\.(c)$/i', $tmpfile)) {
|
||
| 7658 | $mime = 'text/plain'; |
||
| 7659 | $imgmime = 'text.png'; |
||
| 7660 | $srclang = 'c'; |
||
| 7661 | $famime = 'file-code-o'; |
||
| 7662 | } |
||
| 7663 | if (preg_match('/\.(cpp)$/i', $tmpfile)) {
|
||
| 7664 | $mime = 'text/plain'; |
||
| 7665 | $imgmime = 'text.png'; |
||
| 7666 | $srclang = 'cpp'; |
||
| 7667 | $famime = 'file-code-o'; |
||
| 7668 | } |
||
| 7669 | if (preg_match('/\.(h)$/i', $tmpfile)) {
|
||
| 7670 | $mime = 'text/plain'; |
||
| 7671 | $imgmime = 'text.png'; |
||
| 7672 | $srclang = 'h'; |
||
| 7673 | $famime = 'file-code-o'; |
||
| 7674 | } |
||
| 7675 | if (preg_match('/\.(java|jsp)$/i', $tmpfile)) {
|
||
| 7676 | $mime = 'text/plain'; |
||
| 7677 | $imgmime = 'text.png'; |
||
| 7678 | $srclang = 'java'; |
||
| 7679 | $famime = 'file-code-o'; |
||
| 7680 | } |
||
| 7681 | if (preg_match('/\.php([0-9]{1})?$/i', $tmpfile)) {
|
||
| 7682 | $mime = 'text/plain'; |
||
| 7683 | $imgmime = 'php.png'; |
||
| 7684 | $srclang = 'php'; |
||
| 7685 | $famime = 'file-code-o'; |
||
| 7686 | } |
||
| 7687 | if (preg_match('/\.phtml$/i', $tmpfile)) {
|
||
| 7688 | $mime = 'text/plain'; |
||
| 7689 | $imgmime = 'php.png'; |
||
| 7690 | $srclang = 'php'; |
||
| 7691 | $famime = 'file-code-o'; |
||
| 7692 | } |
||
| 7693 | if (preg_match('/\.(pl|pm)$/i', $tmpfile)) {
|
||
| 7694 | $mime = 'text/plain'; |
||
| 7695 | $imgmime = 'pl.png'; |
||
| 7696 | $srclang = 'perl'; |
||
| 7697 | $famime = 'file-code-o'; |
||
| 7698 | } |
||
| 7699 | if (preg_match('/\.sql$/i', $tmpfile)) {
|
||
| 7700 | $mime = 'text/plain'; |
||
| 7701 | $imgmime = 'text.png'; |
||
| 7702 | $srclang = 'sql'; |
||
| 7703 | $famime = 'file-code-o'; |
||
| 7704 | } |
||
| 7705 | if (preg_match('/\.js$/i', $tmpfile)) {
|
||
| 7706 | $mime = 'text/x-javascript'; |
||
| 7707 | $imgmime = 'jscript.png'; |
||
| 7708 | $srclang = 'js'; |
||
| 7709 | $famime = 'file-code-o'; |
||
| 7710 | } |
||
| 7711 | // Open office |
||
| 7712 | if (preg_match('/\.odp$/i', $tmpfile)) {
|
||
| 7713 | $mime = 'application/vnd.oasis.opendocument.presentation'; |
||
| 7714 | $imgmime = 'ooffice.png'; |
||
| 7715 | $famime = 'file-powerpoint-o'; |
||
| 7716 | } |
||
| 7717 | if (preg_match('/\.ods$/i', $tmpfile)) {
|
||
| 7718 | $mime = 'application/vnd.oasis.opendocument.spreadsheet'; |
||
| 7719 | $imgmime = 'ooffice.png'; |
||
| 7720 | $famime = 'file-excel-o'; |
||
| 7721 | } |
||
| 7722 | if (preg_match('/\.odt$/i', $tmpfile)) {
|
||
| 7723 | $mime = 'application/vnd.oasis.opendocument.text'; |
||
| 7724 | $imgmime = 'ooffice.png'; |
||
| 7725 | $famime = 'file-word-o'; |
||
| 7726 | } |
||
| 7727 | // MS Office |
||
| 7728 | if (preg_match('/\.mdb$/i', $tmpfile)) {
|
||
| 7729 | $mime = 'application/msaccess'; |
||
| 7730 | $imgmime = 'mdb.png'; |
||
| 7731 | $famime = 'file-o'; |
||
| 7732 | } |
||
| 7733 | if (preg_match('/\.doc(x|m)?$/i', $tmpfile)) {
|
||
| 7734 | $mime = 'application/msword'; |
||
| 7735 | $imgmime = 'doc.png'; |
||
| 7736 | $famime = 'file-word-o'; |
||
| 7737 | } |
||
| 7738 | if (preg_match('/\.dot(x|m)?$/i', $tmpfile)) {
|
||
| 7739 | $mime = 'application/msword'; |
||
| 7740 | $imgmime = 'doc.png'; |
||
| 7741 | $famime = 'file-word-o'; |
||
| 7742 | } |
||
| 7743 | if (preg_match('/\.xlt(x)?$/i', $tmpfile)) {
|
||
| 7744 | $mime = 'application/vnd.ms-excel'; |
||
| 7745 | $imgmime = 'xls.png'; |
||
| 7746 | $famime = 'file-excel-o'; |
||
| 7747 | } |
||
| 7748 | if (preg_match('/\.xla(m)?$/i', $tmpfile)) {
|
||
| 7749 | $mime = 'application/vnd.ms-excel'; |
||
| 7750 | $imgmime = 'xls.png'; |
||
| 7751 | $famime = 'file-excel-o'; |
||
| 7752 | } |
||
| 7753 | if (preg_match('/\.xls$/i', $tmpfile)) {
|
||
| 7754 | $mime = 'application/vnd.ms-excel'; |
||
| 7755 | $imgmime = 'xls.png'; |
||
| 7756 | $famime = 'file-excel-o'; |
||
| 7757 | } |
||
| 7758 | if (preg_match('/\.xls(b|m|x)$/i', $tmpfile)) {
|
||
| 7759 | $mime = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; |
||
| 7760 | $imgmime = 'xls.png'; |
||
| 7761 | $famime = 'file-excel-o'; |
||
| 7762 | } |
||
| 7763 | if (preg_match('/\.pps(m|x)?$/i', $tmpfile)) {
|
||
| 7764 | $mime = 'application/vnd.ms-powerpoint'; |
||
| 7765 | $imgmime = 'ppt.png'; |
||
| 7766 | $famime = 'file-powerpoint-o'; |
||
| 7767 | } |
||
| 7768 | if (preg_match('/\.ppt(m|x)?$/i', $tmpfile)) {
|
||
| 7769 | $mime = 'application/x-mspowerpoint'; |
||
| 7770 | $imgmime = 'ppt.png'; |
||
| 7771 | $famime = 'file-powerpoint-o'; |
||
| 7772 | } |
||
| 7773 | // Other |
||
| 7774 | if (preg_match('/\.pdf$/i', $tmpfile)) {
|
||
| 7775 | $mime = 'application/pdf'; |
||
| 7776 | $imgmime = 'pdf.png'; |
||
| 7777 | $famime = 'file-pdf-o'; |
||
| 7778 | } |
||
| 7779 | // Scripts |
||
| 7780 | if (preg_match('/\.bat$/i', $tmpfile)) {
|
||
| 7781 | $mime = 'text/x-bat'; |
||
| 7782 | $imgmime = 'script.png'; |
||
| 7783 | $srclang = 'dos'; |
||
| 7784 | $famime = 'file-code-o'; |
||
| 7785 | } |
||
| 7786 | if (preg_match('/\.sh$/i', $tmpfile)) {
|
||
| 7787 | $mime = 'text/x-sh'; |
||
| 7788 | $imgmime = 'script.png'; |
||
| 7789 | $srclang = 'bash'; |
||
| 7790 | $famime = 'file-code-o'; |
||
| 7791 | } |
||
| 7792 | if (preg_match('/\.ksh$/i', $tmpfile)) {
|
||
| 7793 | $mime = 'text/x-ksh'; |
||
| 7794 | $imgmime = 'script.png'; |
||
| 7795 | $srclang = 'bash'; |
||
| 7796 | $famime = 'file-code-o'; |
||
| 7797 | } |
||
| 7798 | if (preg_match('/\.bash$/i', $tmpfile)) {
|
||
| 7799 | $mime = 'text/x-bash'; |
||
| 7800 | $imgmime = 'script.png'; |
||
| 7801 | $srclang = 'bash'; |
||
| 7802 | $famime = 'file-code-o'; |
||
| 7803 | } |
||
| 7804 | // Images |
||
| 7805 | if (preg_match('/\.ico$/i', $tmpfile)) {
|
||
| 7806 | $mime = 'image/x-icon'; |
||
| 7807 | $imgmime = 'image.png'; |
||
| 7808 | $famime = 'file-image-o'; |
||
| 7809 | } |
||
| 7810 | if (preg_match('/\.(jpg|jpeg)$/i', $tmpfile)) {
|
||
| 7811 | $mime = 'image/jpeg'; |
||
| 7812 | $imgmime = 'image.png'; |
||
| 7813 | $famime = 'file-image-o'; |
||
| 7814 | } |
||
| 7815 | if (preg_match('/\.png$/i', $tmpfile)) {
|
||
| 7816 | $mime = 'image/png'; |
||
| 7817 | $imgmime = 'image.png'; |
||
| 7818 | $famime = 'file-image-o'; |
||
| 7819 | } |
||
| 7820 | if (preg_match('/\.gif$/i', $tmpfile)) {
|
||
| 7821 | $mime = 'image/gif'; |
||
| 7822 | $imgmime = 'image.png'; |
||
| 7823 | $famime = 'file-image-o'; |
||
| 7824 | } |
||
| 7825 | if (preg_match('/\.bmp$/i', $tmpfile)) {
|
||
| 7826 | $mime = 'image/bmp'; |
||
| 7827 | $imgmime = 'image.png'; |
||
| 7828 | $famime = 'file-image-o'; |
||
| 7829 | } |
||
| 7830 | if (preg_match('/\.(tif|tiff)$/i', $tmpfile)) {
|
||
| 7831 | $mime = 'image/tiff'; |
||
| 7832 | $imgmime = 'image.png'; |
||
| 7833 | $famime = 'file-image-o'; |
||
| 7834 | } |
||
| 7835 | if (preg_match('/\.svg$/i', $tmpfile)) {
|
||
| 7836 | $mime = 'image/svg+xml'; |
||
| 7837 | $imgmime = 'image.png'; |
||
| 7838 | $famime = 'file-image-o'; |
||
| 7839 | } |
||
| 7840 | // Calendar |
||
| 7841 | if (preg_match('/\.vcs$/i', $tmpfile)) {
|
||
| 7842 | $mime = 'text/calendar'; |
||
| 7843 | $imgmime = 'other.png'; |
||
| 7844 | $famime = 'file-text-o'; |
||
| 7845 | } |
||
| 7846 | if (preg_match('/\.ics$/i', $tmpfile)) {
|
||
| 7847 | $mime = 'text/calendar'; |
||
| 7848 | $imgmime = 'other.png'; |
||
| 7849 | $famime = 'file-text-o'; |
||
| 7850 | } |
||
| 7851 | // Other |
||
| 7852 | if (preg_match('/\.torrent$/i', $tmpfile)) {
|
||
| 7853 | $mime = 'application/x-bittorrent'; |
||
| 7854 | $imgmime = 'other.png'; |
||
| 7855 | $famime = 'file-o'; |
||
| 7856 | } |
||
| 7857 | // Audio |
||
| 7858 | if (preg_match('/\.(mp3|ogg|au|wav|wma|mid)$/i', $tmpfile)) {
|
||
| 7859 | $mime = 'audio'; |
||
| 7860 | $imgmime = 'audio.png'; |
||
| 7861 | $famime = 'file-audio-o'; |
||
| 7862 | } |
||
| 7863 | // Video |
||
| 7864 | if (preg_match('/\.ogv$/i', $tmpfile)) {
|
||
| 7865 | $mime = 'video/ogg'; |
||
| 7866 | $imgmime = 'video.png'; |
||
| 7867 | $famime = 'file-video-o'; |
||
| 7868 | } |
||
| 7869 | if (preg_match('/\.webm$/i', $tmpfile)) {
|
||
| 7870 | $mime = 'video/webm'; |
||
| 7871 | $imgmime = 'video.png'; |
||
| 7872 | $famime = 'file-video-o'; |
||
| 7873 | } |
||
| 7874 | if (preg_match('/\.avi$/i', $tmpfile)) {
|
||
| 7875 | $mime = 'video/x-msvideo'; |
||
| 7876 | $imgmime = 'video.png'; |
||
| 7877 | $famime = 'file-video-o'; |
||
| 7878 | } |
||
| 7879 | if (preg_match('/\.divx$/i', $tmpfile)) {
|
||
| 7880 | $mime = 'video/divx'; |
||
| 7881 | $imgmime = 'video.png'; |
||
| 7882 | $famime = 'file-video-o'; |
||
| 7883 | } |
||
| 7884 | if (preg_match('/\.xvid$/i', $tmpfile)) {
|
||
| 7885 | $mime = 'video/xvid'; |
||
| 7886 | $imgmime = 'video.png'; |
||
| 7887 | $famime = 'file-video-o'; |
||
| 7888 | } |
||
| 7889 | if (preg_match('/\.(wmv|mpg|mpeg)$/i', $tmpfile)) {
|
||
| 7890 | $mime = 'video'; |
||
| 7891 | $imgmime = 'video.png'; |
||
| 7892 | $famime = 'file-video-o'; |
||
| 7893 | } |
||
| 7894 | // Archive |
||
| 7895 | if (preg_match('/\.(zip|rar|gz|tgz|z|cab|bz2|7z|tar|lzh)$/i', $tmpfile)) {
|
||
| 7896 | $mime = 'archive'; |
||
| 7897 | $imgmime = 'archive.png'; |
||
| 7898 | $famime = 'file-archive-o'; |
||
| 7899 | } // application/xxx where zzz is zip, ... |
||
| 7900 | // Exe |
||
| 7901 | if (preg_match('/\.(exe|com)$/i', $tmpfile)) {
|
||
| 7902 | $mime = 'application/octet-stream'; |
||
| 7903 | $imgmime = 'other.png'; |
||
| 7904 | $famime = 'file-o'; |
||
| 7905 | } |
||
| 7906 | // Lib |
||
| 7907 | if (preg_match('/\.(dll|lib|o|so|a)$/i', $tmpfile)) {
|
||
| 7908 | $mime = 'library'; |
||
| 7909 | $imgmime = 'library.png'; |
||
| 7910 | $famime = 'file-o'; |
||
| 7911 | } |
||
| 7912 | // Err |
||
| 7913 | if (preg_match('/\.err$/i', $tmpfile)) {
|
||
| 7914 | $mime = 'error'; |
||
| 7915 | $imgmime = 'error.png'; |
||
| 7916 | $famime = 'file-text-o'; |
||
| 7917 | } |
||
| 7918 | |||
| 7919 | // Return string |
||
| 7920 | if ($mode == 1) {
|
||
| 7921 | $tmp = explode('/', $mime);
|
||
| 7922 | return (!empty($tmp[1]) ? $tmp[1] : $tmp[0]); |
||
| 7923 | } |
||
| 7924 | if ($mode == 2) {
|
||
| 7925 | return $imgmime; |
||
| 7926 | } |
||
| 7927 | if ($mode == 3) {
|
||
| 7928 | return $srclang; |
||
| 7929 | } |
||
| 7930 | if ($mode == 4) {
|
||
| 7931 | return $famime; |
||
| 7932 | } |
||
| 7933 | return $mime; |
||
| 7934 | } |
||
| 7935 | |||
| 7936 | /** |
||
| 7937 | * Return value from dictionary |
||
| 7938 | * |
||
| 7939 | * @param string $tablename name of dictionary |
||
| 7940 | * @param string $field the value to return |
||
| 7941 | * @param int $id id of line |
||
| 7942 | * @param bool $checkentity add filter on entity |
||
| 7943 | * @param string $rowidfield name of the column rowid |
||
| 7944 | * @return string |
||
| 7945 | */ |
||
| 7946 | static function getDictvalue($tablename, $field, $id, $checkentity = false, $rowidfield = 'rowid') |
||
| 7947 | {
|
||
| 7948 | // global $dictvalues, $db, Globals::$langs; |
||
| 7949 | |||
| 7950 | if (!isset($dictvalues[$tablename])) {
|
||
| 7951 | $dictvalues[$tablename] = array(); |
||
| 7952 | $sql = 'SELECT * FROM ' . $tablename . ' WHERE 1'; |
||
| 7953 | if ($checkentity) |
||
| 7954 | $sql .= ' AND entity IN (0,' . getEntity($tablename) . ')'; |
||
| 7955 | |||
| 7956 | $resql = $db->query($sql); |
||
| 7957 | if ($resql) {
|
||
| 7958 | while ($obj = $db->fetch_object($resql)) {
|
||
| 7959 | $dictvalues[$tablename][$obj->{$rowidfield}] = $obj;
|
||
| 7960 | } |
||
| 7961 | } else {
|
||
| 7962 | dol_print_error($db); |
||
| 7963 | } |
||
| 7964 | } |
||
| 7965 | |||
| 7966 | if (!empty($dictvalues[$tablename][$id])) |
||
| 7967 | return $dictvalues[$tablename][$id]->{$field}; // Found
|
||
| 7968 | else { // Not found
|
||
| 7969 | if ($id > 0) |
||
| 7970 | return $id; |
||
| 7971 | return ''; |
||
| 7972 | } |
||
| 7973 | } |
||
| 7974 | |||
| 7975 | /** |
||
| 7976 | * Return true if the color is light |
||
| 7977 | * |
||
| 7978 | * @param string $stringcolor String with hex (FFFFFF) or comma RGB ('255,255,255')
|
||
| 7979 | * @return int -1 : Error with argument passed |0 : color is dark | 1 : color is light |
||
| 7980 | */ |
||
| 7981 | static function colorIsLight($stringcolor) |
||
| 7982 | {
|
||
| 7983 | $res = -1; |
||
| 7984 | if (!empty($stringcolor)) {
|
||
| 7985 | $res = 0; |
||
| 7986 | $tmp = explode(',', $stringcolor);
|
||
| 7987 | if (count($tmp) > 1) { // This is a comma RGB ('255','255','255')
|
||
| 7988 | $r = $tmp[0]; |
||
| 7989 | $g = $tmp[1]; |
||
| 7990 | $b = $tmp[2]; |
||
| 7991 | } else {
|
||
| 7992 | $hexr = $stringcolor[0] . $stringcolor[1]; |
||
| 7993 | $hexg = $stringcolor[2] . $stringcolor[3]; |
||
| 7994 | $hexb = $stringcolor[4] . $stringcolor[5]; |
||
| 7995 | $r = hexdec($hexr); |
||
| 7996 | $g = hexdec($hexg); |
||
| 7997 | $b = hexdec($hexb); |
||
| 7998 | } |
||
| 7999 | $bright = (max($r, $g, $b) + min($r, $g, $b)) / 510.0; // HSL algorithm |
||
| 8000 | if ($bright > 0.6) |
||
| 8001 | $res = 1; |
||
| 8002 | } |
||
| 8003 | return $res; |
||
| 8004 | } |
||
| 8005 | |||
| 8006 | /** |
||
| 8007 | * Function to test if an entry is enabled or not |
||
| 8008 | * |
||
| 8009 | * @param string $type_user 0=We test for internal user, 1=We test for external user |
||
| 8010 | * @param array $menuentry Array for feature entry to test |
||
| 8011 | * @param array $listofmodulesforexternal Array with list of modules allowed to external users |
||
| 8012 | * @return int 0=Hide, 1=Show, 2=Show gray |
||
| 8013 | */ |
||
| 8014 | static function isVisibleToUserType($type_user, &$menuentry, &$listofmodulesforexternal) |
||
| 8015 | {
|
||
| 8016 | // global Globals::$conf; |
||
| 8017 | //print 'type_user='.$type_user.' module='.$menuentry['module'].' enabled='.$menuentry['enabled'].' perms='.$menuentry['perms']; |
||
| 8018 | //print 'ok='.in_array($menuentry['module'], $listofmodulesforexternal); |
||
| 8019 | if (empty($menuentry['enabled'])) |
||
| 8020 | return 0; // Entry disabled by condition |
||
| 8021 | if ($type_user && $menuentry['module']) {
|
||
| 8022 | $tmploops = explode('|', $menuentry['module']);
|
||
| 8023 | $found = 0; |
||
| 8024 | foreach ($tmploops as $tmploop) {
|
||
| 8025 | if (in_array($tmploop, $listofmodulesforexternal)) {
|
||
| 8026 | $found++; |
||
| 8027 | break; |
||
| 8028 | } |
||
| 8029 | } |
||
| 8030 | if (!$found) |
||
| 8031 | return 0; // Entry is for menus all excluded to external users |
||
| 8032 | } |
||
| 8033 | if (!$menuentry['perms'] && $type_user) |
||
| 8034 | return 0; // No permissions and user is external |
||
| 8035 | if (!$menuentry['perms'] && !empty(Globals::$conf->global->MAIN_MENU_HIDE_UNAUTHORIZED)) |
||
| 8036 | return 0; // No permissions and option to hide when not allowed, even for internal user, is on |
||
| 8037 | if (!$menuentry['perms']) |
||
| 8038 | return 2; // No permissions and user is external |
||
| 8039 | return 1; |
||
| 8040 | } |
||
| 8041 | |||
| 8042 | /** |
||
| 8043 | * Round to next multiple. |
||
| 8044 | * |
||
| 8045 | * @param double $n Number to round up |
||
| 8046 | * @param integer $x Multiple. For example 60 to round up to nearest exact minute for a date with seconds. |
||
| 8047 | * @return integer Value rounded. |
||
| 8048 | */ |
||
| 8049 | static function roundUpToNextMultiple($n, $x = 5) |
||
| 8052 | } |
||
| 8053 | } |
||
| 8054 |