| Total Complexity | 283 |
| Total Lines | 1768 |
| Duplicated Lines | 0 % |
| Changes | 0 | ||
Complex classes like CommonDocGenerator 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 CommonDocGenerator, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 56 | abstract class CommonDocGenerator |
||
| 57 | { |
||
| 58 | /** |
||
| 59 | * @var string Model name |
||
| 60 | */ |
||
| 61 | public $name = ''; |
||
| 62 | |||
| 63 | /** |
||
| 64 | * @var string Version |
||
| 65 | */ |
||
| 66 | public $version = ''; |
||
| 67 | |||
| 68 | /** |
||
| 69 | * @var string Error code (or message) |
||
| 70 | */ |
||
| 71 | public $error = ''; |
||
| 72 | |||
| 73 | /** |
||
| 74 | * @var string[] Array of error strings |
||
| 75 | */ |
||
| 76 | public $errors = array(); |
||
| 77 | |||
| 78 | /** |
||
| 79 | * @var DoliDB Database handler. |
||
| 80 | */ |
||
| 81 | protected $db; |
||
| 82 | |||
| 83 | /** |
||
| 84 | * @var ?Extrafields object |
||
| 85 | */ |
||
| 86 | public $extrafieldsCache; |
||
| 87 | |||
| 88 | /** |
||
| 89 | * @var int If set to 1, save the fullname of generated file with path as the main doc when generating a doc with this template. |
||
| 90 | */ |
||
| 91 | public $update_main_doc_field; |
||
| 92 | |||
| 93 | /** |
||
| 94 | * @var string The name of constant to use to scan ODT files (Example: 'COMMANDE_ADDON_PDF_ODT_PATH') |
||
| 95 | */ |
||
| 96 | public $scandir; |
||
| 97 | |||
| 98 | /** |
||
| 99 | * @var string model description (short text) |
||
| 100 | */ |
||
| 101 | public $description; |
||
| 102 | |||
| 103 | /** |
||
| 104 | * @var array |
||
| 105 | */ |
||
| 106 | public $format; |
||
| 107 | |||
| 108 | /** |
||
| 109 | * @var string pdf, odt, etc |
||
| 110 | */ |
||
| 111 | public $type; |
||
| 112 | |||
| 113 | public $page_hauteur; |
||
| 114 | public $page_largeur; |
||
| 115 | public $marge_gauche; |
||
| 116 | public $marge_droite; |
||
| 117 | public $marge_haute; |
||
| 118 | public $marge_basse; |
||
| 119 | |||
| 120 | public $option_logo; |
||
| 121 | public $option_tva; |
||
| 122 | public $option_multilang; |
||
| 123 | public $option_freetext; |
||
| 124 | public $option_draft_watermark; |
||
| 125 | public $watermark; |
||
| 126 | |||
| 127 | public $option_modereg; |
||
| 128 | public $option_condreg; |
||
| 129 | public $option_escompte; |
||
| 130 | public $option_credit_note; |
||
| 131 | |||
| 132 | public $tva; |
||
| 133 | public $tva_array; |
||
| 134 | /** |
||
| 135 | * Local tax rates Array[tax_type][tax_rate] |
||
| 136 | * |
||
| 137 | * @var array<int,array<string,float>> |
||
| 138 | */ |
||
| 139 | public $localtax1; |
||
| 140 | |||
| 141 | /** |
||
| 142 | * Local tax rates Array[tax_type][tax_rate] |
||
| 143 | * |
||
| 144 | * @var array<int,array<string,float>> |
||
| 145 | */ |
||
| 146 | public $localtax2; |
||
| 147 | |||
| 148 | /** |
||
| 149 | * @var int Tab Title Height |
||
| 150 | */ |
||
| 151 | public $tabTitleHeight; |
||
| 152 | |||
| 153 | /** |
||
| 154 | * @var array default title fields style |
||
| 155 | */ |
||
| 156 | public $defaultTitlesFieldsStyle; |
||
| 157 | |||
| 158 | /** |
||
| 159 | * @var array default content fields style |
||
| 160 | */ |
||
| 161 | public $defaultContentsFieldsStyle; |
||
| 162 | |||
| 163 | /** |
||
| 164 | * @var Societe Issuer of document |
||
| 165 | */ |
||
| 166 | public $emetteur; |
||
| 167 | |||
| 168 | /** |
||
| 169 | * @var array{0:int,1:int} Minimum version of PHP required by module. |
||
| 170 | * e.g.: PHP ≥ 7.1 = array(7, 1) |
||
| 171 | */ |
||
| 172 | public $phpmin = array(7, 1); |
||
| 173 | |||
| 174 | /** |
||
| 175 | * @var array<string,array{rank:int,width:float|int,title:array{textkey:string,label:string,align:string,padding:array{0:float,1:float,2:float,3:float}},content:array{align:string,padding:array{0:float,1:float,2:float,3:float}}}> Array of columns |
||
| 176 | */ |
||
| 177 | public $cols; |
||
| 178 | |||
| 179 | /** |
||
| 180 | * @var array{fullpath:string} Array with result of doc generation. content is array('fullpath'=>$file) |
||
| 181 | */ |
||
| 182 | public $result; |
||
| 183 | |||
| 184 | public $posxlabel; |
||
| 185 | public $posxup; |
||
| 186 | public $posxref; |
||
| 187 | public $posxpicture; // For picture |
||
| 188 | public $posxdesc; // For description |
||
| 189 | public $posxqty; |
||
| 190 | public $posxpuht; |
||
| 191 | public $posxtva; |
||
| 192 | public $posxtotalht; |
||
| 193 | public $postotalht; |
||
| 194 | public $posxunit; |
||
| 195 | public $posxdiscount; |
||
| 196 | public $posxworkload; |
||
| 197 | public $posxtimespent; |
||
| 198 | public $posxprogress; |
||
| 199 | public $atleastonephoto; |
||
| 200 | public $atleastoneratenotnull; |
||
| 201 | public $atleastonediscount; |
||
| 202 | |||
| 203 | /** |
||
| 204 | * Constructor |
||
| 205 | * |
||
| 206 | * @param DoliDB $db Database handler |
||
| 207 | */ |
||
| 208 | public function __construct($db) |
||
| 209 | { |
||
| 210 | $this->db = $db; |
||
| 211 | } |
||
| 212 | |||
| 213 | |||
| 214 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
| 215 | /** |
||
| 216 | * Define array with couple substitution key => substitution value |
||
| 217 | * |
||
| 218 | * @param User $user User |
||
| 219 | * @param Translate $outputlangs Language object for output |
||
| 220 | * @return array Array of substitution key->code |
||
| 221 | */ |
||
| 222 | public function get_substitutionarray_user($user, $outputlangs) |
||
| 223 | { |
||
| 224 | // phpcs:enable |
||
| 225 | global $conf, $extrafields; |
||
| 226 | |||
| 227 | $logotouse = $conf->user->dir_output . '/' . get_exdir(0, 0, 0, 0, $user, 'user') . 'photos/' . getImageFileNameForSize($user->photo, '_small'); |
||
| 228 | |||
| 229 | $array_user = array( |
||
| 230 | 'myuser_lastname' => $user->lastname, |
||
| 231 | 'myuser_firstname' => $user->firstname, |
||
| 232 | 'myuser_fullname' => $user->getFullName($outputlangs, 1), |
||
| 233 | 'myuser_login' => $user->login, |
||
| 234 | 'myuser_phone' => $user->office_phone, |
||
| 235 | 'myuser_address' => $user->address, |
||
| 236 | 'myuser_zip' => $user->zip, |
||
| 237 | 'myuser_town' => $user->town, |
||
| 238 | 'myuser_country' => $user->country, |
||
| 239 | 'myuser_country_code' => $user->country_code, |
||
| 240 | 'myuser_state' => $user->state, |
||
| 241 | 'myuser_state_code' => $user->state_code, |
||
| 242 | 'myuser_fax' => $user->office_fax, |
||
| 243 | 'myuser_mobile' => $user->user_mobile, |
||
| 244 | 'myuser_email' => $user->email, |
||
| 245 | 'myuser_logo' => $logotouse, |
||
| 246 | 'myuser_job' => $user->job, |
||
| 247 | 'myuser_web' => '', // url not exist in $user object |
||
| 248 | 'myuser_birth' => dol_print_date($user->birth, 'day', 'gmt'), |
||
| 249 | 'myuser_dateemployment' => dol_print_date($user->dateemployment, 'day', 'tzuser'), |
||
| 250 | 'myuser_dateemploymentend' => dol_print_date($user->dateemploymentend, 'day', 'tzuser'), |
||
| 251 | 'myuser_gender' => $user->gender, |
||
| 252 | ); |
||
| 253 | // Retrieve extrafields |
||
| 254 | if (is_array($user->array_options) && count($user->array_options)) { |
||
| 255 | if (empty($extrafields->attributes[$user->table_element])) { |
||
| 256 | $extrafields->fetch_name_optionals_label($user->table_element); |
||
| 257 | } |
||
| 258 | $array_user = $this->fill_substitutionarray_with_extrafields($user, $array_user, $extrafields, 'myuser', $outputlangs); |
||
| 259 | } |
||
| 260 | return $array_user; |
||
| 261 | } |
||
| 262 | |||
| 263 | |||
| 264 | /** |
||
| 265 | * Define array with couple substitution key => substitution value |
||
| 266 | * |
||
| 267 | * @param Adherent $member Member |
||
| 268 | * @param Translate $outputlangs Language object for output |
||
| 269 | * @return array Array of substitution key->code |
||
| 270 | */ |
||
| 271 | public function getSubstitutionarrayMember($member, $outputlangs) |
||
| 272 | { |
||
| 273 | global $conf, $extrafields; |
||
| 274 | |||
| 275 | if ($member->photo) { |
||
| 276 | $logotouse = $conf->member->dir_output . '/' . get_exdir(0, 0, 0, 1, $member, 'user') . '/photos/' . $member->photo; |
||
| 277 | } else { |
||
| 278 | $logotouse = DOL_DOCUMENT_ROOT . '/public/theme/common/nophoto.png'; |
||
| 279 | } |
||
| 280 | |||
| 281 | $array_member = array( |
||
| 282 | 'mymember_lastname' => $member->lastname, |
||
| 283 | 'mymember_firstname' => $member->firstname, |
||
| 284 | 'mymember_fullname' => $member->getFullName($outputlangs, 1), |
||
| 285 | 'mymember_login' => $member->login, |
||
| 286 | 'mymember_address' => $member->address, |
||
| 287 | 'mymember_zip' => $member->zip, |
||
| 288 | 'mymember_town' => $member->town, |
||
| 289 | 'mymember_country_code' => $member->country_code, |
||
| 290 | 'mymember_country' => $member->country, |
||
| 291 | 'mymember_state_code' => $member->state_code, |
||
| 292 | 'mymember_state' => $member->state, |
||
| 293 | 'mymember_phone_perso' => $member->phone_perso, |
||
| 294 | 'mymember_phone_pro' => $member->phone, |
||
| 295 | 'mymember_phone_mobile' => $member->phone_mobile, |
||
| 296 | 'mymember_email' => $member->email, |
||
| 297 | 'mymember_logo' => $logotouse, |
||
| 298 | 'mymember_gender' => $member->gender, |
||
| 299 | 'mymember_birth_locale' => dol_print_date($member->birth, 'day', 'tzuser', $outputlangs), |
||
| 300 | 'mymember_birth' => dol_print_date($member->birth, 'day', 'tzuser'), |
||
| 301 | ); |
||
| 302 | // Retrieve extrafields |
||
| 303 | if (is_array($member->array_options) && count($member->array_options)) { |
||
| 304 | $array_member = $this->fill_substitutionarray_with_extrafields($member, $array_member, $extrafields, 'mymember', $outputlangs); |
||
| 305 | } |
||
| 306 | return $array_member; |
||
| 307 | } |
||
| 308 | |||
| 309 | |||
| 310 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
| 311 | /** |
||
| 312 | * Define array with couple substitution key => substitution value |
||
| 313 | * |
||
| 314 | * @param Societe $mysoc Object thirdparty |
||
| 315 | * @param Translate $outputlangs Language object for output |
||
| 316 | * @return array Array of substitution key->code |
||
| 317 | */ |
||
| 318 | public function get_substitutionarray_mysoc($mysoc, $outputlangs) |
||
| 319 | { |
||
| 320 | // phpcs:enable |
||
| 321 | global $conf; |
||
| 322 | |||
| 323 | if (empty($mysoc->forme_juridique) && !empty($mysoc->forme_juridique_code)) { |
||
| 324 | $mysoc->forme_juridique = getFormeJuridiqueLabel($mysoc->forme_juridique_code); |
||
| 325 | } |
||
| 326 | if (empty($mysoc->country) && !empty($mysoc->country_code)) { |
||
| 327 | $mysoc->country = $outputlangs->transnoentitiesnoconv("Country" . $mysoc->country_code); |
||
| 328 | } |
||
| 329 | if (empty($mysoc->state) && !empty($mysoc->state_code)) { |
||
| 330 | $mysoc->state = getState($mysoc->state_code, 0); |
||
| 331 | } |
||
| 332 | |||
| 333 | $logotouse = $conf->mycompany->dir_output . '/logos/thumbs/' . $mysoc->logo_small; |
||
| 334 | |||
| 335 | return array( |
||
| 336 | 'mycompany_logo' => $logotouse, |
||
| 337 | 'mycompany_name' => $mysoc->name, |
||
| 338 | 'mycompany_email' => $mysoc->email, |
||
| 339 | 'mycompany_phone' => $mysoc->phone, |
||
| 340 | 'mycompany_fax' => $mysoc->fax, |
||
| 341 | 'mycompany_address' => $mysoc->address, |
||
| 342 | 'mycompany_zip' => $mysoc->zip, |
||
| 343 | 'mycompany_town' => $mysoc->town, |
||
| 344 | 'mycompany_country' => $mysoc->country, |
||
| 345 | 'mycompany_country_code' => $mysoc->country_code, |
||
| 346 | 'mycompany_state' => $mysoc->state, |
||
| 347 | 'mycompany_state_code' => $mysoc->state_code, |
||
| 348 | 'mycompany_web' => $mysoc->url, |
||
| 349 | 'mycompany_juridicalstatus' => $mysoc->forme_juridique, |
||
| 350 | 'mycompany_managers' => $mysoc->managers, |
||
| 351 | 'mycompany_capital' => $mysoc->capital, |
||
| 352 | 'mycompany_barcode' => $mysoc->barcode, |
||
| 353 | 'mycompany_idprof1' => $mysoc->idprof1, |
||
| 354 | 'mycompany_idprof2' => $mysoc->idprof2, |
||
| 355 | 'mycompany_idprof3' => $mysoc->idprof3, |
||
| 356 | 'mycompany_idprof4' => $mysoc->idprof4, |
||
| 357 | 'mycompany_idprof5' => $mysoc->idprof5, |
||
| 358 | 'mycompany_idprof6' => $mysoc->idprof6, |
||
| 359 | 'mycompany_vatnumber' => $mysoc->tva_intra, |
||
| 360 | 'mycompany_socialobject' => $mysoc->socialobject, |
||
| 361 | 'mycompany_note_private' => $mysoc->note_private, |
||
| 362 | //'mycompany_note_public'=>$mysoc->note_public, // Only private not exists for "mysoc" but both for thirdparties |
||
| 363 | ); |
||
| 364 | } |
||
| 365 | |||
| 366 | |||
| 367 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
| 368 | /** |
||
| 369 | * Define array with couple substitution key => substitution value |
||
| 370 | * For example {company_name}, {company_name_alias} |
||
| 371 | * |
||
| 372 | * @param Societe $object Object |
||
| 373 | * @param Translate $outputlangs Language object for output |
||
| 374 | * @param string $array_key Name of the key for return array |
||
| 375 | * @return array Array of substitution key->code |
||
| 376 | */ |
||
| 377 | public function get_substitutionarray_thirdparty($object, $outputlangs, $array_key = 'company') |
||
| 378 | { |
||
| 379 | // phpcs:enable |
||
| 380 | global $extrafields; |
||
| 381 | |||
| 382 | if (empty($object->country) && !empty($object->country_code)) { |
||
| 383 | $object->country = $outputlangs->transnoentitiesnoconv("Country" . $object->country_code); |
||
| 384 | } |
||
| 385 | if (empty($object->state) && !empty($object->state_code)) { |
||
| 386 | $object->state = getState($object->state_code, 0); |
||
| 387 | } |
||
| 388 | |||
| 389 | $array_thirdparty = array( |
||
| 390 | 'company_name' => $object->name, |
||
| 391 | 'company_name_alias' => $object->name_alias, |
||
| 392 | 'company_email' => $object->email, |
||
| 393 | 'company_phone' => $object->phone, |
||
| 394 | 'company_fax' => $object->fax, |
||
| 395 | 'company_address' => $object->address, |
||
| 396 | 'company_zip' => $object->zip, |
||
| 397 | 'company_town' => $object->town, |
||
| 398 | 'company_country' => $object->country, |
||
| 399 | 'company_country_code' => $object->country_code, |
||
| 400 | 'company_state' => $object->state, |
||
| 401 | 'company_state_code' => $object->state_code, |
||
| 402 | 'company_web' => $object->url, |
||
| 403 | 'company_barcode' => $object->barcode, |
||
| 404 | 'company_vatnumber' => $object->tva_intra, |
||
| 405 | 'company_customercode' => $object->code_client, |
||
| 406 | 'company_suppliercode' => $object->code_fournisseur, |
||
| 407 | 'company_customeraccountancycode' => $object->code_compta_client, |
||
| 408 | 'company_supplieraccountancycode' => $object->code_compta_fournisseur, |
||
| 409 | 'company_juridicalstatus' => $object->forme_juridique, |
||
| 410 | 'company_outstanding_limit' => $object->outstanding_limit, |
||
| 411 | 'company_capital' => $object->capital, |
||
| 412 | 'company_capital_formated' => price($object->capital, 0, '', 1, -1), |
||
| 413 | 'company_idprof1' => $object->idprof1, |
||
| 414 | 'company_idprof2' => $object->idprof2, |
||
| 415 | 'company_idprof3' => $object->idprof3, |
||
| 416 | 'company_idprof4' => $object->idprof4, |
||
| 417 | 'company_idprof5' => $object->idprof5, |
||
| 418 | 'company_idprof6' => $object->idprof6, |
||
| 419 | 'company_note_public' => $object->note_public, |
||
| 420 | 'company_note_private' => $object->note_private, |
||
| 421 | 'company_default_bank_iban' => (is_object($object->bank_account) ? $object->bank_account->iban : ''), |
||
| 422 | 'company_default_bank_bic' => (is_object($object->bank_account) ? $object->bank_account->bic : '') |
||
| 423 | ); |
||
| 424 | |||
| 425 | // Retrieve extrafields |
||
| 426 | if (is_array($object->array_options) && count($object->array_options)) { |
||
| 427 | $object->fetch_optionals(); |
||
| 428 | |||
| 429 | $array_thirdparty = $this->fill_substitutionarray_with_extrafields($object, $array_thirdparty, $extrafields, $array_key, $outputlangs); |
||
| 430 | } |
||
| 431 | return $array_thirdparty; |
||
| 432 | } |
||
| 433 | |||
| 434 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
| 435 | /** |
||
| 436 | * Define array with couple substitution key => substitution value |
||
| 437 | * |
||
| 438 | * @param Contact $object contact |
||
| 439 | * @param Translate $outputlangs object for output |
||
| 440 | * @param string $array_key Name of the key for return array |
||
| 441 | * @return array Array of substitution key->code |
||
| 442 | */ |
||
| 443 | public function get_substitutionarray_contact($object, $outputlangs, $array_key = 'object') |
||
| 444 | { |
||
| 445 | // phpcs:enable |
||
| 446 | global $conf, $extrafields; |
||
| 447 | |||
| 448 | if (empty($object->country) && !empty($object->country_code)) { |
||
| 449 | $object->country = $outputlangs->transnoentitiesnoconv("Country" . $object->country_code); |
||
| 450 | } |
||
| 451 | if (empty($object->state) && !empty($object->state_code)) { |
||
| 452 | $object->state = getState($object->state_code, 0); |
||
|
|
|||
| 453 | } |
||
| 454 | |||
| 455 | $array_contact = array( |
||
| 456 | $array_key . '_fullname' => $object->getFullName($outputlangs, 1), |
||
| 457 | $array_key . '_lastname' => $object->lastname, |
||
| 458 | $array_key . '_firstname' => $object->firstname, |
||
| 459 | $array_key . '_address' => $object->address, |
||
| 460 | $array_key . '_zip' => $object->zip, |
||
| 461 | $array_key . '_town' => $object->town, |
||
| 462 | $array_key . '_state_id' => $object->state_id, |
||
| 463 | $array_key . '_state_code' => $object->state_code, |
||
| 464 | $array_key . '_state' => $object->state, |
||
| 465 | $array_key . '_country_id' => $object->country_id, |
||
| 466 | $array_key . '_country_code' => $object->country_code, |
||
| 467 | $array_key . '_country' => $object->country, |
||
| 468 | $array_key . '_poste' => $object->poste, |
||
| 469 | $array_key . '_socid' => $object->socid, |
||
| 470 | $array_key . '_statut' => $object->statut, |
||
| 471 | $array_key . '_code' => $object->code, |
||
| 472 | $array_key . '_email' => $object->email, |
||
| 473 | $array_key . '_phone_pro' => $object->phone_pro, |
||
| 474 | $array_key . '_phone_perso' => $object->phone_perso, |
||
| 475 | $array_key . '_phone_mobile' => $object->phone_mobile, |
||
| 476 | $array_key . '_fax' => $object->fax, |
||
| 477 | $array_key . '_birthday' => $object->birthday, |
||
| 478 | $array_key . '_default_lang' => $object->default_lang, |
||
| 479 | $array_key . '_note_public' => $object->note_public, |
||
| 480 | $array_key . '_note_private' => $object->note_private, |
||
| 481 | $array_key . '_civility' => $object->civility, |
||
| 482 | ); |
||
| 483 | |||
| 484 | // Retrieve extrafields |
||
| 485 | if (is_array($object->array_options) && count($object->array_options)) { |
||
| 486 | $object->fetch_optionals(); |
||
| 487 | |||
| 488 | $array_contact = $this->fill_substitutionarray_with_extrafields($object, $array_contact, $extrafields, $array_key, $outputlangs); |
||
| 489 | } |
||
| 490 | return $array_contact; |
||
| 491 | } |
||
| 492 | |||
| 493 | |||
| 494 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
| 495 | /** |
||
| 496 | * Define array with couple substitution key => substitution value |
||
| 497 | * |
||
| 498 | * @param Translate $outputlangs Language object for output |
||
| 499 | * @return array Array of substitution key->code |
||
| 500 | */ |
||
| 501 | public function get_substitutionarray_other($outputlangs) |
||
| 502 | { |
||
| 503 | // phpcs:enable |
||
| 504 | global $conf; |
||
| 505 | |||
| 506 | $now = dol_now('gmt'); // gmt |
||
| 507 | $array_other = array( |
||
| 508 | // Date in default language |
||
| 509 | 'current_date' => dol_print_date($now, 'day', 'tzuser'), |
||
| 510 | 'current_datehour' => dol_print_date($now, 'dayhour', 'tzuser'), |
||
| 511 | 'current_server_date' => dol_print_date($now, 'day', 'tzserver'), |
||
| 512 | 'current_server_datehour' => dol_print_date($now, 'dayhour', 'tzserver'), |
||
| 513 | // Date in requested output language |
||
| 514 | 'current_date_locale' => dol_print_date($now, 'day', 'tzuser', $outputlangs), |
||
| 515 | 'current_datehour_locale' => dol_print_date($now, 'dayhour', 'tzuser', $outputlangs), |
||
| 516 | 'current_server_date_locale' => dol_print_date($now, 'day', 'tzserver', $outputlangs), |
||
| 517 | 'current_server_datehour_locale' => dol_print_date($now, 'dayhour', 'tzserver', $outputlangs), |
||
| 518 | ); |
||
| 519 | |||
| 520 | |||
| 521 | foreach ($conf->global as $key => $val) { |
||
| 522 | if (isASecretKey($key)) { |
||
| 523 | $newval = '*****forbidden*****'; |
||
| 524 | } else { |
||
| 525 | $newval = $val; |
||
| 526 | } |
||
| 527 | $array_other['__[' . $key . ']__'] = $newval; |
||
| 528 | } |
||
| 529 | |||
| 530 | return $array_other; |
||
| 531 | } |
||
| 532 | |||
| 533 | |||
| 534 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
| 535 | /** |
||
| 536 | * Define array with couple substitution key => substitution value |
||
| 537 | * Note that vars into substitutions array are formatted. |
||
| 538 | * |
||
| 539 | * @param CommonObject $object Main object to use as data source |
||
| 540 | * @param Translate $outputlangs Lang object to use for output |
||
| 541 | * @param string $array_key Name of the key for return array |
||
| 542 | * @return array Array of substitution |
||
| 543 | */ |
||
| 544 | public function get_substitutionarray_object($object, $outputlangs, $array_key = 'object') |
||
| 734 | } |
||
| 735 | |||
| 736 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
| 737 | /** |
||
| 738 | * Define array with couple substitution key => substitution value |
||
| 739 | * Note that vars into substitutions array are formatted. |
||
| 740 | * |
||
| 741 | * @param CommonObjectLine $line Object line |
||
| 742 | * @param Translate $outputlangs Translate object to use for output |
||
| 743 | * @param int $linenumber The number of the line for the substitution of "object_line_pos" |
||
| 744 | * @return array Return a substitution array |
||
| 745 | */ |
||
| 746 | public function get_substitutionarray_lines($line, $outputlangs, $linenumber = 0) |
||
| 747 | { |
||
| 748 | // phpcs:enable |
||
| 749 | $resarray = array( |
||
| 750 | 'line_pos' => $linenumber, |
||
| 751 | 'line_fulldesc' => doc_getlinedesc($line, $outputlangs), |
||
| 752 | |||
| 753 | 'line_product_ref' => (empty($line->product_ref) ? '' : $line->product_ref), |
||
| 754 | 'line_product_ref_fourn' => (empty($line->ref_fourn) ? '' : $line->ref_fourn), // for supplier doc lines |
||
| 755 | 'line_product_label' => (empty($line->product_label) ? '' : $line->product_label), |
||
| 756 | 'line_product_type' => (empty($line->product_type) ? '' : $line->product_type), |
||
| 757 | 'line_product_barcode' => (empty($line->product_barcode) ? '' : $line->product_barcode), |
||
| 758 | 'line_product_desc' => (empty($line->product_desc) ? '' : $line->product_desc), |
||
| 759 | |||
| 760 | 'line_desc' => $line->desc, |
||
| 761 | 'line_vatrate' => vatrate($line->tva_tx, true, $line->info_bits), |
||
| 762 | 'line_localtax1_rate' => vatrate($line->localtax1_tx), |
||
| 763 | 'line_localtax2_rate' => vatrate($line->localtax1_tx), |
||
| 764 | 'line_up' => price2num($line->subprice), |
||
| 765 | 'line_up_locale' => price($line->subprice, 0, $outputlangs), |
||
| 766 | 'line_total_up' => price2num($line->subprice * (float) $line->qty), |
||
| 767 | 'line_total_up_locale' => price($line->subprice * (float) $line->qty, 0, $outputlangs), |
||
| 768 | 'line_qty' => $line->qty, |
||
| 769 | 'line_discount_percent' => ($line->remise_percent ? $line->remise_percent . '%' : ''), |
||
| 770 | 'line_price_ht' => price2num($line->total_ht), |
||
| 771 | 'line_price_ttc' => price2num($line->total_ttc), |
||
| 772 | 'line_price_vat' => price2num($line->total_tva), |
||
| 773 | 'line_price_ht_locale' => price($line->total_ht, 0, $outputlangs), |
||
| 774 | 'line_price_ttc_locale' => price($line->total_ttc, 0, $outputlangs), |
||
| 775 | 'line_price_vat_locale' => price($line->total_tva, 0, $outputlangs), |
||
| 776 | // Dates |
||
| 777 | 'line_date_start' => dol_print_date($line->date_start, 'day'), |
||
| 778 | 'line_date_start_locale' => dol_print_date($line->date_start, 'day', 'tzserver', $outputlangs), |
||
| 779 | 'line_date_start_rfc' => dol_print_date($line->date_start, 'dayrfc'), |
||
| 780 | 'line_date_end' => dol_print_date($line->date_end, 'day'), |
||
| 781 | 'line_date_end_locale' => dol_print_date($line->date_end, 'day', 'tzserver', $outputlangs), |
||
| 782 | 'line_date_end_rfc' => dol_print_date($line->date_end, 'dayrfc'), |
||
| 783 | |||
| 784 | 'line_multicurrency_code' => price2num($line->multicurrency_code), |
||
| 785 | 'line_multicurrency_subprice' => price2num($line->multicurrency_subprice), |
||
| 786 | 'line_multicurrency_total_ht' => price2num($line->multicurrency_total_ht), |
||
| 787 | 'line_multicurrency_total_tva' => price2num($line->multicurrency_total_tva), |
||
| 788 | 'line_multicurrency_total_ttc' => price2num($line->multicurrency_total_ttc), |
||
| 789 | 'line_multicurrency_subprice_locale' => price($line->multicurrency_subprice, 0, $outputlangs), |
||
| 790 | 'line_multicurrency_total_ht_locale' => price($line->multicurrency_total_ht, 0, $outputlangs), |
||
| 791 | 'line_multicurrency_total_tva_locale' => price($line->multicurrency_total_tva, 0, $outputlangs), |
||
| 792 | 'line_multicurrency_total_ttc_locale' => price($line->multicurrency_total_ttc, 0, $outputlangs), |
||
| 793 | ); |
||
| 794 | |||
| 795 | // Units |
||
| 796 | if (getDolGlobalInt('PRODUCT_USE_UNITS')) { |
||
| 797 | $resarray['line_unit'] = $outputlangs->trans($line->getLabelOfUnit('long')); |
||
| 798 | $resarray['line_unit_short'] = $outputlangs->trans($line->getLabelOfUnit('short')); |
||
| 799 | } |
||
| 800 | |||
| 801 | // Retrieve extrafields |
||
| 802 | $extrafieldkey = $line->table_element; |
||
| 803 | $array_key = "line"; |
||
| 804 | $extrafields = new ExtraFields($this->db); |
||
| 805 | $extrafields->fetch_name_optionals_label($extrafieldkey, true); |
||
| 806 | $line->fetch_optionals(); |
||
| 807 | |||
| 808 | $resarray = $this->fill_substitutionarray_with_extrafields($line, $resarray, $extrafields, $array_key, $outputlangs); |
||
| 809 | |||
| 810 | // Check if the current line belongs to a supplier order |
||
| 811 | if (get_only_class($line) == 'CommandeFournisseurLigne') { |
||
| 812 | // Add the product supplier extrafields to the substitutions |
||
| 813 | $extrafields->fetch_name_optionals_label("product_fournisseur_price"); |
||
| 814 | $extralabels = $extrafields->attributes["product_fournisseur_price"]['label']; |
||
| 815 | |||
| 816 | if (!empty($extralabels) && is_array($extralabels)) { |
||
| 817 | $columns = ""; |
||
| 818 | |||
| 819 | foreach ($extralabels as $key => $label) { |
||
| 820 | $columns .= "$key, "; |
||
| 821 | } |
||
| 822 | |||
| 823 | if ($columns != "") { |
||
| 824 | $columns = substr($columns, 0, strlen($columns) - 2); |
||
| 825 | $resql = $this->db->query("SELECT " . $columns . " FROM " . $this->db->prefix() . "product_fournisseur_price_extrafields AS ex INNER JOIN " . $this->db->prefix() . "product_fournisseur_price AS f ON ex.fk_object = f.rowid WHERE f.ref_fourn = '" . $this->db->escape($line->ref_supplier) . "'"); |
||
| 826 | |||
| 827 | if ($this->db->num_rows($resql) > 0) { |
||
| 828 | $resql = $this->db->fetch_object($resql); |
||
| 829 | |||
| 830 | foreach ($extralabels as $key => $label) { |
||
| 831 | $resarray['line_product_supplier_' . $key] = $resql->$key; |
||
| 832 | } |
||
| 833 | } |
||
| 834 | } |
||
| 835 | } |
||
| 836 | } |
||
| 837 | |||
| 838 | // Load product data optional fields to the line -> enables to use "line_options_{extrafield}" |
||
| 839 | if (isset($line->fk_product) && $line->fk_product > 0) { |
||
| 840 | $tmpproduct = new Product($this->db); |
||
| 841 | $result = $tmpproduct->fetch($line->fk_product); |
||
| 842 | if (!empty($tmpproduct->array_options) && is_array($tmpproduct->array_options)) { |
||
| 843 | foreach ($tmpproduct->array_options as $key => $label) { |
||
| 844 | $resarray["line_product_" . $key] = $label; |
||
| 845 | } |
||
| 846 | } |
||
| 847 | } else { |
||
| 848 | // Set unused placeholders as blank |
||
| 849 | $extrafields->fetch_name_optionals_label("product"); |
||
| 850 | if ($extrafields->attributes["product"]['count'] > 0) { |
||
| 851 | $extralabels = $extrafields->attributes["product"]['label']; |
||
| 852 | |||
| 853 | foreach ($extralabels as $key => $label) { |
||
| 854 | $resarray['line_product_options_' . $key] = ''; |
||
| 855 | } |
||
| 856 | } |
||
| 857 | } |
||
| 858 | |||
| 859 | return $resarray; |
||
| 860 | } |
||
| 861 | |||
| 862 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
| 863 | /** |
||
| 864 | * Define array with couple substitution key => substitution value |
||
| 865 | * Note that vars into substitutions array are formatted. |
||
| 866 | * |
||
| 867 | * @param Expedition $object Main object to use as data source |
||
| 868 | * @param Translate $outputlangs Lang object to use for output |
||
| 869 | * @param string $array_key Name of the key for return array |
||
| 870 | * @return array Array of substitution |
||
| 871 | */ |
||
| 872 | public function get_substitutionarray_shipment($object, $outputlangs, $array_key = 'object') |
||
| 873 | { |
||
| 874 | // phpcs:enable |
||
| 875 | global $extrafields; |
||
| 876 | |||
| 877 | include_once DOL_DOCUMENT_ROOT . '/core/lib/product.lib.php'; |
||
| 878 | |||
| 879 | $object->list_delivery_methods($object->shipping_method_id); |
||
| 880 | $calculatedVolume = ((float) $object->trueWidth * (float) $object->trueHeight * (float) $object->trueDepth); |
||
| 881 | |||
| 882 | $array_shipment = array( |
||
| 883 | $array_key . '_id' => $object->id, |
||
| 884 | $array_key . '_ref' => $object->ref, |
||
| 885 | $array_key . '_ref_ext' => $object->ref_ext, |
||
| 886 | $array_key . '_ref_customer' => $object->ref_customer, |
||
| 887 | $array_key . '_date_delivery' => dol_print_date($object->date_delivery, 'day'), |
||
| 888 | $array_key . '_hour_delivery' => dol_print_date($object->date_delivery, 'hour'), |
||
| 889 | $array_key . '_date_creation' => dol_print_date($object->date_creation, 'day'), |
||
| 890 | $array_key . '_total_ht' => price($object->total_ht), |
||
| 891 | $array_key . '_total_vat' => price($object->total_tva), |
||
| 892 | $array_key . '_total_ttc' => price($object->total_ttc), |
||
| 893 | $array_key . '_total_discount_ht' => price($object->getTotalDiscount()), |
||
| 894 | $array_key . '_note_private' => $object->note_private, |
||
| 895 | $array_key . '_note' => $object->note_public, |
||
| 896 | $array_key . '_tracking_number' => $object->tracking_number, |
||
| 897 | $array_key . '_tracking_url' => $object->tracking_url, |
||
| 898 | $array_key . '_shipping_method' => $object->listmeths[0]['libelle'], |
||
| 899 | $array_key . '_weight' => $object->trueWeight . ' ' . measuringUnitString(0, 'weight', $object->weight_units), |
||
| 900 | $array_key . '_width' => $object->trueWidth . ' ' . measuringUnitString(0, 'size', $object->width_units), |
||
| 901 | $array_key . '_height' => $object->trueHeight . ' ' . measuringUnitString(0, 'size', $object->height_units), |
||
| 902 | $array_key . '_depth' => $object->trueDepth . ' ' . measuringUnitString(0, 'size', $object->depth_units), |
||
| 903 | $array_key . '_size' => $calculatedVolume . ' ' . measuringUnitString(0, 'volume'), |
||
| 904 | ); |
||
| 905 | |||
| 906 | // Add vat by rates |
||
| 907 | foreach ($object->lines as $line) { |
||
| 908 | if (empty($array_shipment[$array_key . '_total_vat_' . $line->tva_tx])) { |
||
| 909 | $array_shipment[$array_key . '_total_vat_' . $line->tva_tx] = 0; |
||
| 910 | } |
||
| 911 | $array_shipment[$array_key . '_total_vat_' . $line->tva_tx] += $line->total_tva; |
||
| 912 | } |
||
| 913 | |||
| 914 | // Retrieve extrafields |
||
| 915 | if (is_array($object->array_options) && count($object->array_options)) { |
||
| 916 | $object->fetch_optionals(); |
||
| 917 | |||
| 918 | $array_shipment = $this->fill_substitutionarray_with_extrafields($object, $array_shipment, $extrafields, $array_key, $outputlangs); |
||
| 919 | } |
||
| 920 | |||
| 921 | // Add info from $object->xxx where xxx has been loaded by fetch_origin() of shipment |
||
| 922 | if (is_object($object->commande) && !empty($object->commande->ref)) { |
||
| 923 | $array_shipment['order_ref'] = $object->commande->ref; |
||
| 924 | $array_shipment['order_ref_customer'] = $object->commande->ref_customer; |
||
| 925 | } |
||
| 926 | |||
| 927 | return $array_shipment; |
||
| 928 | } |
||
| 929 | |||
| 930 | |||
| 931 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
| 932 | /** |
||
| 933 | * Define array with couple substitution key => substitution value |
||
| 934 | * |
||
| 935 | * @param Object $object Dolibarr Object |
||
| 936 | * @param Translate $outputlangs Language object for output |
||
| 937 | * @param boolean|int $recursive Want to fetch child array or child object. |
||
| 938 | * @return array Array of substitution key->code |
||
| 939 | */ |
||
| 940 | public function get_substitutionarray_each_var_object(&$object, $outputlangs, $recursive = 1) |
||
| 941 | { |
||
| 942 | // phpcs:enable |
||
| 943 | $array_other = array(); |
||
| 944 | if (!empty($object)) { |
||
| 945 | foreach ($object as $key => $value) { |
||
| 946 | if (in_array($key, array('db', 'fields', 'lines', 'modelpdf', 'model_pdf'))) { // discard some properties |
||
| 947 | continue; |
||
| 948 | } |
||
| 949 | if (!empty($value)) { |
||
| 950 | if (!is_array($value) && !is_object($value)) { |
||
| 951 | $array_other['object_' . $key] = $value; |
||
| 952 | } elseif (is_array($value) && $recursive) { |
||
| 953 | $tmparray = $this->get_substitutionarray_each_var_object($value, $outputlangs, 0); |
||
| 954 | if (!empty($tmparray) && is_array($tmparray)) { |
||
| 955 | foreach ($tmparray as $key2 => $value2) { |
||
| 956 | $array_other['object_' . $key . '_' . preg_replace('/^object_/', '', $key2)] = $value2; |
||
| 957 | } |
||
| 958 | } |
||
| 959 | } elseif (is_object($value) && $recursive) { |
||
| 960 | $tmparray = $this->get_substitutionarray_each_var_object($value, $outputlangs, 0); |
||
| 961 | if (!empty($tmparray) && is_array($tmparray)) { |
||
| 962 | foreach ($tmparray as $key2 => $value2) { |
||
| 963 | $array_other['object_' . $key . '_' . preg_replace('/^object_/', '', $key2)] = $value2; |
||
| 964 | } |
||
| 965 | } |
||
| 966 | } |
||
| 967 | } |
||
| 968 | } |
||
| 969 | } |
||
| 970 | |||
| 971 | return $array_other; |
||
| 972 | } |
||
| 973 | |||
| 974 | |||
| 975 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
| 976 | /** |
||
| 977 | * Fill array with couple extrafield key => extrafield value |
||
| 978 | * Note that vars into substitutions array are formatted. |
||
| 979 | * |
||
| 980 | * @param Object $object Object with extrafields (must have $object->array_options filled) |
||
| 981 | * @param array $array_to_fill Substitution array |
||
| 982 | * @param Extrafields $extrafields Extrafields object |
||
| 983 | * @param string $array_key Prefix for name of the keys into returned array |
||
| 984 | * @param Translate $outputlangs Lang object to use for output |
||
| 985 | * @return array Substitution array |
||
| 986 | */ |
||
| 987 | public function fill_substitutionarray_with_extrafields($object, $array_to_fill, $extrafields, $array_key, $outputlangs) |
||
| 988 | { |
||
| 989 | // phpcs:enable |
||
| 990 | global $conf; |
||
| 991 | |||
| 992 | if ($extrafields->attributes[$object->table_element]['count'] > 0) { |
||
| 993 | foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) { |
||
| 994 | $formatedarrayoption = $object->array_options; |
||
| 995 | |||
| 996 | if ($extrafields->attributes[$object->table_element]['type'][$key] == 'price') { |
||
| 997 | $formatedarrayoption['options_' . $key] = price2num($formatedarrayoption['options_' . $key]); |
||
| 998 | $formatedarrayoption['options_' . $key . '_currency'] = price($formatedarrayoption['options_' . $key], 0, $outputlangs, 0, 0, -1, $conf->currency); |
||
| 999 | //Add value to store price with currency |
||
| 1000 | $array_to_fill = array_merge($array_to_fill, array($array_key . '_options_' . $key . '_currency' => $formatedarrayoption['options_' . $key . '_currency'])); |
||
| 1001 | } elseif ($extrafields->attributes[$object->table_element]['type'][$key] == 'select') { |
||
| 1002 | $valueofselectkey = $formatedarrayoption['options_' . $key]; |
||
| 1003 | if (array_key_exists($valueofselectkey, $extrafields->attributes[$object->table_element]['param'][$key]['options'])) { |
||
| 1004 | $formatedarrayoption['options_' . $key] = $extrafields->attributes[$object->table_element]['param'][$key]['options'][$valueofselectkey]; |
||
| 1005 | } else { |
||
| 1006 | $formatedarrayoption['options_' . $key] = ''; |
||
| 1007 | } |
||
| 1008 | } elseif ($extrafields->attributes[$object->table_element]['type'][$key] == 'checkbox') { |
||
| 1009 | $valArray = explode(',', $formatedarrayoption['options_' . $key]); |
||
| 1010 | $output = array(); |
||
| 1011 | foreach ($extrafields->attributes[$object->table_element]['param'][$key]['options'] as $keyopt => $valopt) { |
||
| 1012 | if (in_array($keyopt, $valArray)) { |
||
| 1013 | $output[] = $valopt; |
||
| 1014 | } |
||
| 1015 | } |
||
| 1016 | $formatedarrayoption['options_' . $key] = implode(', ', $output); |
||
| 1017 | } elseif ($extrafields->attributes[$object->table_element]['type'][$key] == 'date') { |
||
| 1018 | if (strlen($formatedarrayoption['options_' . $key]) > 0) { |
||
| 1019 | $date = $formatedarrayoption['options_' . $key]; |
||
| 1020 | $formatedarrayoption['options_' . $key] = dol_print_date($date, 'day'); // using company output language |
||
| 1021 | $formatedarrayoption['options_' . $key . '_locale'] = dol_print_date($date, 'day', 'tzserver', $outputlangs); // using output language format |
||
| 1022 | $formatedarrayoption['options_' . $key . '_rfc'] = dol_print_date($date, 'dayrfc'); // international format |
||
| 1023 | } else { |
||
| 1024 | $formatedarrayoption['options_' . $key] = ''; |
||
| 1025 | $formatedarrayoption['options_' . $key . '_locale'] = ''; |
||
| 1026 | $formatedarrayoption['options_' . $key . '_rfc'] = ''; |
||
| 1027 | } |
||
| 1028 | $array_to_fill = array_merge($array_to_fill, array($array_key . '_options_' . $key . '_locale' => $formatedarrayoption['options_' . $key . '_locale'])); |
||
| 1029 | $array_to_fill = array_merge($array_to_fill, array($array_key . '_options_' . $key . '_rfc' => $formatedarrayoption['options_' . $key . '_rfc'])); |
||
| 1030 | } elseif ($extrafields->attributes[$object->table_element]['type'][$key] == 'datetime') { |
||
| 1031 | $datetime = $formatedarrayoption['options_' . $key]; |
||
| 1032 | $formatedarrayoption['options_' . $key] = ($datetime != "0000-00-00 00:00:00" ? dol_print_date($datetime, 'dayhour') : ''); // using company output language |
||
| 1033 | $formatedarrayoption['options_' . $key . '_locale'] = ($datetime != "0000-00-00 00:00:00" ? dol_print_date($datetime, 'dayhour', 'tzserver', $outputlangs) : ''); // using output language format |
||
| 1034 | $formatedarrayoption['options_' . $key . '_rfc'] = ($datetime != "0000-00-00 00:00:00" ? dol_print_date($datetime, 'dayhourrfc') : ''); // international format |
||
| 1035 | $array_to_fill = array_merge($array_to_fill, array($array_key . '_options_' . $key . '_locale' => $formatedarrayoption['options_' . $key . '_locale'])); |
||
| 1036 | $array_to_fill = array_merge($array_to_fill, array($array_key . '_options_' . $key . '_rfc' => $formatedarrayoption['options_' . $key . '_rfc'])); |
||
| 1037 | } elseif ($extrafields->attributes[$object->table_element]['type'][$key] == 'link') { |
||
| 1038 | $id = $formatedarrayoption['options_' . $key]; |
||
| 1039 | if ($id != "") { |
||
| 1040 | $param = $extrafields->attributes[$object->table_element]['param'][$key]; |
||
| 1041 | $param_list = array_keys($param['options']); // $param_list='ObjectName:classPath' |
||
| 1042 | $InfoFieldList = explode(":", $param_list[0]); |
||
| 1043 | $classname = $InfoFieldList[0]; |
||
| 1044 | $classpath = $InfoFieldList[1]; |
||
| 1045 | if (!empty($classpath)) { |
||
| 1046 | dol_include_once($InfoFieldList[1]); |
||
| 1047 | if ($classname && class_exists($classname)) { |
||
| 1048 | $tmpobject = new $classname($this->db); |
||
| 1049 | $tmpobject->fetch($id); |
||
| 1050 | // completely replace the id with the linked object name |
||
| 1051 | $formatedarrayoption['options_' . $key] = $tmpobject->name; |
||
| 1052 | } |
||
| 1053 | } |
||
| 1054 | } |
||
| 1055 | } |
||
| 1056 | |||
| 1057 | if (array_key_exists('options_' . $key, $formatedarrayoption)) { |
||
| 1058 | $array_to_fill = array_merge($array_to_fill, array($array_key . '_options_' . $key => $formatedarrayoption['options_' . $key])); |
||
| 1059 | } else { |
||
| 1060 | $array_to_fill = array_merge($array_to_fill, array($array_key . '_options_' . $key => '')); |
||
| 1061 | } |
||
| 1062 | } |
||
| 1063 | } |
||
| 1064 | |||
| 1065 | return $array_to_fill; |
||
| 1066 | } |
||
| 1067 | |||
| 1068 | |||
| 1069 | /** |
||
| 1070 | * Rect pdf |
||
| 1071 | * |
||
| 1072 | * @param TCPDI|TCPDF $pdf Pdf object |
||
| 1073 | * @param float $x Abscissa of first point |
||
| 1074 | * @param float $y Ordinate of first point |
||
| 1075 | * @param float $l ?? |
||
| 1076 | * @param float $h ?? |
||
| 1077 | * @param int $hidetop 1=Hide top bar of array and title, 0=Hide nothing, -1=Hide only title |
||
| 1078 | * @param int $hidebottom Hide bottom |
||
| 1079 | * @return void |
||
| 1080 | */ |
||
| 1081 | public function printRect($pdf, $x, $y, $l, $h, $hidetop = 0, $hidebottom = 0) |
||
| 1082 | { |
||
| 1083 | if (empty($hidetop) || $hidetop == -1) { |
||
| 1084 | $pdf->line($x, $y, $x + $l, $y); |
||
| 1085 | } |
||
| 1086 | $pdf->line($x + $l, $y, $x + $l, $y + $h); |
||
| 1087 | if (empty($hidebottom)) { |
||
| 1088 | $pdf->line($x + $l, $y + $h, $x, $y + $h); |
||
| 1089 | } |
||
| 1090 | $pdf->line($x, $y + $h, $x, $y); |
||
| 1091 | } |
||
| 1092 | |||
| 1093 | |||
| 1094 | /** |
||
| 1095 | * uasort callback function to Sort columns fields |
||
| 1096 | * |
||
| 1097 | * @param array $a PDF lines array fields configs |
||
| 1098 | * @param array $b PDF lines array fields configs |
||
| 1099 | * @return int Return compare result |
||
| 1100 | */ |
||
| 1101 | public function columnSort($a, $b) |
||
| 1102 | { |
||
| 1103 | if (empty($a['rank'])) { |
||
| 1104 | $a['rank'] = 0; |
||
| 1105 | } |
||
| 1106 | if (empty($b['rank'])) { |
||
| 1107 | $b['rank'] = 0; |
||
| 1108 | } |
||
| 1109 | if ($a['rank'] == $b['rank']) { |
||
| 1110 | return 0; |
||
| 1111 | } |
||
| 1112 | return ($a['rank'] > $b['rank']) ? -1 : 1; |
||
| 1113 | } |
||
| 1114 | |||
| 1115 | /** |
||
| 1116 | * Prepare Array Column Field |
||
| 1117 | * |
||
| 1118 | * @param object $object common object |
||
| 1119 | * @param Translate $outputlangs langs |
||
| 1120 | * @param int $hidedetails Do not show line details |
||
| 1121 | * @param int $hidedesc Do not show desc |
||
| 1122 | * @param int $hideref Do not show ref |
||
| 1123 | * @return void |
||
| 1124 | */ |
||
| 1125 | public function prepareArrayColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0) |
||
| 1126 | { |
||
| 1127 | $this->defineColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref); |
||
| 1128 | |||
| 1129 | |||
| 1130 | // Sorting |
||
| 1131 | uasort($this->cols, array($this, 'columnSort')); |
||
| 1132 | |||
| 1133 | // Positioning |
||
| 1134 | $curX = $this->page_largeur - $this->marge_droite; // start from right |
||
| 1135 | |||
| 1136 | // Array width |
||
| 1137 | $arrayWidth = $this->page_largeur - $this->marge_droite - $this->marge_gauche; |
||
| 1138 | |||
| 1139 | // Count flexible column |
||
| 1140 | $totalDefinedColWidth = 0; |
||
| 1141 | $countFlexCol = 0; |
||
| 1142 | foreach ($this->cols as $colKey => & $colDef) { |
||
| 1143 | if (!$this->getColumnStatus($colKey)) { |
||
| 1144 | continue; // continue if disabled |
||
| 1145 | } |
||
| 1146 | |||
| 1147 | if (!empty($colDef['scale'])) { |
||
| 1148 | // In case of column width is defined by percentage |
||
| 1149 | $colDef['width'] = abs($arrayWidth * $colDef['scale'] / 100); |
||
| 1150 | } |
||
| 1151 | |||
| 1152 | if (empty($colDef['width'])) { |
||
| 1153 | $countFlexCol++; |
||
| 1154 | } else { |
||
| 1155 | $totalDefinedColWidth += $colDef['width']; |
||
| 1156 | } |
||
| 1157 | } |
||
| 1158 | |||
| 1159 | foreach ($this->cols as $colKey => & $colDef) { |
||
| 1160 | // setting empty conf with default |
||
| 1161 | if (!empty($colDef['title'])) { |
||
| 1162 | $colDef['title'] = array_replace($this->defaultTitlesFieldsStyle, $colDef['title']); |
||
| 1163 | } else { |
||
| 1164 | $colDef['title'] = $this->defaultTitlesFieldsStyle; |
||
| 1165 | } |
||
| 1166 | |||
| 1167 | // setting empty conf with default |
||
| 1168 | if (!empty($colDef['content'])) { |
||
| 1169 | $colDef['content'] = array_replace($this->defaultContentsFieldsStyle, $colDef['content']); |
||
| 1170 | } else { |
||
| 1171 | $colDef['content'] = $this->defaultContentsFieldsStyle; |
||
| 1172 | } |
||
| 1173 | |||
| 1174 | if ($this->getColumnStatus($colKey)) { |
||
| 1175 | // In case of flexible column |
||
| 1176 | if (empty($colDef['width'])) { |
||
| 1177 | $colDef['width'] = abs(($arrayWidth - $totalDefinedColWidth)) / $countFlexCol; |
||
| 1178 | } |
||
| 1179 | |||
| 1180 | // Set positions |
||
| 1181 | $lastX = $curX; |
||
| 1182 | $curX = $lastX - $colDef['width']; |
||
| 1183 | $colDef['xStartPos'] = $curX; |
||
| 1184 | $colDef['xEndPos'] = $lastX; |
||
| 1185 | } |
||
| 1186 | } |
||
| 1187 | } |
||
| 1188 | |||
| 1189 | /** |
||
| 1190 | * get column content width from column key |
||
| 1191 | * |
||
| 1192 | * @param string $colKey the column key |
||
| 1193 | * @return float width in mm |
||
| 1194 | */ |
||
| 1195 | public function getColumnContentWidth($colKey) |
||
| 1199 | } |
||
| 1200 | |||
| 1201 | |||
| 1202 | /** |
||
| 1203 | * get column content X (abscissa) left position from column key |
||
| 1204 | * |
||
| 1205 | * @param string $colKey the column key |
||
| 1206 | * @return float X position in mm |
||
| 1207 | */ |
||
| 1208 | public function getColumnContentXStart($colKey) |
||
| 1209 | { |
||
| 1210 | $colDef = (isset($this->cols[$colKey]) ? $this->cols[$colKey] : null); |
||
| 1211 | return (is_array($colDef) ? ((isset($colDef['xStartPos']) ? $colDef['xStartPos'] : 0) + $colDef['content']['padding'][3]) : 0); |
||
| 1212 | } |
||
| 1213 | |||
| 1214 | /** |
||
| 1215 | * get column position rank from column key |
||
| 1216 | * |
||
| 1217 | * @param string $colKey the column key |
||
| 1218 | * @return int rank on success and -1 on error |
||
| 1219 | */ |
||
| 1220 | public function getColumnRank($colKey) |
||
| 1221 | { |
||
| 1222 | if (!isset($this->cols[$colKey]['rank'])) { |
||
| 1223 | return -1; |
||
| 1224 | } |
||
| 1225 | return $this->cols[$colKey]['rank']; |
||
| 1226 | } |
||
| 1227 | |||
| 1228 | /** |
||
| 1229 | * get column position rank from column key |
||
| 1230 | * |
||
| 1231 | * @param string $newColKey the new column key |
||
| 1232 | * @param array $defArray a single column definition array |
||
| 1233 | * @param string $targetCol target column used to place the new column beside |
||
| 1234 | * @param bool $insertAfterTarget insert before or after target column ? |
||
| 1235 | * @return int new rank on success and -1 on error |
||
| 1236 | */ |
||
| 1237 | public function insertNewColumnDef($newColKey, $defArray, $targetCol = '', $insertAfterTarget = false) |
||
| 1238 | { |
||
| 1239 | // prepare wanted rank |
||
| 1240 | $rank = -1; |
||
| 1241 | |||
| 1242 | // try to get rank from target column |
||
| 1243 | if (!empty($targetCol)) { |
||
| 1244 | $rank = $this->getColumnRank($targetCol); |
||
| 1245 | if ($rank >= 0 && $insertAfterTarget) { |
||
| 1246 | $rank++; |
||
| 1247 | } |
||
| 1248 | } |
||
| 1249 | |||
| 1250 | // get rank from new column definition |
||
| 1251 | if ($rank < 0 && !empty($defArray['rank'])) { |
||
| 1252 | $rank = $defArray['rank']; |
||
| 1253 | } |
||
| 1254 | |||
| 1255 | // error: no rank |
||
| 1256 | if ($rank < 0) { |
||
| 1257 | return -1; |
||
| 1258 | } |
||
| 1259 | |||
| 1260 | foreach ($this->cols as $colKey => & $colDef) { |
||
| 1261 | if ($rank <= $colDef['rank']) { |
||
| 1262 | $colDef['rank'] = $colDef['rank'] + 1; |
||
| 1263 | } |
||
| 1264 | } |
||
| 1265 | |||
| 1266 | $defArray['rank'] = $rank; |
||
| 1267 | $this->cols[$newColKey] = $defArray; // array_replace is used to preserve keys |
||
| 1268 | |||
| 1269 | return $rank; |
||
| 1270 | } |
||
| 1271 | |||
| 1272 | |||
| 1273 | /** |
||
| 1274 | * print standard column content |
||
| 1275 | * |
||
| 1276 | * @param TCPDI|TCPDF $pdf Pdf object |
||
| 1277 | * @param float $curY current Y position |
||
| 1278 | * @param string $colKey the column key |
||
| 1279 | * @param string $columnText column text |
||
| 1280 | * @return int Return integer <0 if KO, >= if OK |
||
| 1281 | */ |
||
| 1282 | public function printStdColumnContent($pdf, &$curY, $colKey, $columnText = '') |
||
| 1313 | } |
||
| 1314 | |||
| 1315 | |||
| 1316 | /** |
||
| 1317 | * print description column content |
||
| 1318 | * |
||
| 1319 | * @param TCPDI|TCPDF $pdf Pdf object |
||
| 1320 | * @param float $curY current Y position |
||
| 1321 | * @param string $colKey the column key |
||
| 1322 | * @param object $object CommonObject |
||
| 1323 | * @param int $i the $object->lines array key |
||
| 1324 | * @param Translate $outputlangs Output language |
||
| 1325 | * @param int $hideref hide ref |
||
| 1326 | * @param int $hidedesc hide desc |
||
| 1327 | * @param int $issupplierline if object need supplier product |
||
| 1328 | * @return void |
||
| 1329 | */ |
||
| 1330 | public function printColDescContent($pdf, &$curY, $colKey, $object, $i, $outputlangs, $hideref = 0, $hidedesc = 0, $issupplierline = 0) |
||
| 1355 | } |
||
| 1356 | } |
||
| 1357 | |||
| 1358 | /** |
||
| 1359 | * get extrafield content for pdf writeHtmlCell compatibility |
||
| 1360 | * usage for PDF line columns and object note block |
||
| 1361 | * |
||
| 1362 | * @param CommonObject $object Common object |
||
| 1363 | * @param string $extrafieldKey The extrafield key |
||
| 1364 | * @param Translate $outputlangs The output langs (if value is __(XXX)__ we use it to translate it). |
||
| 1365 | * @return string |
||
| 1366 | */ |
||
| 1367 | public function getExtrafieldContent($object, $extrafieldKey, $outputlangs = null) |
||
| 1421 | } |
||
| 1422 | |||
| 1423 | /** |
||
| 1424 | * display extrafields columns content |
||
| 1425 | * |
||
| 1426 | * @param CommonObjectLine $object line of common object |
||
| 1427 | * @param Translate $outputlangs Output language |
||
| 1428 | * @param array $params array of additional parameters |
||
| 1429 | * @return string Html string |
||
| 1430 | */ |
||
| 1431 | public function getExtrafieldsInHtml($object, $outputlangs, $params = array()) |
||
| 1432 | { |
||
| 1433 | global $hookmanager; |
||
| 1434 | |||
| 1435 | if (empty($object->table_element)) { |
||
| 1436 | return ""; |
||
| 1437 | } |
||
| 1438 | |||
| 1439 | // Load extrafields if not already done |
||
| 1440 | if (is_null($this->extrafieldsCache)) { |
||
| 1441 | $this->extrafieldsCache = new ExtraFields($this->db); |
||
| 1442 | } |
||
| 1443 | if (empty($this->extrafieldsCache->attributes[$object->table_element])) { |
||
| 1444 | $this->extrafieldsCache->fetch_name_optionals_label($object->table_element); |
||
| 1445 | } |
||
| 1446 | $extrafields = $this->extrafieldsCache; |
||
| 1447 | |||
| 1448 | $defaultParams = array( |
||
| 1449 | 'style' => '', |
||
| 1450 | 'display' => 'auto', // auto, table, list |
||
| 1451 | 'printableEnable' => array(1), |
||
| 1452 | 'printableEnableNotEmpty' => array(2), |
||
| 1453 | |||
| 1454 | 'table' => array( |
||
| 1455 | 'maxItemsInRow' => 2, |
||
| 1456 | 'cellspacing' => 0, |
||
| 1457 | 'cellpadding' => 0, |
||
| 1458 | 'border' => 0, |
||
| 1459 | 'labelcolwidth' => '25%', |
||
| 1460 | 'arrayOfLineBreakType' => array('text', 'html') |
||
| 1461 | ), |
||
| 1462 | |||
| 1463 | 'list' => array( |
||
| 1464 | 'separator' => '<br>' |
||
| 1465 | ), |
||
| 1466 | |||
| 1467 | 'auto' => array( |
||
| 1468 | 'list' => 0, // 0 for default |
||
| 1469 | 'table' => 4 // if there more than x extrafield to display |
||
| 1470 | ), |
||
| 1471 | ); |
||
| 1472 | |||
| 1473 | $params = $params + $defaultParams; |
||
| 1474 | |||
| 1475 | /** |
||
| 1476 | * @var ExtraFields $extrafields |
||
| 1477 | */ |
||
| 1478 | |||
| 1479 | $html = ''; |
||
| 1480 | $fields = array(); |
||
| 1481 | |||
| 1482 | if (!empty($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label'])) { |
||
| 1483 | foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) { |
||
| 1484 | // Enable extrafield ? |
||
| 1485 | $enabled = 0; |
||
| 1486 | $disableOnEmpty = 0; |
||
| 1487 | if (!empty($extrafields->attributes[$object->table_element]['printable'][$key])) { |
||
| 1488 | $printable = intval($extrafields->attributes[$object->table_element]['printable'][$key]); |
||
| 1489 | if (in_array($printable, $params['printableEnable']) || in_array($printable, $params['printableEnableNotEmpty'])) { |
||
| 1490 | $enabled = 1; |
||
| 1491 | } |
||
| 1492 | |||
| 1493 | if (in_array($printable, $params['printableEnableNotEmpty'])) { |
||
| 1494 | $disableOnEmpty = 1; |
||
| 1495 | } |
||
| 1496 | } |
||
| 1497 | |||
| 1498 | if (empty($enabled)) { |
||
| 1499 | continue; |
||
| 1500 | } |
||
| 1501 | |||
| 1502 | // Load language if required |
||
| 1503 | if (!empty($extrafields->attributes[$object->table_element]['langfile'][$key])) { |
||
| 1504 | $outputlangs->load($extrafields->attributes[$object->table_element]['langfile'][$key]); |
||
| 1505 | } |
||
| 1506 | |||
| 1507 | $field = new stdClass(); |
||
| 1508 | $field->rank = intval($extrafields->attributes[$object->table_element]['pos'][$key]); |
||
| 1509 | $field->content = $this->getExtrafieldContent($object, $key, $outputlangs); |
||
| 1510 | $field->label = $outputlangs->transnoentities($label); |
||
| 1511 | $field->type = $extrafields->attributes[$object->table_element]['type'][$key]; |
||
| 1512 | |||
| 1513 | // don't display if empty |
||
| 1514 | if ($disableOnEmpty && empty($field->content)) { |
||
| 1515 | continue; |
||
| 1516 | } |
||
| 1517 | |||
| 1518 | $fields[] = $field; |
||
| 1519 | } |
||
| 1520 | } |
||
| 1521 | |||
| 1522 | if (!empty($fields)) { |
||
| 1523 | // Sort extrafields by rank |
||
| 1524 | uasort( |
||
| 1525 | $fields, |
||
| 1526 | /** |
||
| 1527 | * @param stdClass $a |
||
| 1528 | * @param stdClass $b |
||
| 1529 | * @return int<-1,1> |
||
| 1530 | */ |
||
| 1531 | static function ($a, $b) { |
||
| 1532 | return ($a->rank > $b->rank) ? 1 : -1; |
||
| 1533 | } |
||
| 1534 | ); |
||
| 1535 | |||
| 1536 | // define some HTML content with style |
||
| 1537 | $html .= !empty($params['style']) ? '<style>' . $params['style'] . '</style>' : ''; |
||
| 1538 | |||
| 1539 | // auto select display format |
||
| 1540 | if ($params['display'] == 'auto') { |
||
| 1541 | $lastNnumbItems = 0; |
||
| 1542 | foreach ($params['auto'] as $display => $numbItems) { |
||
| 1543 | if ($lastNnumbItems <= $numbItems && count($fields) > $numbItems) { |
||
| 1544 | $lastNnumbItems = $numbItems; |
||
| 1545 | $params['display'] = $display; |
||
| 1546 | } |
||
| 1547 | } |
||
| 1548 | } |
||
| 1549 | |||
| 1550 | if ($params['display'] == 'list') { |
||
| 1551 | // Display in list format |
||
| 1552 | $i = 0; |
||
| 1553 | foreach ($fields as $field) { |
||
| 1554 | $html .= !empty($i) ? $params['list']['separator'] : ''; |
||
| 1555 | $html .= '<strong>' . $field->label . ' : </strong>'; |
||
| 1556 | $html .= $field->content; |
||
| 1557 | $i++; |
||
| 1558 | } |
||
| 1559 | } elseif ($params['display'] == 'table') { |
||
| 1560 | // Display in table format |
||
| 1561 | $html .= '<table class="extrafield-table" cellspacing="' . $params['table']['cellspacing'] . '" cellpadding="' . $params['table']['cellpadding'] . '" border="' . $params['table']['border'] . '">'; |
||
| 1562 | |||
| 1563 | $html .= "<tr>"; |
||
| 1564 | $itemsInRow = 0; |
||
| 1565 | $maxItemsInRow = $params['table']['maxItemsInRow']; |
||
| 1566 | foreach ($fields as $field) { |
||
| 1567 | //$html.= !empty($html)?'<br>':''; |
||
| 1568 | if ($itemsInRow >= $maxItemsInRow) { |
||
| 1569 | // start a new line |
||
| 1570 | $html .= "</tr><tr>"; |
||
| 1571 | $itemsInRow = 0; |
||
| 1572 | } |
||
| 1573 | |||
| 1574 | // for some type we need line break |
||
| 1575 | if (in_array($field->type, $params['table']['arrayOfLineBreakType'])) { |
||
| 1576 | if ($itemsInRow > 0) { |
||
| 1577 | // close table row and empty cols |
||
| 1578 | for ($i = $itemsInRow; $i <= $maxItemsInRow; $i++) { |
||
| 1579 | $html .= "<td></td><td></td>"; |
||
| 1580 | } |
||
| 1581 | $html .= "</tr>"; |
||
| 1582 | |||
| 1583 | // start a new line |
||
| 1584 | $html .= "<tr>"; |
||
| 1585 | } |
||
| 1586 | |||
| 1587 | $itemsInRow = $maxItemsInRow; |
||
| 1588 | $html .= '<td colspan="' . ($maxItemsInRow * 2 - 1) . '">'; |
||
| 1589 | $html .= '<strong>' . $field->label . ' :</strong> '; |
||
| 1590 | $html .= $field->content; |
||
| 1591 | $html .= "</td>"; |
||
| 1592 | } else { |
||
| 1593 | $itemsInRow++; |
||
| 1594 | $html .= '<td width="' . $params['table']['labelcolwidth'] . '" class="extrafield-label">'; |
||
| 1595 | $html .= '<strong>' . $field->label . ' :</strong>'; |
||
| 1596 | $html .= "</td>"; |
||
| 1597 | |||
| 1598 | |||
| 1599 | $html .= '<td class="extrafield-content">'; |
||
| 1600 | $html .= $field->content; |
||
| 1601 | $html .= "</td>"; |
||
| 1602 | } |
||
| 1603 | } |
||
| 1604 | $html .= "</tr>"; |
||
| 1605 | |||
| 1606 | $html .= '</table>'; |
||
| 1607 | } |
||
| 1608 | } |
||
| 1609 | |||
| 1610 | return $html; |
||
| 1611 | } |
||
| 1612 | |||
| 1613 | |||
| 1614 | /** |
||
| 1615 | * get column status from column key |
||
| 1616 | * |
||
| 1617 | * @param string $colKey the column key |
||
| 1618 | * @return boolean true if column on |
||
| 1619 | */ |
||
| 1620 | public function getColumnStatus($colKey) |
||
| 1621 | { |
||
| 1622 | if (!empty($this->cols[$colKey]['status'])) { |
||
| 1623 | return true; |
||
| 1624 | } else { |
||
| 1625 | return false; |
||
| 1626 | } |
||
| 1627 | } |
||
| 1628 | |||
| 1629 | /** |
||
| 1630 | * Print standard column content |
||
| 1631 | * |
||
| 1632 | * @param TCPDI|TCPDF $pdf Pdf object |
||
| 1633 | * @param float $tab_top Tab top position |
||
| 1634 | * @param float $tab_height Default tab height |
||
| 1635 | * @param Translate $outputlangs Output language |
||
| 1636 | * @param int $hidetop Hide top |
||
| 1637 | * @return float Height of col tab titles |
||
| 1638 | */ |
||
| 1639 | public function pdfTabTitles(&$pdf, $tab_top, $tab_height, $outputlangs, $hidetop = 0) |
||
| 1708 | } |
||
| 1709 | |||
| 1710 | |||
| 1711 | |||
| 1712 | /** |
||
| 1713 | * Define Array Column Field for extrafields |
||
| 1714 | * |
||
| 1715 | * @param object $object common object det |
||
| 1716 | * @param Translate $outputlangs langs |
||
| 1717 | * @param int $hidedetails Do not show line details |
||
| 1718 | * @return int Return integer <0 if KO, >=0 if OK |
||
| 1719 | */ |
||
| 1720 | public function defineColumnExtrafield($object, $outputlangs, $hidedetails = 0) |
||
| 1799 | } |
||
| 1800 | |||
| 1801 | /** |
||
| 1802 | * Define Array Column Field into $this->cols |
||
| 1803 | * This method must be implemented by the module that generate the document with its own columns. |
||
| 1804 | * |
||
| 1805 | * @param Object $object Common object |
||
| 1806 | * @param Translate $outputlangs Langs |
||
| 1807 | * @param int $hidedetails Do not show line details |
||
| 1808 | * @param int $hidedesc Do not show desc |
||
| 1809 | * @param int $hideref Do not show ref |
||
| 1810 | * @return void |
||
| 1811 | */ |
||
| 1812 | public function defineColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0) |
||
| 1848 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountIdthat can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theidproperty of an instance of theAccountclass. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.