diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index f113a8a7a36..fb05f408e57 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -28,7 +28,7 @@ jobs: # This is faster for a big repo. - name: Get all changed php files (if PR) id: changed-php - uses: tj-actions/changed-files@v43 + uses: tj-actions/changed-files@v44 if: env.gh_event == 'pull_request' with: files: | @@ -66,7 +66,7 @@ jobs: # The next uses git, which is slow for a bit repo. # - name: Get all changed php files (if PR) # id: changed-php - # uses: tj-actions/changed-files@v43 + # uses: tj-actions/changed-files@v44 # if: env.gh_event == 'pull_request' # with: # files: | @@ -115,7 +115,7 @@ jobs: ls -l ~/.cache/pre-commit/ - name: Convert Raw Log to Annotations - uses: mdeweerd/logToCheckStyle@v2024.3.4 + uses: mdeweerd/logToCheckStyle@v2024.3.5 if: ${{ failure() }} with: in: ${{ env.RAW_LOG }} diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/windows-ci.yml index f85ad2535be..7f550037416 100644 --- a/.github/workflows/windows-ci.yml +++ b/.github/workflows/windows-ci.yml @@ -157,7 +157,7 @@ jobs: for /f "tokens=2 delims==" %%A in ('doskey /m:err') do EXIT /B %%A - name: Convert Raw Log to Annotations - uses: mdeweerd/logToCheckStyle@v2024.3.4 + uses: mdeweerd/logToCheckStyle@v2024.3.5 if: ${{ failure() }} with: in: ${{ env.PHPUNIT_LOG }} diff --git a/ChangeLog b/ChangeLog index d8efc905db7..00d936e3deb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,7 +7,7 @@ English Dolibarr ChangeLog For users: ---------- -NEW: Compatibility with PHP 8.3 +NEW: Compatibility with PHP 8.2 (with no need to disable warnings) ... For developers or integrators: @@ -34,6 +34,10 @@ The following changes may create regressions for some external modules, but were the deprecated field $fk_user_done in actioncomm table is removed. Please use $fk_user_action instead. * The table commande_fournisseur_dispatch has been renamed into receptiondet_batch to better match its goal and the field fk_commande and fk_commandefourndet were renamed into fk_element and fk_elementdet +* Removed trigger BILLREC_CREATEBILL. This trigger was not a CRUD event. If you used it, you can already use the trigger BILL_CREATE and + test that ($object->fac_rec > 0) to know if creation trigger is from a recurring invoice or not. Also this old trigger was never enabled + into table llx_c_action_trigger. + ***** ChangeLog for 19.0.1 compared to 19.0.0 ***** diff --git a/build/exe/doliwamp/index.php.install b/build/exe/doliwamp/index.php.install index 0df983529f4..2ccd4a5ff66 100644 --- a/build/exe/doliwamp/index.php.install +++ b/build/exe/doliwamp/index.php.install @@ -3,7 +3,7 @@ // Page created by Shepard [Fabian Pijcke] // Arno Esterhuizen // and Romain Bourdon -// +// // icones by Mark James // // Modified from WampServer project by Laurent Destailleur (NLTechno) @@ -260,7 +260,7 @@ if (isset($_GET['askhelp'])) // Show PHPInfo if (isset($_GET['phpinfo'])) { - phpinfo(); + phpinfo(INFO_GENERAL|INFO_MODULES); exit(); } @@ -274,27 +274,27 @@ if (isset($_GET['img'])) header("Content-type: image/png"); echo base64_decode($pngFolder); exit(); - + case 'pngFolderGo' : header("Content-type: image/png"); echo base64_decode($pngFolderGo); exit(); - + case 'pngLogo' : header("Content-type: image/png"); echo base64_decode($pngLogo); exit(); - + case 'pngPlugin' : header("Content-type: image/png"); echo base64_decode($pngPlugin); exit(); - + case 'pngWrench' : header("Content-type: image/png"); echo base64_decode($pngWrench); exit(); - + case 'favicon' : header("Content-type: image/x-icon"); echo base64_decode($favicon); @@ -324,7 +324,7 @@ foreach ($loaded_extensions as $extension) { $phpExtContents .= "
  • ${extension}
  • "; } - + // Read alias directory $listoffile=array(); $aliasarray=array(); @@ -337,10 +337,10 @@ if (is_dir($aliasDir)) { } } sort($listoffiles); - + foreach($listoffiles as $file) { if (is_file($aliasDir.$file) && preg_match('/\.conf/',$file)) - { + { $msg = ''; $aliasContents.='
      '; @@ -350,7 +350,7 @@ if (is_dir($aliasDir)) { if (preg_match('/dolibarr/i',$file)) $aliasContents .= $file.'
    http://localhost'.($apachePort != 80?':'.$apachePort:'').'/'.$file.'/http://ipofyourserver'.($apachePort != 80?':'.$apachePort:'').'/'.$file.'/'; elseif (preg_match('/phpmyadmin/i',$file)) $aliasContents .= $file.'http://localhost'.($apachePort != 80?':'.$apachePort:'').'/'.$file.'/'.$langues[$langue]['NotAvailable'].''; else $aliasContents .= $file.' '.$langues[$langue]['NotAvailable'].''; - + $aliasarray[]=$file; } } @@ -358,13 +358,13 @@ if (is_dir($aliasDir)) { } if (!isset($aliasContents)) $aliasContents = ''.$langues[$langue]['txtNoAlias'].''; - + // Read projects in www dir $listoffiles=array(); $handle=opendir("."); if (is_resource($handle)) { - while ($file = readdir($handle)) + while ($file = readdir($handle)) { $listoffiles[]=$file; } @@ -372,14 +372,14 @@ if (is_resource($handle)) { } foreach($listoffiles as $file) { - if (is_dir($file) && !in_array($file,$projectsListIgnore) && !in_array($file,$aliasarray)) - { + if (is_dir($file) && !in_array($file,$projectsListIgnore) && !in_array($file,$aliasarray)) + { $projectContents .= 'http://localhost'.($apachePort != 80?':'.$apachePort:'').'/'.$file.'/)'.''.$langues[$langue]['NotAvailable'].''; } } @@ -509,7 +509,7 @@ a:hover { font-size: 0.85em; } - + @@ -533,7 +533,7 @@ a:hover {
    ${apacheVersion}  
    {$langues[$langue]['versp']}
    ${phpVersion}  
    -
    {$langues[$langue]['phpExt']}
    +
    {$langues[$langue]['phpExt']}
      ${phpExtContents} @@ -554,8 +554,8 @@ a:hover { {$langues[$langue]['FromInternet']} - ${aliasContents} - ${projectContents} + ${aliasContents} + ${projectContents}

      {$langues[$langue]['titrePage']}

      diff --git a/dev/examples/mail/source_email_ticket_2_answer_from_ticket.txt b/dev/examples/mail/source_email_ticket_2_answer_from_ticket.txt index 350b9a93cad..969d4eec95a 100644 --- a/dev/examples/mail/source_email_ticket_2_answer_from_ticket.txt +++ b/dev/examples/mail/source_email_ticket_2_answer_from_ticket.txt @@ -10,7 +10,8 @@ To: customer@customercompany.fr Subject: [MyBigCompany - Ticket #TS2008-0040] Nouveau message Date: Thu, 20 Aug 2020 18:31:37 +0200 Message-ID: <1597941097.SMTPs-dolibarr-tic58@83b5bc91f83a56e458db71e0adac2b62> -References: <1597941097.SMTPs-dolibarr-tic58@83b5bc91f83a56e458db71e0adac2b62> +References: +In-Reply-To: X-Dolibarr-TRACKID: tic58@83b5bc91f83a56e458db71e0adac2b62 X-RemoteAddr: 127.0.0.1 X-Mailer: Dolibarr version 13.0.0-alpha (using SMTPs Mailer) @@ -25,17 +26,17 @@ Content-Type: multipart/alternative; boundary="mul_872cdd6a64216735955664484832b --mul_872cdd6a64216735955664484832b075 Content-Type: text/plain; charset=UTF-8 -Bonjour +Bonjour + - Une nouvelle réponse a été ajoutée à un ticket que vous suivez. Voici -le message :PredefinedMailContentTicket_send - - +le message :PredefinedMailContentTicket_send + + Vous pouvez voir la progression du ticket en cliquant sur le lien -ci-dessus. : fr5uw2yospypn2rz - Cordialement, - +ci-dessus. : fr5uw2yospypn2rz + Cordialement, + -- --mul_872cdd6a64216735955664484832b075 Content-Type: text/html; charset=UTF-8 diff --git a/dev/tools/codespell/codespell-dict.txt b/dev/tools/codespell/codespell-dict.txt index ad8c0ecf617..32bfa0aa414 100644 --- a/dev/tools/codespell/codespell-dict.txt +++ b/dev/tools/codespell/codespell-dict.txt @@ -18,9 +18,11 @@ dollibarr->dolibarr extrafeild->extrafield thoose->those # fiche->card +nempty->an empty, empty, not empty, mot de passe->password not de passe->password nothtml->nohtml +shippin->shipping tableau de bord->state board tagret->target thridparty->thirdparty diff --git a/dev/tools/phan/baseline.txt b/dev/tools/phan/baseline.txt index 52c70f4f641..6fa9139c750 100644 --- a/dev/tools/phan/baseline.txt +++ b/dev/tools/phan/baseline.txt @@ -9,23 +9,21 @@ */ return [ // # Issue statistics: - // PhanParamSignatureMismatch : 25+ occurrences + // PhanParamSignatureMismatch : 20+ occurrences // PhanPluginSuspiciousParamPosition : 15+ occurrences // PhanUndeclaredConstant : 15+ occurrences // PhanPluginDuplicateExpressionBinaryOp : 10+ occurrences - // PhanTypeMismatchReturn : 8 occurrences - // PhanRedefineFunctionInternal : 6 occurrences - // PhanTypeArraySuspiciousNull : 6 occurrences + // PhanTypeMismatchReturn : 5 occurrences // PhanParamTooMany : 4 occurrences - // PhanTypeMismatchReturnNullable : 3 occurrences // PhanAccessMethodProtected : 1 occurrence // PhanAccessPropertyStaticAsNonStatic : 1 occurrence // PhanNoopStringLiteral : 1 occurrence + // PhanTypeArraySuspiciousNull : 1 occurrence // Currently, file_suppressions and directory_suppressions are the only supported suppressions 'file_suppressions' => [ + 'htdocs/adherents/admin/member.php' => ['PhanParamTooMany'], 'htdocs/adherents/type.php' => ['PhanPluginDuplicateExpressionBinaryOp'], - 'htdocs/admin/receiptprinter.php' => ['PhanRedefineFunctionInternal'], 'htdocs/api/class/api_documents.class.php' => ['PhanPluginDuplicateExpressionBinaryOp'], 'htdocs/barcode/printsheet.php' => ['PhanPluginDuplicateExpressionBinaryOp'], 'htdocs/categories/class/api_categories.class.php' => ['PhanAccessMethodProtected'], @@ -35,23 +33,15 @@ return [ 'htdocs/compta/cashcontrol/cashcontrol_card.php' => ['PhanPluginDuplicateExpressionBinaryOp'], 'htdocs/compta/prelevement/class/bonprelevement.class.php' => ['PhanParamTooMany'], 'htdocs/compta/prelevement/create.php' => ['PhanPluginSuspiciousParamPosition'], - 'htdocs/core/class/commondocgenerator.class.php' => ['PhanTypeArraySuspiciousNull'], - 'htdocs/core/class/commonobject.class.php' => ['PhanTypeMismatchReturnNullable'], - 'htdocs/core/class/extrafields.class.php' => ['PhanTypeMismatchReturnNullable'], 'htdocs/core/class/html.form.class.php' => ['PhanPluginSuspiciousParamPosition'], 'htdocs/core/db/mysqli.class.php' => ['PhanParamSignatureMismatch'], 'htdocs/core/db/pgsql.class.php' => ['PhanParamSignatureMismatch'], - 'htdocs/core/db/sqlite3.class.php' => ['PhanParamSignatureMismatch', 'PhanTypeMismatchReturnNullable'], + 'htdocs/core/db/sqlite3.class.php' => ['PhanParamSignatureMismatch'], 'htdocs/core/get_info.php' => ['PhanPluginSuspiciousParamPosition'], 'htdocs/core/lib/files.lib.php' => ['PhanPluginDuplicateExpressionBinaryOp'], - 'htdocs/core/lib/functions.lib.php' => ['PhanParamTooMany', 'PhanRedefineFunctionInternal'], 'htdocs/core/lib/price.lib.php' => ['PhanPluginSuspiciousParamPosition'], 'htdocs/core/modules/movement/doc/pdf_standard.modules.php' => ['PhanPluginDuplicateExpressionBinaryOp'], - 'htdocs/core/modules/mrp/doc/pdf_vinci.modules.php' => ['PhanTypeArraySuspiciousNull', 'PhanTypeInvalidRightOperandOfAdd'], - 'htdocs/core/modules/syslog/mod_syslog_file.php' => ['PhanParamSignatureMismatch'], - 'htdocs/core/modules/syslog/mod_syslog_syslog.php' => ['PhanParamSignatureMismatch'], 'htdocs/don/class/don.class.php' => ['PhanParamTooMany'], - 'htdocs/expedition/class/api_shipments.class.php' => ['PhanTypeMismatchReturn'], 'htdocs/expensereport/class/api_expensereports.class.php' => ['PhanTypeMismatchReturn'], 'htdocs/fourn/class/fournisseur.commande.class.php' => ['PhanTypeMismatchReturn'], 'htdocs/fourn/class/fournisseur.facture.class.php' => ['PhanTypeMismatchReturn'], diff --git a/dev/tools/phan/config.php b/dev/tools/phan/config.php index 38dcbb2bff1..92760bd48d5 100644 --- a/dev/tools/phan/config.php +++ b/dev/tools/phan/config.php @@ -350,7 +350,13 @@ return [ // Note: trick to have different key for same regex: '/^isModEnable[d]$/' => [0, $deprecatedModuleNameRegex, "DeprecatedModuleName"], '/^sanitizeVal$/' => [1, $sanitizeRegex,"UnknownSanitizeType"], + '/^checkVal$/' => [1, $sanitizeRegex,"UnknownCheckValSanitizeType"], '/^\\\\ExtraFields::addExtraField$/' => [2, $extraFieldTypeRegex,"UnknownExtrafieldTypeBack"], + '/^dol_now$/' => [0, '{^(?:auto|gmt|tz(?:server|ref|user(?:rel)?))$}',"InvalidDolNowArgument"], // '', 0, 1 match bool and int values + '/^dol_mktime$/' => [6, '{^(?:|0|1|auto|gmt|tz(?:server|ref|user(?:rel)?|,[+a-zA-Z-/]+))$}',"InvalidDolMktimeArgument"], // '', 0, 1 match bool and int values + '/^dol_print_date$/' => [2, '{^(?:|0|1|auto|gmt|tz(?:server|user(?:rel)?))$}',"InvalidDolMktimeArgument"], + '/^GETPOSTFLOAT$/' => [1, '{^(?:|M[UTS]|C[UT]|\d+)$}',"InvalidGetPostFloatRounding"], + '/^price2num$/' => [1, '{^(?:|M[UTS]|C[UT]|\d+)$}',"InvalidPrice2NumRounding"], ], 'plugins' => [ __DIR__.'/plugins/NoVarDumpPlugin.php', diff --git a/dev/tools/phan/config_extended.php b/dev/tools/phan/config_extended.php index 535f52f70b2..991ba4d3668 100644 --- a/dev/tools/phan/config_extended.php +++ b/dev/tools/phan/config_extended.php @@ -1,324 +1,12 @@ */ -define('DOL_PROJECT_ROOT', __DIR__.'/../../..'); -define('DOL_DOCUMENT_ROOT', DOL_PROJECT_ROOT.'/htdocs'); -define('PHAN_DIR', __DIR__); -$sanitizeRegex - = '/^(array:)?(?:'.implode( - '|', - array( - // Documented: - 'none', - 'array', - 'int', - 'intcomma', - 'alpha', - 'alphawithlgt', - 'alphanohtml', - 'MS', - 'aZ', - 'aZ09', - 'aZ09arobase', - 'aZ09comma', - 'san_alpha', - 'restricthtml', - 'nohtml', - 'custom', - // Not documented: - 'email', - 'restricthtmlallowclass', - 'restricthtmlallowunvalid', - 'restricthtmlnolink', - //'ascii', - //'categ_id', - //'chaine', - //'html', - //'boolean', - //'double', - //'float', - //'string', - ) - ).')*$/'; +// Load default configuration (with many exclusions) +// +$config = include __DIR__.DIRECTORY_SEPARATOR."config.php"; -/** - * Map deprecated module names to new module names - */ -$DEPRECATED_MODULE_MAPPING = array( - 'actioncomm' => 'agenda', - 'adherent' => 'member', - 'adherent_type' => 'member_type', - 'banque' => 'bank', - 'categorie' => 'category', - 'commande' => 'order', - 'contrat' => 'contract', - 'entrepot' => 'stock', - 'expedition' => 'shipping', - 'facture' => 'invoice', - 'ficheinter' => 'intervention', - 'product_fournisseur_price' => 'productsupplierprice', - 'product_price' => 'productprice', - 'projet' => 'project', - 'propale' => 'propal', - 'socpeople' => 'contact', -); - -/** - * Map module names to the 'class' name (the class is: mod) - * Value is null when the module is not internal to the default - * Dolibarr setup. - */ -$VALID_MODULE_MAPPING = array( - 'accounting' => 'Accounting', - 'agenda' => 'Agenda', - 'ai' => 'Ai', - 'anothermodule' => null, - 'api' => 'Api', - 'asset' => 'Asset', - 'bank' => 'Banque', - 'barcode' => 'Barcode', - 'blockedlog' => 'BlockedLog', - 'bom' => 'Bom', - 'bookcal' => 'BookCal', - 'bookmark' => 'Bookmark', - 'cashdesk' => null, // TODO: fill in proper class - 'category' => 'Categorie', - 'clicktodial' => 'ClickToDial', - 'collab' => 'Collab', - 'comptabilite' => 'Comptabilite', - 'contact' => null, // TODO: fill in proper class - 'contract' => 'Contrat', - 'cron' => 'Cron', - 'datapolicy' => 'DataPolicy', - 'dav' => 'Dav', - 'debugbar' => 'DebugBar', - 'shipping' => 'Expedition', - 'deplacement' => 'Deplacement', - "documentgeneration" => 'DocumentGeneration', - 'don' => 'Don', - 'dynamicprices' => 'DynamicPrices', - 'ecm' => 'ECM', - 'ecotax' => null, // TODO: External module ? - 'emailcollector' => 'EmailCollector', - 'eventorganization' => 'EventOrganization', - 'expensereport' => 'ExpenseReport', - 'export' => 'Export', - 'externalrss' => 'ExternalRss', - 'externalsite' => 'ExternalSite', - 'fckeditor' => 'Fckeditor', - 'fournisseur' => 'Fournisseur', - 'ftp' => 'FTP', - 'geoipmaxmind' => 'GeoIPMaxmind', - 'google' => null, // External ? - 'gravatar' => 'Gravatar', - 'holiday' => 'Holiday', - 'hrm' => 'HRM', - 'import' => 'Import', - 'incoterm' => 'Incoterm', - 'intervention' => 'Ficheinter', - 'intracommreport' => 'Intracommreport', - 'invoice' => 'Facture', - 'knowledgemanagement' => 'KnowledgeManagement', - 'label' => 'Label', - 'ldap' => 'Ldap', - 'loan' => 'Loan', - 'mailing' => 'Mailing', - 'mailman' => null, // Same module as mailmanspip -> MailmanSpip ?? - 'mailmanspip' => 'MailmanSpip', - 'margin' => 'Margin', - 'member' => 'Adherent', - 'memcached' => null, // TODO: External module? - 'modulebuilder' => 'ModuleBuilder', - 'mrp' => 'Mrp', - 'multicompany' => null, // Not provided by default, no module tests - 'multicurrency' => 'MultiCurrency', - 'mymodule' => null, // modMyModule - Name used in module builder (avoid false positives) - 'notification' => 'Notification', - 'numberwords' => null, // Not provided by default, no module tests - 'oauth' => 'Oauth', - 'openstreetmap' => null, // External module? - 'opensurvey' => 'OpenSurvey', - 'order' => 'Commande', - 'partnership' => 'Partnership', - 'paybox' => 'Paybox', - 'paymentbybanktransfer' => 'PaymentByBankTransfer', - 'paypal' => 'Paypal', - 'paypalplus' => null, - 'prelevement' => 'Prelevement', - 'printing' => 'Printing', - 'product' => 'Product', - 'productbatch' => 'ProductBatch', - 'productprice' => null, - 'productsupplierprice' => null, - 'project' => 'Projet', - 'propal' => 'Propale', - 'receiptprinter' => 'ReceiptPrinter', - 'reception' => 'Reception', - 'recruitment' => 'Recruitment', - 'resource' => 'Resource', - 'salaries' => 'Salaries', - 'service' => 'Service', - 'socialnetworks' => 'SocialNetworks', - 'societe' => 'Societe', - 'stock' => 'Stock', - 'stocktransfer' => 'StockTransfer', - 'stripe' => 'Stripe', - 'supplier_invoice' => null, // Special case, uses invoice - 'supplier_order' => null, // Special case, uses invoice - 'supplier_proposal' => 'SupplierProposal', - 'syslog' => 'Syslog', - 'takepos' => 'TakePos', - 'tax' => 'Tax', - 'theme_datacolor' => 'array{0:array{0:int,1:int,2:int},1:array{0:int,1:int,2:int},2:array{0:int,1:int,2:int},3:array{0:int,1:int,2:int}}', - 'ticket' => 'Ticket', - 'user' => 'User', - 'variants' => 'Variants', - 'webhook' => 'Webhook', - 'webportal' => 'WebPortal', - 'webservices' => 'WebServices', - 'webservicesclient' => 'WebServicesClient', - 'website' => 'Website', - 'workflow' => 'Workflow', - 'workstation' => 'Workstation', - 'zapier' => 'Zapier', -); - -$moduleNameRegex = '/^(?:'.implode('|', array_merge(array_keys($DEPRECATED_MODULE_MAPPING), array_keys($VALID_MODULE_MAPPING))).')$/'; - -$deprecatedModuleNameRegex = '/^(?!(?:'.implode('|', array_keys($DEPRECATED_MODULE_MAPPING)).')$).*/'; - -/** - * This configuration will be read and overlaid on top of the - * default configuration. Command line arguments will be applied - * after this file is read. - */ -return [ - // 'processes' => 6, - 'backward_compatibility_checks' => false, - 'simplify_ast' => true, - 'analyzed_file_extensions' => ['php','inc'], - 'globals_type_map' => [ - 'action' => 'string', - 'actioncode' => 'string', - 'badgeStatus0' => 'string', - 'badgeStatus1' => 'string', - 'badgeStatus11' => 'string', - 'badgeStatus3' => 'string', - 'badgeStatus4' => 'string', - 'badgeStatus6' => 'string', - 'badgeStatus8' => 'string', - 'badgeStatus9' => 'string', - 'classname' => 'string', - 'conf' => '\Conf', - 'conffile' => 'string', - 'conffiletoshow' => 'string', - 'conffiletoshowshort' => 'string', - 'db' => '\DoliDB', - 'disableedit' => 'int<0,1>', - 'disablemove' => 'int<0,1>', - 'disableremove' => 'int<0,1>', - 'dolibarr_main_authentication' => 'string', - 'dolibarr_main_data_root' => 'string', - 'dolibarr_main_data_root' => 'string', - 'dolibarr_main_db_encrypted_pass' => 'string', - 'dolibarr_main_db_host' => 'string', - 'dolibarr_main_db_pass' => 'string', - 'dolibarr_main_demo' => 'string', - 'dolibarr_main_document_root' => 'string', - 'dolibarr_main_url_root' => 'string', - 'errormsg' => 'string', - 'extrafields' => '\ExtraFields', - 'filter' => 'string', - 'filtert' => 'int', - 'forceall' => 'int<0,1>', - 'form' => '\Form', - 'hookmanager' => '\HookManager', - 'inputalsopricewithtax' => 'int<0,1>', - 'langs' => '\Translate', - 'leftmenu' => 'string', - 'mainmenu' => 'string', - 'menumanager' => '\MenuManager', - 'mysoc' => '\Societe', - 'nblines' => '\int', - 'obj' => '\CommonObject', // Deprecated - 'object_rights' => 'int|stdClass', - 'objectoffield' => '\CommonObject', - 'senderissupplier' => 'int<0,2>', - 'user' => '\User', - 'website' => 'string', // See discussion https://github.com/Dolibarr/dolibarr/pull/28891#issuecomment-2002268334 // Disable because Phan infers Website type - 'websitepage' => '\WebSitePage', - 'websitepagefile' => 'string', - // 'object' => '\CommonObject', // Deprecated, not enabled because conflicts with $object assignments - ], - - // Supported values: `'5.6'`, `'7.0'`, `'7.1'`, `'7.2'`, `'7.3'`, `'7.4'`, `null`. - // If this is set to `null`, - // then Phan assumes the PHP version which is closest to the minor version - // of the php executable used to execute Phan. - //"target_php_version" => null, - "target_php_version" => '8.2', - //"target_php_version" => '7.3', - //"target_php_version" => '5.6', - - // A list of directories that should be parsed for class and - // method information. After excluding the directories - // defined in exclude_analysis_directory_list, the remaining - // files will be statically analyzed for errors. - // - // Thus, both first-party and third-party code being used by - // your application should be included in this list. - 'directory_list' => [ - 'htdocs', - PHAN_DIR . '/stubs/', - ], - - // A directory list that defines files that will be excluded - // from static analysis, but whose class and method - // information should be included. - // - // Generally, you'll want to include the directories for - // third-party code (such as "vendor/") in this list. - // - // n.b.: If you'd like to parse but not analyze 3rd - // party code, directories containing that code - // should be added to the `directory_list` as - // to `exclude_analysis_directory_list`. - "exclude_analysis_directory_list" => [ - 'htdocs/includes/', - 'htdocs/install/doctemplates/websites/', - 'htdocs/core/class/lessc.class.php', // External library - PHAN_DIR . '/stubs/', - ], - //'exclude_file_regex' => '@^vendor/.*/(tests?|Tests?)/@', - 'exclude_file_regex' => '@^(' // @phpstan-ignore-line - .'dummy' // @phpstan-ignore-line - .'|htdocs/.*/canvas/.*/tpl/.*.tpl.php' // @phpstan-ignore-line - .'|htdocs/modulebuilder/template/.*' // @phpstan-ignore-line - // Included as stub (old version + incompatible typing hints) - .'|htdocs/includes/restler/.*' // @phpstan-ignore-line - // Included as stub (did not seem properly analysed by phan without it) - .'|htdocs/includes/stripe/.*' // @phpstan-ignore-line - .'|htdocs/conf/conf.php' // @phpstan-ignore-line - .')@', // @phpstan-ignore-line - - // A list of plugin files to execute. - // Plugins which are bundled with Phan can be added here by providing their name - // (e.g. 'AlwaysReturnPlugin') - // - // Documentation about available bundled plugins can be found - // at https://github.com/phan/phan/tree/master/.phan/plugins - // - // Alternately, you can pass in the full path to a PHP file - // with the plugin's implementation (e.g. 'vendor/phan/phan/.phan/plugins/AlwaysReturnPlugin.php') - 'ParamMatchRegexPlugin' => [ - '/^GETPOST$/' => [1, $sanitizeRegex, 'GetPostUnknownSanitizeType'], - '/^isModEnabled$/' => [0, $moduleNameRegex, 'UnknownModuleName'], - // Note: trick to have different key for same regex: - '/^isModEnable[d]$/' => [0, $deprecatedModuleNameRegex, "DeprecatedModuleName"], - '/^sanitizeVal$/' => [1, $sanitizeRegex,"UnknownSanitizeType"], - ], - 'plugins' => [ +$config['plugins'] = [ __DIR__.'/plugins/NoVarDumpPlugin.php', __DIR__.'/plugins/ParamMatchRegexPlugin.php', 'DeprecateAliasPlugin', @@ -367,11 +55,11 @@ return [ 'UseReturnValuePlugin', 'EmptyStatementListPlugin', 'LoopVariableReusePlugin', - ], + ]; - // Add any issue types (such as 'PhanUndeclaredMethod') - // here to inhibit them from being reported - 'suppress_issue_types' => [ +// Add any issue types (such as 'PhanUndeclaredMethod') +// here to inhibit them from being reported +$config['suppress_issue_types'] = [ 'PhanCompatibleNegativeStringOffset', // return false positive 'PhanPluginWhitespaceTab', // Dolibarr used tabs @@ -394,50 +82,6 @@ return [ 'PhanPluginDuplicateConditionalNullCoalescing', // Not essential - 990+ occurrences 'PhanPluginRedundantAssignmentInGlobalScope', // Not essential, a lot of false warning 'PhanPluginDuplicateCatchStatementBody', // Requires PHP7.1 - 50+ occurrences - ], - // You can put relative paths to internal stubs in this config option. - // Phan will continue using its detailed type annotations, - // but load the constants, classes, functions, and classes (and their Reflection types) - // from these stub files (doubling as valid php files). - // Use a different extension from php (and preferably a separate folder) - // to avoid accidentally parsing these as PHP (includes projects depending on this). - // The 'mkstubs' script can be used to generate your own stubs (compatible with php 7.0+ right now) - // Note: The array key must be the same as the extension name reported by `php -m`, - // so that phan can skip loading the stubs if the extension is actually available. - 'autoload_internal_extension_signatures' => [ - // Stubs may be available at https://github.com/JetBrains/phpstorm-stubs/tree/master - - // Xdebug stubs are bundled with Phan 0.10.1+/0.8.9+ for usage, - // because Phan disables xdebug by default. - //'xdebug' => 'vendor/phan/phan/.phan/internal_stubs/xdebug.phan_php', - //'memcached' => PHAN_DIR . '/your_internal_stubs_folder_name/memcached.phan_php', - //'PDO' => PHAN_DIR . '/stubs/PDO.phan_php', - 'brotli' => PHAN_DIR . '/stubs/brotli.phan_php', - 'curl' => PHAN_DIR . '/stubs/curl.phan_php', - 'calendar' => PHAN_DIR . '/stubs/calendar.phan_php', - 'fileinfo' => PHAN_DIR . '/stubs/fileinfo.phan_php', - 'ftp' => PHAN_DIR . '/stubs/ftp.phan_php', - 'gd' => PHAN_DIR . '/stubs/gd.phan_php', - 'geoip' => PHAN_DIR . '/stubs/geoip.phan_php', - 'imap' => PHAN_DIR . '/stubs/imap.phan_php', - 'imagick' => PHAN_DIR . '/stubs/imagick.phan_php', - 'intl' => PHAN_DIR . '/stubs/intl.phan_php', - 'ldap' => PHAN_DIR . '/stubs/ldap.phan_php', - 'mcrypt' => PHAN_DIR . '/stubs/mcrypt.phan_php', - 'memcache' => PHAN_DIR . '/stubs/memcache.phan_php', - 'memcached' => PHAN_DIR . '/stubs/memcached.phan_php', - 'mysqli' => PHAN_DIR . '/stubs/mysqli.phan_php', - 'pdo_cubrid' => PHAN_DIR . '/stubs/pdo_cubrid.phan_php', - 'pdo_mysql' => PHAN_DIR . '/stubs/pdo_mysql.phan_php', - 'pdo_pgsql' => PHAN_DIR . '/stubs/pdo_pgsql.phan_php', - 'pdo_sqlite' => PHAN_DIR . '/stubs/pdo_sqlite.phan_php', - 'pgsql' => PHAN_DIR . '/stubs/pgsql.phan_php', - 'session' => PHAN_DIR . '/stubs/session.phan_php', - 'simplexml' => PHAN_DIR . '/stubs/SimpleXML.phan_php', - 'soap' => PHAN_DIR . '/stubs/soap.phan_php', - 'sockets' => PHAN_DIR . '/stubs/sockets.phan_php', - 'tidy' => PHAN_DIR . '/stubs/tidy.phan_php', - 'zip' => PHAN_DIR . '/stubs/zip.phan_php', - ], - ]; + +return $config; diff --git a/dev/tools/phan/config_fixer.php b/dev/tools/phan/config_fixer.php index 5df01eb7ae6..79a3d589d38 100644 --- a/dev/tools/phan/config_fixer.php +++ b/dev/tools/phan/config_fixer.php @@ -3,101 +3,22 @@ * Copyright (C) 2024 Frédéric France */ -// Uncomment require_once to enable corresponding fixer + +// Load default configuration (with many exclusions) +// +$config = include __DIR__.DIRECTORY_SEPARATOR."config.php"; + //require_once __DIR__.'/plugins/DeprecatedModuleNameFixer.php'; //require_once __DIR__.'/plugins/PriceFormFixer.php'; //require_once __DIR__.'/plugins/UrlEncodeStringifyFixer.php'; require_once __DIR__.'/plugins/SelectDateFixer.php'; -define('DOL_PROJECT_ROOT', __DIR__.'/../../..'); -define('DOL_DOCUMENT_ROOT', DOL_PROJECT_ROOT.'/htdocs'); -define('PHAN_DIR', __DIR__); - -$DEPRECATED_MODULE_MAPPING = array( - 'actioncomm' => 'agenda', - 'adherent' => 'member', - 'adherent_type' => 'member_type', - 'banque' => 'bank', - 'categorie' => 'category', - 'commande' => 'order', - 'contrat' => 'contract', - 'entrepot' => 'stock', - 'expedition' => 'shipping', - 'facture' => 'invoice', - 'ficheinter' => 'intervention', - 'product_fournisseur_price' => 'productsupplierprice', - 'product_price' => 'productprice', - 'projet' => 'project', - 'propale' => 'propal', - 'socpeople' => 'contact', -); - -$deprecatedModuleNameRegex = '/^(?!(?:'.implode('|', array_keys($DEPRECATED_MODULE_MAPPING)).')$).*/'; +//$deprecatedModuleNameRegex = '/^(?!(?:'.implode('|', array_keys($DEPRECATED_MODULE_MAPPING)).')$).*/'; require_once __DIR__.'/plugins/DeprecatedModuleNameFixer.php'; -/** - * This configuration will be read and overlaid on top of the - * default configuration. Command line arguments will be applied - * after this file is read. - */ -return [ - // 'processes' => 6, - 'backward_compatibility_checks' => false, - 'simplify_ast' => true, - 'analyzed_file_extensions' => ['php','inc'], - 'globals_type_map' => [ - 'conf' => '\Conf', - 'db' => '\DoliDB', - 'extrafields' => '\ExtraFields', - 'hookmanager' => '\HookManager', - 'langs' => '\Translate', - 'mysoc' => '\Societe', - 'nblines' => '\int', - 'user' => '\User', - ], - - // Supported values: `'5.6'`, `'7.0'`, `'7.1'`, `'7.2'`, `'7.3'`, `'7.4'`, `null`. - // If this is set to `null`, - // then Phan assumes the PHP version which is closest to the minor version - // of the php executable used to execute Phan. - //"target_php_version" => null, - "target_php_version" => '8.2', - //"target_php_version" => '7.3', - //"target_php_version" => '5.6', - - // A list of directories that should be parsed for class and - // method information. After excluding the directories - // defined in exclude_analysis_directory_list, the remaining - // files will be statically analyzed for errors. - // - // Thus, both first-party and third-party code being used by - // your application should be included in this list. - 'directory_list' => [ - 'htdocs', - PHAN_DIR . '/stubs/', - ], - - // A directory list that defines files that will be excluded - // from static analysis, but whose class and method - // information should be included. - // - // Generally, you'll want to include the directories for - // third-party code (such as "vendor/") in this list. - // - // n.b.: If you'd like to parse but not analyze 3rd - // party code, directories containing that code - // should be added to the `directory_list` as - // to `exclude_analysis_directory_list`. - "exclude_analysis_directory_list" => [ - 'htdocs/includes/', - 'htdocs/install/doctemplates/websites/', - 'htdocs/core/class/lessc.class.php', // External library - PHAN_DIR . '/stubs/', - ], - //'exclude_file_regex' => '@^vendor/.*/(tests?|Tests?)/@', - 'exclude_file_regex' => '@^(' // @phpstan-ignore-line +$config['exclude_file_regex'] = '@^(' // @phpstan-ignore-line .'dummy' // @phpstan-ignore-line .'|htdocs/.*/canvas/.*/tpl/.*.tpl.php' // @phpstan-ignore-line .'|htdocs/modulebuilder/template/.*' // @phpstan-ignore-line @@ -108,144 +29,12 @@ return [ .'|htdocs/conf/conf.php' // @phpstan-ignore-line //.'|htdocs/[^c][^o][^r][^e][^/].*' // For testing @phpstan-ignore-line //.'|htdocs/[^h].*' // For testing on restricted set @phpstan-ignore-line - .')@', // @phpstan-ignore-line + .')@'; // @phpstan-ignore-line - // A list of plugin files to execute. - // Plugins which are bundled with Phan can be added here by providing their name - // (e.g. 'AlwaysReturnPlugin') - // - // Documentation about available bundled plugins can be found - // at https://github.com/phan/phan/tree/master/.phan/plugins - // - // Alternately, you can pass in the full path to a PHP file - // with the plugin's implementation (e.g. 'vendor/phan/phan/.phan/plugins/AlwaysReturnPlugin.php') - 'ParamMatchRegexPlugin' => [ - '/^isModEnabled$/' => [0, $deprecatedModuleNameRegex, "DeprecatedModuleName"], - ], - 'plugins' => [ - __DIR__.'/plugins/ParamMatchRegexPlugin.php', - 'DeprecateAliasPlugin', - // __DIR__.'/plugins/NoVarDumpPlugin.php', - //__DIR__.'/plugins/GetPostFixerPlugin.php', - //'PHPDocToRealTypesPlugin', +// $config['plugins'][] = __DIR__.'/plugins/ParamMatchRegexPlugin.php'; +$config['plugins'][] = 'DeprecateAliasPlugin'; +$config['plugins'][] = 'DeprecateAliasPlugin'; +// $config['plugins'][] = __DIR__.'/plugins/GetPostFixerPlugin.php'; +// $config['plugins'][] = 'PHPDocToRealTypesPlugin'; - /* - //'EmptyMethodAndFunctionPlugin', - 'InvalidVariableIssetPlugin', - //'MoreSpecificElementTypePlugin', - 'NoAssertPlugin', - 'NotFullyQualifiedUsagePlugin', - 'PHPDocRedundantPlugin', - 'PHPUnitNotDeadCodePlugin', - //'PossiblyStaticMethodPlugin', - 'PreferNamespaceUsePlugin', - 'PrintfCheckerPlugin', - 'RedundantAssignmentPlugin', - - 'ConstantVariablePlugin', // Warns about values that are actually constant - //'HasPHPDocPlugin', // Requires PHPDoc - 'InlineHTMLPlugin', // html in PHP file, or at end of file - 'NonBoolBranchPlugin', // Requires test on bool, nont on ints - 'NonBoolInLogicalArithPlugin', - 'NumericalComparisonPlugin', - 'PHPDocToRealTypesPlugin', - 'PHPDocInWrongCommentPlugin', // Missing /** (/* was used) - //'ShortArrayPlugin', // Checks that [] is used - //'StrictLiteralComparisonPlugin', - 'UnknownClassElementAccessPlugin', - 'UnknownElementTypePlugin', - 'WhitespacePlugin', - //'RemoveDebugStatementPlugin', // Reports echo, print, ... - //'StrictComparisonPlugin', // Expects === - 'SuspiciousParamOrderPlugin', - 'UnsafeCodePlugin', - //'UnusedSuppressionPlugin', - - 'AlwaysReturnPlugin', - //'DollarDollarPlugin', - 'DuplicateArrayKeyPlugin', - 'DuplicateExpressionPlugin', - 'PregRegexCheckerPlugin', - 'PrintfCheckerPlugin', - 'SleepCheckerPlugin', - // Checks for syntactically unreachable statements in - // the global scope or function bodies. - 'UnreachableCodePlugin', - 'UseReturnValuePlugin', - 'EmptyStatementListPlugin', - 'LoopVariableReusePlugin', - */ - ], - - // Add any issue types (such as 'PhanUndeclaredMethod') - // here to inhibit them from being reported - 'suppress_issue_types' => [ - 'PhanCompatibleNegativeStringOffset', // return false positive - - 'PhanPluginWhitespaceTab', // Dolibarr used tabs - 'PhanPluginCanUsePHP71Void', // Dolibarr is maintaining 7.0 compatibility - 'PhanPluginShortArray', // Dolibarr uses array() - 'PhanPluginShortArrayList', // Dolibarr uses array() - // The following may require that --quick is not used - // Fixers From PHPDocToRealTypesPlugin: - 'PhanPluginCanUseParamType', // Fixer - Report/Add types in the function definition (function abc(string $var) (adds string) - 'PhanPluginCanUseReturnType', // Fixer - Report/Add return types in the function definition (function abc(string $var) (adds string) - 'PhanPluginCanUseNullableParamType', // Fixer - Report/Add nullable parameter types in the function definition - 'PhanPluginCanUseNullableReturnType', // Fixer - Report/Add nullable return types in the function definition - - 'PhanPluginNonBoolBranch', // Not essential - 31240+ occurrences - 'PhanPluginNumericalComparison', // Not essential - 19870+ occurrences - 'PhanTypeMismatchArgument', // Not essential - 12300+ occurrences - 'PhanPluginNonBoolInLogicalArith', // Not essential - 11040+ occurrences - 'PhanPluginConstantVariableScalar', // Not essential - 5180+ occurrences - 'PhanPluginDuplicateAdjacentStatement', - 'PhanPluginDuplicateConditionalTernaryDuplication', // 2750+ occurrences - 'PhanPluginDuplicateConditionalNullCoalescing', // Not essential - 990+ occurrences - 'PhanPluginRedundantAssignmentInGlobalScope', // Not essential, a lot of false warning - ], - // You can put relative paths to internal stubs in this config option. - // Phan will continue using its detailed type annotations, - // but load the constants, classes, functions, and classes (and their Reflection types) - // from these stub files (doubling as valid php files). - // Use a different extension from php (and preferably a separate folder) - // to avoid accidentally parsing these as PHP (includes projects depending on this). - // The 'mkstubs' script can be used to generate your own stubs (compatible with php 7.0+ right now) - // Note: The array key must be the same as the extension name reported by `php -m`, - // so that phan can skip loading the stubs if the extension is actually available. - 'autoload_internal_extension_signatures' => [ - // Stubs may be available at https://github.com/JetBrains/phpstorm-stubs/tree/master - - // Xdebug stubs are bundled with Phan 0.10.1+/0.8.9+ for usage, - // because Phan disables xdebug by default. - //'xdebug' => 'vendor/phan/phan/.phan/internal_stubs/xdebug.phan_php', - //'memcached' => PHAN_DIR . '/your_internal_stubs_folder_name/memcached.phan_php', - //'PDO' => PHAN_DIR . '/stubs/PDO.phan_php', - 'brotli' => PHAN_DIR . '/stubs/brotli.phan_php', - 'curl' => PHAN_DIR . '/stubs/curl.phan_php', - 'calendar' => PHAN_DIR . '/stubs/calendar.phan_php', - 'fileinfo' => PHAN_DIR . '/stubs/fileinfo.phan_php', - 'ftp' => PHAN_DIR . '/stubs/ftp.phan_php', - 'gd' => PHAN_DIR . '/stubs/gd.phan_php', - 'geoip' => PHAN_DIR . '/stubs/geoip.phan_php', - 'imap' => PHAN_DIR . '/stubs/imap.phan_php', - 'imagick' => PHAN_DIR . '/stubs/imagick.phan_php', - 'intl' => PHAN_DIR . '/stubs/intl.phan_php', - 'ldap' => PHAN_DIR . '/stubs/ldap.phan_php', - 'mcrypt' => PHAN_DIR . '/stubs/mcrypt.phan_php', - 'memcache' => PHAN_DIR . '/stubs/memcache.phan_php', - 'memcached' => PHAN_DIR . '/stubs/memcached.phan_php', - 'mysqli' => PHAN_DIR . '/stubs/mysqli.phan_php', - 'pdo_cubrid' => PHAN_DIR . '/stubs/pdo_cubrid.phan_php', - 'pdo_mysql' => PHAN_DIR . '/stubs/pdo_mysql.phan_php', - 'pdo_pgsql' => PHAN_DIR . '/stubs/pdo_pgsql.phan_php', - 'pdo_sqlite' => PHAN_DIR . '/stubs/pdo_sqlite.phan_php', - 'pgsql' => PHAN_DIR . '/stubs/pgsql.phan_php', - 'session' => PHAN_DIR . '/stubs/session.phan_php', - 'simplexml' => PHAN_DIR . '/stubs/SimpleXML.phan_php', - 'soap' => PHAN_DIR . '/stubs/soap.phan_php', - 'tidy' => PHAN_DIR . '/stubs/tidy.phan_php', - 'sockets' => PHAN_DIR . '/stubs/sockets.phan_php', - 'zip' => PHAN_DIR . '/stubs/zip.phan_php', - ], - - ]; +return $config; diff --git a/dev/tools/phan/stubs/multicompany.php b/dev/tools/phan/stubs/multicompany.php index db62b11c722..0f2ba3b4e74 100644 --- a/dev/tools/phan/stubs/multicompany.php +++ b/dev/tools/phan/stubs/multicompany.php @@ -1,5 +1,7 @@ + * + * Note: in this context Entity == Company. */ class ActionsMulticompany { @@ -9,12 +11,83 @@ class ActionsMulticompany public function __construct($db) { } - /** @ver string */ + /** @var string */ public $id; - /** @ver string */ + /** @var string */ public $label; /** @var array{stock:string[],referent:string} */ public $sharings; - /** @ver DoliDB */ + /** @var DoliDB */ public $db; + + /** + * @param string $login + * @param bool $bool1 + * @param bool $bool2 + * @return array + */ + public function getEntitiesList($login = '', $bool1 = false, $bool2 = false) + { + } + + /** + * @param string $entity + * @return void + */ + public function getInfo($entity) + { + } + + /** + * @param int $id + * @param string $key + * @param string $param_str + * @param bool $bool1 + * @param bool $bool2 + * @param bool $bool3 + * @param bool $bool4 + * @param bool $bool5 + * @return string */ + public function select_entities($id, $key = '', $param_str = '', $bool1 = false, $bool2 = false, $bool3 = false, $bool4 = false, $bool5 = false) + { + } + + /** + * @param Conf $conf + * @return void + */ + public function setValues($conf) + { + } + /** + * @param string $element + * @param int<0,1> $shared + * @param ?CommonObject $currentobject + * @return string + */ + public function getEntity($element, $shared = 1, $currentobject = 0) + { + } + /** + * @param CommonObject $currentobject + * @return int + */ + public function setEntity($currentobject) + { + } + /** + * @param int $entityid + * @return int<-1,0> + */ + public function switchEntity($entityid) + { + } + /** + * @param int $id + * @param string $entitytotest + * @return int + */ + public function checkRight($id, $entitytotest) + { + } } diff --git a/dev/translation/dynamic_translation_keys.lst b/dev/translation/dynamic_translation_keys.lst index cea77bc9ea9..56acbe41810 100644 --- a/dev/translation/dynamic_translation_keys.lst +++ b/dev/translation/dynamic_translation_keys.lst @@ -437,6 +437,7 @@ CardContent CardProduct0 CardProduct1 Cards +Cart CashAccounts CashDeskBankCB CashDeskBankCash @@ -2030,6 +2031,7 @@ Notify_MEMBER_MODIFY Notify_MEMBER_RESILIATE Notify_MEMBER_SUBSCRIPTION Notify_MEMBER_VALIDATE +Notify_ORDER_CANCEL Notify_ORDER_CLOSE Notify_ORDER_SENTBYMAIL Notify_ORDER_SUPPLIER_APPROVE diff --git a/dev/translation/ignore_translation_keys.lst b/dev/translation/ignore_translation_keys.lst index 21b8f270427..1f6bbe80e59 100644 --- a/dev/translation/ignore_translation_keys.lst +++ b/dev/translation/ignore_translation_keys.lst @@ -45,6 +45,7 @@ IPP_Device InstallChoiceRecommanded IsInPackage MailNoChangePossible +MailSentBy ModuleBuilderDesc2 ModulesMarketPlaceDesc MoveField @@ -403,11 +404,6 @@ EventFee EventIntoASerie EventOrganizationArea EventParticipant -ExampleOnlyForATBEDEITNLESCustomers -ExampleOnlyForBECustomers -ExampleOnlyForDECustomers -ExampleOnlyForKlarnaCustomers -ExampleOnlyForNLCustomers Expedition Experimental Expired @@ -518,7 +514,6 @@ MO MRP MYDATA_AADE_KEY MYDATA_AADE_USER -Mailman MainAccountForRevenueStampSaleNotDefined Manual Map @@ -754,18 +749,11 @@ Roles Rowid RulesPurchaseTurnoverCollectedOfExpenseAccounts SID -SOAPError -SPIP SQL SQLSort STATE_ STATE_IPP_ STRIPE_APPLICATION_FEE_PLATFORM -STRIPE_BANCONTACT -STRIPE_GIROPAY -STRIPE_IDEAL -STRIPE_KLARNA -STRIPE_SOFORT ST_ SaveFailed Saved diff --git a/htdocs/accountancy/admin/categories_list.php b/htdocs/accountancy/admin/categories_list.php index 453280b11b2..93397d52eb1 100644 --- a/htdocs/accountancy/admin/categories_list.php +++ b/htdocs/accountancy/admin/categories_list.php @@ -304,13 +304,8 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { setEventMessages($db->error(), null, 'errors'); } } - //$_GET["id"]=GETPOST('id', 'int'); // Force affichage dictionnaire en cours d'edition } -// if (GETPOST('actioncancel', 'alpha')) { -// $_GET["id"]=GETPOST('id', 'int'); // Force affichage dictionnaire en cours d'edition -// } - if ($action == 'confirm_delete' && $confirm == 'yes') { // delete $rowidcol = "rowid"; diff --git a/htdocs/accountancy/admin/export.php b/htdocs/accountancy/admin/export.php index 8a0d6764590..ec87c9bc489 100644 --- a/htdocs/accountancy/admin/export.php +++ b/htdocs/accountancy/admin/export.php @@ -216,20 +216,6 @@ if ($num) { } } -print "\n"; - -print "
      \n"; - -/* - * Export model - */ -print ''; - -print ''; -print ''; -print ''; - - print ''; print ''; if (!$conf->use_javascript_ajax) { @@ -238,12 +224,13 @@ if (!$conf->use_javascript_ajax) { print ""; } else { print ''; } print ""; + print "
      '.$langs->trans("Modelcsv").'
      '.$langs->trans("Selectmodelcsv").''; - $listmodelcsv = $accountancyexport->getType(); - print $form->selectarray("ACCOUNTING_EXPORT_MODELCSV", $listmodelcsv, getDolGlobalString('ACCOUNTING_EXPORT_MODELCSV'), 0, 0, 0, '', 0, 0, 0, '', '', 1); + $listofexporttemplates = $accountancyexport->getType(1); + print $form->selectarray("ACCOUNTING_EXPORT_MODELCSV", $listofexporttemplates, getDolGlobalString('ACCOUNTING_EXPORT_MODELCSV'), 0, 0, 0, '', 0, 0, 0, '', '', 1); print '
      "; print "
      \n"; diff --git a/htdocs/accountancy/admin/journals_list.php b/htdocs/accountancy/admin/journals_list.php index 0ed3ad34d63..deb81a3b60d 100644 --- a/htdocs/accountancy/admin/journals_list.php +++ b/htdocs/accountancy/admin/journals_list.php @@ -275,14 +275,8 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { setEventMessages($db->error(), null, 'errors'); } } - //$_GET["id"]=GETPOST('id', 'int'); // Force affichage dictionnaire en cours d'edition } -//if (GETPOST('actioncancel', 'alpha')) -//{ -// $_GET["id"]=GETPOST('id', 'int'); // Force affichage dictionnaire en cours d'edition -//} - if ($action == 'confirm_delete' && $confirm == 'yes') { // delete if ($tabrowid[$id]) { $rowidcol = $tabrowid[$id]; diff --git a/htdocs/accountancy/bookkeeping/export.php b/htdocs/accountancy/bookkeeping/export.php index 72aee30478d..f28f2ec2b90 100644 --- a/htdocs/accountancy/bookkeeping/export.php +++ b/htdocs/accountancy/bookkeeping/export.php @@ -6,6 +6,7 @@ * Copyright (C) 2016-2017 Laurent Destailleur * Copyright (C) 2018-2021 Frédéric France * Copyright (C) 2022 Progiseize + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -165,7 +166,7 @@ if (!in_array($action, array('export_file', 'delmouv', 'delmouvconfirm')) && !GE $query .= " where date_start < '".$db->idate(dol_now())."' and date_end > '".$db->idate(dol_now())."' limit 1"; $res = $db->query($query); - if ($res->num_rows > 0) { + if ($db->num_rows($res) > 0) { $fiscalYear = $db->fetch_object($res); $search_date_start = strtotime($fiscalYear->date_start); $search_date_end = strtotime($fiscalYear->date_end); @@ -321,17 +322,17 @@ if (empty($reshook)) { if (!empty($search_date_start)) { $filter['t.doc_date>='] = $search_date_start; $tmp = dol_getdate($search_date_start); - $param .= '&search_date_startmonth='.urlencode($tmp['mon']).'&search_date_startday='.urlencode($tmp['mday']).'&search_date_startyear='.urlencode($tmp['year']); + $param .= '&search_date_startmonth='.((int) $tmp['mon']).'&search_date_startday='.((int) $tmp['mday']).'&search_date_startyear='.((int) $tmp['year']); } if (!empty($search_date_end)) { $filter['t.doc_date<='] = $search_date_end; $tmp = dol_getdate($search_date_end); - $param .= '&search_date_endmonth='.urlencode($tmp['mon']).'&search_date_endday='.urlencode($tmp['mday']).'&search_date_endyear='.urlencode($tmp['year']); + $param .= '&search_date_endmonth='.((int) $tmp['mon']).'&search_date_endday='.((int) $tmp['mday']).'&search_date_endyear='.((int) $tmp['year']); } if (!empty($search_doc_date)) { $filter['t.doc_date'] = $search_doc_date; $tmp = dol_getdate($search_doc_date); - $param .= '&doc_datemonth='.urlencode($tmp['mon']).'&doc_dateday='.urlencode($tmp['mday']).'&doc_dateyear='.urlencode($tmp['year']); + $param .= '&doc_datemonth='.((int) $tmp['mon']).'&doc_dateday='.((int) $tmp['mday']).'&doc_dateyear='.((int) $tmp['year']); } if (!empty($search_doc_type)) { $filter['t.doc_type'] = $search_doc_type; @@ -400,42 +401,42 @@ if (empty($reshook)) { if (!empty($search_date_creation_start)) { $filter['t.date_creation>='] = $search_date_creation_start; $tmp = dol_getdate($search_date_creation_start); - $param .= '&search_date_creation_startmonth='.urlencode($tmp['mon']).'&search_date_creation_startday='.urlencode($tmp['mday']).'&search_date_creation_startyear='.urlencode($tmp['year']); + $param .= '&search_date_creation_startmonth='.((int) $tmp['mon']).'&search_date_creation_startday='.((int) $tmp['mday']).'&search_date_creation_startyear='.((int) $tmp['year']); } if (!empty($search_date_creation_end)) { $filter['t.date_creation<='] = $search_date_creation_end; $tmp = dol_getdate($search_date_creation_end); - $param .= '&search_date_creation_endmonth='.urlencode($tmp['mon']).'&search_date_creation_endday='.urlencode($tmp['mday']).'&search_date_creation_endyear='.urlencode($tmp['year']); + $param .= '&search_date_creation_endmonth='.((int) $tmp['mon']).'&search_date_creation_endday='.((int) $tmp['mday']).'&search_date_creation_endyear='.((int) $tmp['year']); } if (!empty($search_date_modification_start)) { $filter['t.tms>='] = $search_date_modification_start; $tmp = dol_getdate($search_date_modification_start); - $param .= '&search_date_modification_startmonth='.urlencode($tmp['mon']).'&search_date_modification_startday='.urlencode($tmp['mday']).'&search_date_modification_startyear='.urlencode($tmp['year']); + $param .= '&search_date_modification_startmonth='.((int) $tmp['mon']).'&search_date_modification_startday='.((int) $tmp['mday']).'&search_date_modification_startyear='.((int) $tmp['year']); } if (!empty($search_date_modification_end)) { $filter['t.tms<='] = $search_date_modification_end; $tmp = dol_getdate($search_date_modification_end); - $param .= '&search_date_modification_endmonth='.urlencode($tmp['mon']).'&search_date_modification_endday='.urlencode($tmp['mday']).'&search_date_modification_endyear='.urlencode($tmp['year']); + $param .= '&search_date_modification_endmonth='.((int) $tmp['mon']).'&search_date_modification_endday='.((int) $tmp['mday']).'&search_date_modification_endyear='.((int) $tmp['year']); } if (!empty($search_date_export_start)) { $filter['t.date_export>='] = $search_date_export_start; $tmp = dol_getdate($search_date_export_start); - $param .= '&search_date_export_startmonth='.urlencode($tmp['mon']).'&search_date_export_startday='.urlencode($tmp['mday']).'&search_date_export_startyear='.urlencode($tmp['year']); + $param .= '&search_date_export_startmonth='.((int) $tmp['mon']).'&search_date_export_startday='.((int) $tmp['mday']).'&search_date_export_startyear='.((int) $tmp['year']); } if (!empty($search_date_export_end)) { $filter['t.date_export<='] = $search_date_export_end; $tmp = dol_getdate($search_date_export_end); - $param .= '&search_date_export_endmonth='.urlencode($tmp['mon']).'&search_date_export_endday='.urlencode($tmp['mday']).'&search_date_export_endyear='.urlencode($tmp['year']); + $param .= '&search_date_export_endmonth='.((int) $tmp['mon']).'&search_date_export_endday='.((int) $tmp['mday']).'&search_date_export_endyear='.((int) $tmp['year']); } if (!empty($search_date_validation_start)) { $filter['t.date_validated>='] = $search_date_validation_start; $tmp = dol_getdate($search_date_validation_start); - $param .= '&search_date_validation_startmonth='.urlencode($tmp['mon']).'&search_date_validation_startday='.urlencode($tmp['mday']).'&search_date_validation_startyear='.urlencode($tmp['year']); + $param .= '&search_date_validation_startmonth='.((int) $tmp['mon']).'&search_date_validation_startday='.((int) $tmp['mday']).'&search_date_validation_startyear='.((int) $tmp['year']); } if (!empty($search_date_validation_end)) { $filter['t.date_validated<='] = $search_date_validation_end; $tmp = dol_getdate($search_date_validation_end); - $param .= '&search_date_validation_endmonth='.urlencode($tmp['mon']).'&search_date_validation_endday='.urlencode($tmp['mday']).'&search_date_validation_endyear='.urlencode($tmp['year']); + $param .= '&search_date_validation_endmonth='.((int) $tmp['mon']).'&search_date_validation_endday='.((int) $tmp['mday']).'&search_date_validation_endyear='.((int) $tmp['year']); } if (!empty($search_debit)) { $filter['t.debit'] = $search_debit; @@ -835,8 +836,11 @@ if ($action == 'export_file') { $form_question['separator3'] = array('name' => 'separator3', 'type' => 'separator'); } - // add documents in an archive for accountancy export (Quadratus) - if (getDolGlobalString('ACCOUNTING_EXPORT_MODELCSV') == AccountancyExport::$EXPORT_TYPE_QUADRATUS) { + // add documents in an archive for some accountancy export format + if (getDolGlobalString('ACCOUNTING_EXPORT_MODELCSV') == AccountancyExport::$EXPORT_TYPE_QUADRATUS + || getDolGlobalString('ACCOUNTING_EXPORT_MODELCSV') == AccountancyExport::$EXPORT_TYPE_FEC + || getDolGlobalString('ACCOUNTING_EXPORT_MODELCSV') == AccountancyExport::$EXPORT_TYPE_FEC2 + ) { $form_question['notifiedexportfull'] = array( 'name' => 'notifiedexportfull', 'type' => 'checkbox', @@ -1263,6 +1267,7 @@ while ($i < min($num, $limit)) { // Document ref if (!empty($arrayfields['t.doc_ref']['checked'])) { $documentlink = ''; + $objectstatic = null; if ($line->doc_type == 'customer_invoice') { $langs->loadLangs(array('bills')); @@ -1273,7 +1278,7 @@ while ($i < min($num, $limit)) { if ($objectstatic->id > 0) { $filename = dol_sanitizeFileName($line->doc_ref); - $filedir = $conf->facture->dir_output.'/'.dol_sanitizeFileName($line->doc_ref); + $filedir = $conf->invoice->dir_output.'/'.dol_sanitizeFileName($line->doc_ref); $urlsource = $_SERVER['PHP_SELF'].'?id='.$objectstatic->id; $documentlink = $formfile->getDocumentsLink($objectstatic->element, $filename, $filedir); } @@ -1315,7 +1320,7 @@ while ($i < min($num, $limit)) { $labeltoshow = ''; $labeltoshowalt = ''; - if ($line->doc_type == 'customer_invoice' || $line->doc_type == 'supplier_invoice' || $line->doc_type == 'expense_report') { + if (($objectstatic instanceof CommonObject) && in_array($line->doc_type, array('customer_invoice', 'supplier_invoice', 'expense_report'))) { if ($objectstatic->id > 0) { $labeltoshow .= $objectstatic->getNomUrl(1, '', 0, 0, '', 0, -1, 1); $labeltoshow .= $documentlink; diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index a9931ab2ccb..cd2d8eec015 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -6,6 +6,7 @@ * Copyright (C) 2016-2017 Laurent Destailleur * Copyright (C) 2018-2021 Frédéric France * Copyright (C) 2022 Progiseize + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -160,7 +161,7 @@ if (!in_array($action, array('delmouv', 'delmouvconfirm')) && !GETPOSTISSET('beg $query .= " where date_start < '".$db->idate(dol_now())."' and date_end > '".$db->idate(dol_now())."' limit 1"; $res = $db->query($query); - if ($res->num_rows > 0) { + if ($db->num_rows($res) > 0) { $fiscalYear = $db->fetch_object($res); $search_date_start = strtotime($fiscalYear->date_start); $search_date_end = strtotime($fiscalYear->date_end); @@ -309,17 +310,17 @@ if (empty($reshook)) { if (!empty($search_date_start)) { $filter['t.doc_date>='] = $search_date_start; $tmp = dol_getdate($search_date_start); - $param .= '&search_date_startmonth='.urlencode($tmp['mon']).'&search_date_startday='.urlencode($tmp['mday']).'&search_date_startyear='.urlencode($tmp['year']); + $param .= '&search_date_startmonth='.((int) $tmp['mon']).'&search_date_startday='.((int) $tmp['mday']).'&search_date_startyear='.((int) $tmp['year']); } if (!empty($search_date_end)) { $filter['t.doc_date<='] = $search_date_end; $tmp = dol_getdate($search_date_end); - $param .= '&search_date_endmonth='.urlencode($tmp['mon']).'&search_date_endday='.urlencode($tmp['mday']).'&search_date_endyear='.urlencode($tmp['year']); + $param .= '&search_date_endmonth='.((int) $tmp['mon']).'&search_date_endday='.((int) $tmp['mday']).'&search_date_endyear='.((int) $tmp['year']); } if (!empty($search_doc_date)) { $filter['t.doc_date'] = $search_doc_date; $tmp = dol_getdate($search_doc_date); - $param .= '&doc_datemonth='.urlencode($tmp['mon']).'&doc_dateday='.urlencode($tmp['mday']).'&doc_dateyear='.urlencode($tmp['year']); + $param .= '&doc_datemonth='.((int) $tmp['mon']).'&doc_dateday='.((int) $tmp['mday']).'&doc_dateyear='.((int) $tmp['year']); } if (!empty($search_doc_type)) { $filter['t.doc_type'] = $search_doc_type; @@ -388,42 +389,42 @@ if (empty($reshook)) { if (!empty($search_date_creation_start)) { $filter['t.date_creation>='] = $search_date_creation_start; $tmp = dol_getdate($search_date_creation_start); - $param .= '&search_date_creation_startmonth='.urlencode($tmp['mon']).'&search_date_creation_startday='.urlencode($tmp['mday']).'&search_date_creation_startyear='.urlencode($tmp['year']); + $param .= '&search_date_creation_startmonth='.((int) $tmp['mon']).'&search_date_creation_startday='.((int) $tmp['mday']).'&search_date_creation_startyear='.((int) $tmp['year']); } if (!empty($search_date_creation_end)) { $filter['t.date_creation<='] = $search_date_creation_end; $tmp = dol_getdate($search_date_creation_end); - $param .= '&search_date_creation_endmonth='.urlencode($tmp['mon']).'&search_date_creation_endday='.urlencode($tmp['mday']).'&search_date_creation_endyear='.urlencode($tmp['year']); + $param .= '&search_date_creation_endmonth='.((int) $tmp['mon']).'&search_date_creation_endday='.((int) $tmp['mday']).'&search_date_creation_endyear='.((int) $tmp['year']); } if (!empty($search_date_modification_start)) { $filter['t.tms>='] = $search_date_modification_start; $tmp = dol_getdate($search_date_modification_start); - $param .= '&search_date_modification_startmonth='.urlencode($tmp['mon']).'&search_date_modification_startday='.urlencode($tmp['mday']).'&search_date_modification_startyear='.urlencode($tmp['year']); + $param .= '&search_date_modification_startmonth='.((int) $tmp['mon']).'&search_date_modification_startday='.((int) $tmp['mday']).'&search_date_modification_startyear='.((int) $tmp['year']); } if (!empty($search_date_modification_end)) { $filter['t.tms<='] = $search_date_modification_end; $tmp = dol_getdate($search_date_modification_end); - $param .= '&search_date_modification_endmonth='.urlencode($tmp['mon']).'&search_date_modification_endday='.urlencode($tmp['mday']).'&search_date_modification_endyear='.urlencode($tmp['year']); + $param .= '&search_date_modification_endmonth='.((int) $tmp['mon']).'&search_date_modification_endday='.((int) $tmp['mday']).'&search_date_modification_endyear='.((int) $tmp['year']); } if (!empty($search_date_export_start)) { $filter['t.date_export>='] = $search_date_export_start; $tmp = dol_getdate($search_date_export_start); - $param .= '&search_date_export_startmonth='.urlencode($tmp['mon']).'&search_date_export_startday='.urlencode($tmp['mday']).'&search_date_export_startyear='.urlencode($tmp['year']); + $param .= '&search_date_export_startmonth='.((int) $tmp['mon']).'&search_date_export_startday='.((int) $tmp['mday']).'&search_date_export_startyear='.((int) $tmp['year']); } if (!empty($search_date_export_end)) { $filter['t.date_export<='] = $search_date_export_end; $tmp = dol_getdate($search_date_export_end); - $param .= '&search_date_export_endmonth='.urlencode($tmp['mon']).'&search_date_export_endday='.urlencode($tmp['mday']).'&search_date_export_endyear='.urlencode($tmp['year']); + $param .= '&search_date_export_endmonth='.((int) $tmp['mon']).'&search_date_export_endday='.((int) $tmp['mday']).'&search_date_export_endyear='.((int) $tmp['year']); } if (!empty($search_date_validation_start)) { $filter['t.date_validated>='] = $search_date_validation_start; $tmp = dol_getdate($search_date_validation_start); - $param .= '&search_date_validation_startmonth='.urlencode($tmp['mon']).'&search_date_validation_startday='.urlencode($tmp['mday']).'&search_date_validation_startyear='.urlencode($tmp['year']); + $param .= '&search_date_validation_startmonth='.((int) $tmp['mon']).'&search_date_validation_startday='.((int) $tmp['mday']).'&search_date_validation_startyear='.((int) $tmp['year']); } if (!empty($search_date_validation_end)) { $filter['t.date_validated<='] = $search_date_validation_end; $tmp = dol_getdate($search_date_validation_end); - $param .= '&search_date_validation_endmonth='.urlencode($tmp['mon']).'&search_date_validation_endday='.urlencode($tmp['mday']).'&search_date_validation_endyear='.urlencode($tmp['year']); + $param .= '&search_date_validation_endmonth='.((int) $tmp['mon']).'&search_date_validation_endday='.((int) $tmp['mday']).'&search_date_validation_endyear='.((int) $tmp['year']); } if (!empty($search_debit)) { $filter['t.debit'] = $search_debit; @@ -468,6 +469,7 @@ if (empty($reshook)) { } $nbok = 0; + $result = 0; if (!$error) { foreach ($toselect as $toselectid) { $result = $object->fetch($toselectid); diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php index 601cb02bd38..40315b46433 100644 --- a/htdocs/accountancy/class/accountancyexport.class.php +++ b/htdocs/accountancy/class/accountancyexport.class.php @@ -5,7 +5,7 @@ * Copyright (C) 2015 Florian Henry * Copyright (C) 2015 Raphaël Doursenaud * Copyright (C) 2016 Pierre-Henry Favre - * Copyright (C) 2016-2023 Alexandre Spangaro + * Copyright (C) 2016-2024 Alexandre Spangaro * Copyright (C) 2022 Lionel Vessiller * Copyright (C) 2013-2017 Olivier Geffroy * Copyright (C) 2017 Elarifr. Ari Elbaz @@ -116,14 +116,14 @@ class AccountancyExport /** * Array with all export type available (key + label) * - * @return array of type + * @param int $mode Mode of list: 0=flat list, 1=rich list + * @return array of type */ - public function getType() + public function getType($mode = 0) { global $langs, $hookmanager; - $listofexporttypes = array( - self::$EXPORT_TYPE_CONFIGURABLE => $langs->trans('Modelcsv_configurable'), + $listofspecialformatexport = array( self::$EXPORT_TYPE_CEGID => $langs->trans('Modelcsv_CEGID'), self::$EXPORT_TYPE_COALA => $langs->trans('Modelcsv_COALA'), self::$EXPORT_TYPE_BOB50 => $langs->trans('Modelcsv_bob50'), @@ -140,17 +140,37 @@ class AccountancyExport self::$EXPORT_TYPE_LDCOMPTA10 => $langs->trans('Modelcsv_LDCompta10'), self::$EXPORT_TYPE_GESTIMUMV3 => $langs->trans('Modelcsv_Gestinumv3'), self::$EXPORT_TYPE_GESTIMUMV5 => $langs->trans('Modelcsv_Gestinumv5'), - self::$EXPORT_TYPE_FEC => $langs->trans('Modelcsv_FEC'), - self::$EXPORT_TYPE_FEC2 => $langs->trans('Modelcsv_FEC2'), self::$EXPORT_TYPE_ISUITEEXPERT => 'Export iSuite Expert', ); + $listofgenericformatexport = array( + self::$EXPORT_TYPE_CONFIGURABLE => $langs->trans('Modelcsv_configurable'), + self::$EXPORT_TYPE_FEC => $langs->trans('Modelcsv_FEC'), + self::$EXPORT_TYPE_FEC2 => $langs->trans('Modelcsv_FEC2'), + ); + + if (empty($mode)) { + $listofexporttypes = $listofgenericformatexport + $listofspecialformatexport; + ksort($listofexporttypes, SORT_NUMERIC); + } else { + ksort($listofspecialformatexport, SORT_NUMERIC); + $listofexporttypes = array(); + $i = 0; + foreach ($listofgenericformatexport as $key => $val) { + $i++; + $listofexporttypes[$key] = array('id' => $key, 'label' => $val, 'position' => $i); + } + $listofexporttypes['separator_'.$i] = array('id' => 0, 'label' => '----------------', 'position' => $i, 'disabled' => 'disabled'); + foreach ($listofspecialformatexport as $key => $val) { + $i++; + $listofexporttypes[$key] = array('id' => $key, 'label' => $val, 'position' => $i); + } + } + // allow modules to define export formats $parameters = array(); $reshook = $hookmanager->executeHooks('getType', $parameters, $listofexporttypes); - ksort($listofexporttypes, SORT_NUMERIC); - return $listofexporttypes; } @@ -395,11 +415,12 @@ class AccountancyExport // directory already created when module is enabled $outputDir .= '/export'; $outputDir .= '/'.dol_sanitizePathName($formatexportset); - if (!dol_is_dir($outputDir)) { - if (dol_mkdir($outputDir) < 0) { - $this->errors[] = $langs->trans('ErrorCanNotCreateDir', $outputDir); - return -1; - } + } + + if (!dol_is_dir($outputDir)) { + if (dol_mkdir($outputDir) < 0) { + $this->errors[] = $langs->trans('ErrorCanNotCreateDir', $outputDir); + return -1; } } diff --git a/htdocs/accountancy/class/accountingjournal.class.php b/htdocs/accountancy/class/accountingjournal.class.php index 14afbbbe7d8..8e88ed464bd 100644 --- a/htdocs/accountancy/class/accountingjournal.class.php +++ b/htdocs/accountancy/class/accountingjournal.class.php @@ -77,11 +77,6 @@ class AccountingJournal extends CommonObject */ public $active; - /** - * @var AccountingJournal[] array of lines - */ - public $lines; - /** * @var array Accounting account cached */ @@ -159,88 +154,6 @@ class AccountingJournal extends CommonObject return -1; } - /** - * Load object in memory from the database - * - * @param string $sortorder Sort Order - * @param string $sortfield Sort field - * @param int $limit limit - * @param int $offset offset limit - * @param string|array $filter filter array - * @param string $filtermode filter mode (AND or OR) - * @return int Return integer <0 if KO, >0 if OK - */ - public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND') - { - $sql = "SELECT rowid, code, label, nature, active"; - $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t'; - $sql .= ' WHERE 1 = 1'; - $sql .= " AND entity IN (".getEntity('accountancy').")"; - - // Manage filter - if (is_array($filter)) { - $sqlwhere = array(); - if (count($filter) > 0) { - foreach ($filter as $key => $value) { - if ($key == 't.code' || $key == 't.label' || $key == 't.nature') { - $sqlwhere[] = $key." = '".$this->db->escape($value)."'"; - } elseif ($key == 't.rowid' || $key == 't.active') { - $sqlwhere[] = $key.'='.((int) $value); - } - } - } - if (count($sqlwhere) > 0) { - $sql .= " AND ".implode(" ".$this->db->sanitize($filtermode)." ", $sqlwhere); - } - - $filter = ''; - } - - // Manage filter - $errormessage = ''; - $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage); - if ($errormessage) { - $this->errors[] = $errormessage; - dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR); - return -1; - } - - if (!empty($sortfield)) { - $sql .= $this->db->order($sortfield, $sortorder); - } - if (!empty($limit)) { - $sql .= $this->db->plimit($limit + 1, $offset); - } - $this->lines = array(); - - dol_syslog(get_class($this)."::fetch", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) { - $num = $this->db->num_rows($resql); - - while ($obj = $this->db->fetch_object($resql)) { - $line = new self($this->db); - - $line->id = $obj->rowid; - $line->code = $obj->code; - $line->label = $obj->label; - $line->nature = $obj->nature; - $line->active = $obj->active; - - $this->lines[] = $line; - } - - $this->db->free($resql); - - return $num; - } else { - $this->errors[] = 'Error '.$this->db->lasterror(); - dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR); - - return -1; - } - } - /** * Return clickable name (with picto eventually) * @@ -253,7 +166,7 @@ class AccountingJournal extends CommonObject */ public function getNomUrl($withpicto = 0, $withlabel = 0, $nourl = 0, $moretitle = '', $notooltip = 0) { - global $langs, $conf, $user, $hookmanager; + global $langs, $conf, $hookmanager; if (!empty($conf->dol_no_mouse_hover)) { $notooltip = 1; // Force disable tooltips diff --git a/htdocs/accountancy/customer/lines.php b/htdocs/accountancy/customer/lines.php index 54d164532f6..3ee0106e7d6 100644 --- a/htdocs/accountancy/customer/lines.php +++ b/htdocs/accountancy/customer/lines.php @@ -507,8 +507,8 @@ if ($result) { } print ''; - print ''; $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->description, 1)); + print ''; $trunclength = getDolGlobalInt('ACCOUNTING_LENGTH_DESCRIPTION', 32); print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->description); print ''; diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php index d02757a297a..0581675d33f 100644 --- a/htdocs/accountancy/customer/list.php +++ b/htdocs/accountancy/customer/list.php @@ -663,8 +663,8 @@ if ($result) { print ''; // Description of line - print ''; $text = dolGetFirstLineOfText(dol_string_nohtmltag($facture_static_det->desc, 1)); + print ''; $trunclength = getDolGlobalInt('ACCOUNTING_LENGTH_DESCRIPTION', 32); print $form->textwithtooltip(dol_trunc($text, $trunclength), $facture_static_det->desc); print ''; diff --git a/htdocs/accountancy/expensereport/lines.php b/htdocs/accountancy/expensereport/lines.php index c23cb2f5e88..58cc1eb6100 100644 --- a/htdocs/accountancy/expensereport/lines.php +++ b/htdocs/accountancy/expensereport/lines.php @@ -4,6 +4,7 @@ * Copyright (C) 2014-2015 Ari Elbaz (elarifr) * Copyright (C) 2013-2016 Florian Henry * Copyright (C) 2014 Juanjo Menent + * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -383,7 +384,7 @@ if ($result) { $userstatic->id = $objp->userid; $userstatic->ref = $objp->label; $userstatic->login = $objp->login; - $userstatic->statut = $objp->statut; + $userstatic->status = $objp->statut; $userstatic->email = $objp->email; $userstatic->gender = $objp->gender; $userstatic->firstname = $objp->firstname; diff --git a/htdocs/accountancy/expensereport/list.php b/htdocs/accountancy/expensereport/list.php index 78565a1f06a..1257e0e8c93 100644 --- a/htdocs/accountancy/expensereport/list.php +++ b/htdocs/accountancy/expensereport/list.php @@ -5,6 +5,7 @@ * Copyright (C) 2013-2014 Florian Henry * Copyright (C) 2014 Juanjo Menent * Copyright (C) 2016 Laurent Destailleur + * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -462,7 +463,7 @@ if ($result) { $userstatic->id = $objp->userid; $userstatic->login = $objp->login; - $userstatic->statut = $objp->statut; + $userstatic->status = $objp->statut; $userstatic->email = $objp->email; $userstatic->gender = $objp->gender; $userstatic->firstname = $objp->firstname; diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php index d716ad9f3a0..c38582aca6a 100644 --- a/htdocs/accountancy/journal/bankjournal.php +++ b/htdocs/accountancy/journal/bankjournal.php @@ -8,7 +8,7 @@ * Copyright (C) 2013-2023 Alexandre Spangaro * Copyright (C) 2013-2014 Florian Henry * Copyright (C) 2013-2014 Olivier Geffroy - * Copyright (C) 2017-2023 Frédéric France + * Copyright (C) 2017-2024 Frédéric France * Copyright (C) 2018 Ferran Marcet * Copyright (C) 2018 Eric Seigne * Copyright (C) 2021 Gauthier VERDOL @@ -66,7 +66,7 @@ require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php'; // Load translation files required by the page $langs->loadLangs(array("companies", "other", "compta", "banks", "bills", "donations", "loan", "accountancy", "trips", "salaries", "hrm", "members")); -// Multi journal +// Multi journal&search_status=-1 $id_journal = GETPOSTINT('id_journal'); $date_startmonth = GETPOSTINT('date_startmonth'); @@ -393,7 +393,6 @@ if ($result) { $userstatic->email = $tabuser[$obj->rowid]['email']; $userstatic->firstname = $tabuser[$obj->rowid]['firstname']; $userstatic->lastname = $tabuser[$obj->rowid]['lastname']; - $userstatic->statut = $tabuser[$obj->rowid]['status']; $userstatic->status = $tabuser[$obj->rowid]['status']; $userstatic->accountancy_code = $tabuser[$obj->rowid]['accountancy_code']; if ($userstatic->id > 0) { @@ -478,7 +477,7 @@ if ($result) { $userstatic->email = $tmpsalary->user->email; $userstatic->firstname = $tmpsalary->user->firstname; $userstatic->lastname = $tmpsalary->user->lastname; - $userstatic->statut = $tmpsalary->user->status; + $userstatic->status = $tmpsalary->user->status; $userstatic->accountancy_code = $tmpsalary->user->accountancy_code; if ($userstatic->id > 0) { @@ -1139,8 +1138,10 @@ if (empty($action) || $action == 'view') { // Button to write into Ledger if (getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER') == "" || getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER') == '-1' || getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER') == "" || getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER') == '-1' - || getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT') == "" || getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT') == '-1' - || getDolGlobalString('ACCOUNTING_ACCOUNT_EXPENSERERPORT') == "" || getDolGlobalString('ACCOUNTING_ACCOUNT_EXPENSERERPORT') == '-1') { + || (isModEnabled("salaries") && (getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT') == "" || getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT') == '-1')) + || (isModEnabled("expensereport") && (getDolGlobalString('ACCOUNTING_ACCOUNT_EXPENSEREPORT') == "" || getDolGlobalString('ACCOUNTING_ACCOUNT_EXPENSEREPORT') == '-1'))) { + + print($desc ? '' : '
      ').'
      '.img_warning().' '.$langs->trans("SomeMandatoryStepsOfSetupWereNotDone"); $desc = ' : '.$langs->trans("AccountancyAreaDescMisc", 4, '{link}'); $desc = str_replace('{link}', ''.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'', $desc); diff --git a/htdocs/accountancy/supplier/lines.php b/htdocs/accountancy/supplier/lines.php index 938b5c699c9..894c594f2a1 100644 --- a/htdocs/accountancy/supplier/lines.php +++ b/htdocs/accountancy/supplier/lines.php @@ -517,8 +517,8 @@ if ($result) { */ // Supplier invoice label - print ''; - print $objp->invoice_label; + print ''; + print dol_escape_htmltag($objp->invoice_label); print ''; // Date invoice @@ -537,8 +537,8 @@ if ($result) { } print ''; - print ''; $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->description, 1)); + print ''; $trunclength = getDolGlobalInt('ACCOUNTING_LENGTH_DESCRIPTION', 32); print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->description); print ''; diff --git a/htdocs/accountancy/supplier/list.php b/htdocs/accountancy/supplier/list.php index 4366f498749..ed41745fac0 100644 --- a/htdocs/accountancy/supplier/list.php +++ b/htdocs/accountancy/supplier/list.php @@ -690,8 +690,8 @@ if ($result) { print ''; // Description of line - print ''; $text = dolGetFirstLineOfText(dol_string_nohtmltag($facturefourn_static_det->desc, 1)); + print ''; $trunclength = getDolGlobalInt('ACCOUNTING_LENGTH_DESCRIPTION', 32); print $form->textwithtooltip(dol_trunc($text, $trunclength), $facturefourn_static_det->desc); print ''; diff --git a/htdocs/adherents/admin/member.php b/htdocs/adherents/admin/member.php index d93ba0b2138..7d3fec544f1 100644 --- a/htdocs/adherents/admin/member.php +++ b/htdocs/adherents/admin/member.php @@ -10,6 +10,7 @@ * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2020-2021 Frédéric France * Copyright (C) 2023 Waël Almoman + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -286,6 +287,7 @@ foreach ($dirModMember as $dirroot) { } $arrayofmodules = dol_sort_array($arrayofmodules, 'position'); +'@phan-var-force array $arrayofmodules'; foreach ($arrayofmodules as $file => $modCodeMember) { print ''."\n"; diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index 051e398512b..0f153f57e01 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -1001,7 +1001,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { $listetype = $adht->liste_array(1); print img_picto('', $adht->picto, 'class="pictofixedwidth"'); if (count($listetype)) { - print $form->selectarray("typeid", $listetype, (GETPOSTINT('typeid') ? GETPOSTINT('typeid') : $typeid), (count($listetype) > 1 ? 1 : 0), 0, 0, '', 0, 0, 0, '', '', 1); + print $form->selectarray("typeid", $listetype, (GETPOSTINT('typeid') ? GETPOSTINT('typeid') : $typeid), (count($listetype) > 1 ? 1 : 0), 0, 0, '', 0, 0, 0, '', 'minwidth150', 1); } else { print ''.$langs->trans("NoTypeDefinedGoToSetup").''; } @@ -1122,8 +1122,8 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { // Categories if (isModEnabled('category') && $user->hasRight('categorie', 'lire')) { print ''.$form->editfieldkey("Categories", 'memcats', '', $object, 0).''; - $cate_arbo = $form->select_all_categories(Categorie::TYPE_MEMBER, null, 'parent', null, null, 1); - print img_picto('', 'category').$form->multiselectarray('memcats', $cate_arbo, GETPOST('memcats', 'array'), null, null, 'quatrevingtpercent widthcentpercentminusx', 0, 0); + $cate_arbo = $form->select_all_categories(Categorie::TYPE_MEMBER, 0, 'parent', 0, 0, 1); + print img_picto('', 'category').$form->multiselectarray('memcats', $cate_arbo, GETPOST('memcats', 'array'), 0, 0, 'quatrevingtpercent widthcentpercentminusx', 0, 0); print ""; } diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index c43bbffed2d..8da35576186 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -674,6 +674,7 @@ class Adherent extends CommonObject require_once $modfile; $modname = getDolGlobalString('MEMBER_CODEMEMBER_ADDON'); $modCodeMember = new $modname(); + '@phan-var-force ModeleNumRefMembers $modCodeMember'; $this->ref = $modCodeMember->getNextValue($mysoc, $this); } catch (Exception $e) { dol_syslog($e->getMessage(), LOG_ERR); @@ -1836,8 +1837,8 @@ class Adherent extends CommonObject // Possibility to add external linked objects with hooks $invoice->linked_objects['subscription'] = $subscriptionid; - if (!empty($_POST['other_linked_objects']) && is_array($_POST['other_linked_objects'])) { - $invoice->linked_objects = array_merge($invoice->linked_objects, $_POST['other_linked_objects']); + if (GETPOSTISARRAY('other_linked_objects')) { + $invoice->linked_objects = array_merge($invoice->linked_objects, GETPOST('other_linked_objects', 'array:int')); } $result = $invoice->create($user); diff --git a/htdocs/adherents/class/adherentstats.class.php b/htdocs/adherents/class/adherentstats.class.php index 612f408edd9..3417d97eec7 100644 --- a/htdocs/adherents/class/adherentstats.class.php +++ b/htdocs/adherents/class/adherentstats.class.php @@ -170,7 +170,7 @@ class AdherentStats extends Stats * Return count of member by status group by adh type, total and average * * @param int $numberYears Number of years to scan (0 = all) - * @return array Array with total of draft, pending, uptodate, expired, resiliated for each member type + * @return array Array with total of draft, pending, uptodate, expired, resiliated for each member type */ public function countMembersByTypeAndStatus($numberYears = 0) { diff --git a/htdocs/adherents/class/api_members.class.php b/htdocs/adherents/class/api_members.class.php index 941a685d326..a0586546b48 100644 --- a/htdocs/adherents/class/api_members.class.php +++ b/htdocs/adherents/class/api_members.class.php @@ -81,7 +81,7 @@ class Members extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('adherent', $member->id) && $id > 0) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } return $this->_cleanObjectDatas($member); @@ -114,7 +114,7 @@ class Members extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('adherent', $member->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } return $this->_cleanObjectDatas($member); @@ -153,7 +153,7 @@ class Members extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('adherent', $member->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } return $this->_cleanObjectDatas($member); @@ -192,7 +192,7 @@ class Members extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('adherent', $member->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } return $this->_cleanObjectDatas($member); @@ -301,11 +301,11 @@ class Members extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $member->context['caller'] = $request_data['caller']; + $member->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $member->$field = $value; + $member->$field = $this->_checkValForAPI($field, $value, $member); } if ($member->create(DolibarrApiAccess::$user) < 0) { throw new RestException(500, 'Error creating member', array_merge(array($member->error), $member->errors)); @@ -337,7 +337,7 @@ class Members extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('member', $member->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach ($request_data as $field => $value) { @@ -346,10 +346,15 @@ class Members extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $member->context['caller'] = $request_data['caller']; + $member->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); + continue; + } + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $member->array_options[$index] = $val; + } continue; } - // Process the status separately because it must be updated using // the validate(), resiliate() and exclude() methods of the class Adherent. if ($field == 'statut') { @@ -370,7 +375,7 @@ class Members extends DolibarrApi } } } else { - $member->$field = $value; + $member->$field = $this->_checkValForAPI($field, $value, $member); } } @@ -405,7 +410,7 @@ class Members extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('member', $member->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -646,7 +651,7 @@ class Members extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('member', $membertype->id, 'adherent_type')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } return $this->_cleanObjectDatas($membertype); @@ -745,11 +750,11 @@ class Members extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $membertype->context['caller'] = $request_data['caller']; + $membertype->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $membertype->$field = $value; + $membertype->$field = $this->_checkValForAPI($field, $value, $membertype); } if ($membertype->create(DolibarrApiAccess::$user) < 0) { throw new RestException(500, 'Error creating member type', array_merge(array($membertype->error), $membertype->errors)); @@ -783,7 +788,7 @@ class Members extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('member', $membertype->id, 'adherent_type')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach ($request_data as $field => $value) { @@ -792,13 +797,13 @@ class Members extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $membertype->context['caller'] = $request_data['caller']; + $membertype->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } // Process the status separately because it must be updated using // the validate(), resiliate() and exclude() methods of the class AdherentType. - $membertype->$field = $value; + $membertype->$field = $this->_checkValForAPI($field, $value, $membertype); } // If there is no error, update() returns the number of affected rows @@ -834,7 +839,7 @@ class Members extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('member', $membertype->id, 'adherent_type')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $res = $membertype->delete(DolibarrApiAccess::$user); diff --git a/htdocs/adherents/class/api_subscriptions.class.php b/htdocs/adherents/class/api_subscriptions.class.php index a5f27263cbd..56eb2f0f0af 100644 --- a/htdocs/adherents/class/api_subscriptions.class.php +++ b/htdocs/adherents/class/api_subscriptions.class.php @@ -161,11 +161,11 @@ class Subscriptions extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $subscription->context['caller'] = $request_data['caller']; + $subscription->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $subscription->$field = $value; + $subscription->$field = $this->_checkValForAPI($field, $value, $subscription); } if ($subscription->create(DolibarrApiAccess::$user) < 0) { throw new RestException(500, 'Error when creating subscription', array_merge(array($subscription->error), $subscription->errors)); @@ -202,11 +202,11 @@ class Subscriptions extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $subscription->context['caller'] = $request_data['caller']; + $subscription->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $subscription->$field = $value; + $subscription->$field = $this->_checkValForAPI($field, $value, $subscription); } if ($subscription->update(DolibarrApiAccess::$user) > 0) { diff --git a/htdocs/adherents/subscription.php b/htdocs/adherents/subscription.php index 3ace1b42d58..f49d743a372 100644 --- a/htdocs/adherents/subscription.php +++ b/htdocs/adherents/subscription.php @@ -421,11 +421,11 @@ if ($user->hasRight('adherent', 'cotisation', 'creer') && $action == 'subscripti // Clean some POST vars if (!$error) { - $_POST["subscription"] = ''; - $_POST["accountid"] = ''; - $_POST["operation"] = ''; - $_POST["label"] = ''; - $_POST["num_chq"] = ''; + $accountid = ''; + $operation = ''; + $label = ''; + $num_chq = ''; + $option = ''; } } } diff --git a/htdocs/admin/agenda_other.php b/htdocs/admin/agenda_other.php index dcc7cdec446..62a63e4a13e 100644 --- a/htdocs/admin/agenda_other.php +++ b/htdocs/admin/agenda_other.php @@ -137,6 +137,7 @@ if ($action == 'set') { require_once $file; $module = new $classname($db, $commande); + '@phan-var-force pdf_standard_actions $module'; if ($module->write_file($commande, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=action&file=SPECIMEN.pdf"); diff --git a/htdocs/admin/agenda_reminder.php b/htdocs/admin/agenda_reminder.php index cdc6a2b8647..c5d87de3a61 100644 --- a/htdocs/admin/agenda_reminder.php +++ b/htdocs/admin/agenda_reminder.php @@ -100,6 +100,7 @@ if ($action == 'set') { require_once $file; $module = new $classname($db, $commande); + '@phan-var-force pdf_standard_actions $module'; if ($module->write_file($commande, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=action&file=SPECIMEN.pdf"); diff --git a/htdocs/admin/bank.php b/htdocs/admin/bank.php index 865b54f5878..c972fa24468 100644 --- a/htdocs/admin/bank.php +++ b/htdocs/admin/bank.php @@ -145,6 +145,7 @@ if ($action == 'specimen') { require_once $file; $module = new $classname($db); + '@phan-var-force ModeleBankAccountDoc $module'; if ($module->write_file($object, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=bank&file=SPECIMEN.pdf"); diff --git a/htdocs/admin/barcode.php b/htdocs/admin/barcode.php index 49f2dc3380c..b856a2cef3e 100644 --- a/htdocs/admin/barcode.php +++ b/htdocs/admin/barcode.php @@ -3,6 +3,7 @@ * Copyright (C) 2004-2015 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2011-2013 Juanjo Menent + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -189,7 +190,7 @@ foreach ($dirbarcode as $reldir) { } } } - +'@phan-var-force array $barcodelist'; // Select barcode numbering module @@ -224,6 +225,7 @@ if (isModEnabled('product')) { } $modBarCode = new $file(); + '@phan-var-force ModeleNumRefBarCode $modBarCode'; print ''; print ''.(isset($modBarCode->name) ? $modBarCode->name : $modBarCode->nom)."\n"; diff --git a/htdocs/admin/bom.php b/htdocs/admin/bom.php index ebfa4e6772a..2e7945930fd 100644 --- a/htdocs/admin/bom.php +++ b/htdocs/admin/bom.php @@ -90,6 +90,7 @@ if ($action == 'updateMask') { require_once $file; $module = new $classname($db); + '@phan-var-force ModelePDFBom $module'; if ($module->write_file($bom, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=bom&file=SPECIMEN.pdf"); diff --git a/htdocs/admin/chequereceipts.php b/htdocs/admin/chequereceipts.php index ec4bb7cf47d..15f1f8a10e9 100644 --- a/htdocs/admin/chequereceipts.php +++ b/htdocs/admin/chequereceipts.php @@ -3,6 +3,7 @@ * Copyright (C) 2010-2016 Juanjo Menent * Copyright (C) 2013-2018 Philippe Grand * Copyright (C) 2015 Jean-François Ferry + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -151,6 +152,7 @@ foreach ($dirmodels as $reldir) { require_once $dir.$filebis; $module = new $classname($db); + '@phan-var-force ModeleNumRefChequeReceipts $module'; // Show modules according to features level if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) { diff --git a/htdocs/admin/commande.php b/htdocs/admin/commande.php index af9db12a62b..0376d551144 100644 --- a/htdocs/admin/commande.php +++ b/htdocs/admin/commande.php @@ -100,6 +100,7 @@ if ($action == 'updateMask') { require_once $file; $module = new $classname($db); + '@phan-var-force ModelePDFCommandes $module'; if ($module->write_file($commande, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=commande&file=SPECIMEN.pdf"); diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php index 1a5a68fc085..5472212d30c 100644 --- a/htdocs/admin/company.php +++ b/htdocs/admin/company.php @@ -281,8 +281,8 @@ if (($action == 'update' && !GETPOST("cancel", 'alpha')) } if ($action == 'addthumb' || $action == 'addthumbsquarred') { // Regenerate thumbs - if (file_exists($conf->mycompany->dir_output.'/logos/'.$_GET["file"])) { - $isimage = image_format_supported($_GET["file"]); + if (file_exists($conf->mycompany->dir_output.'/logos/'.GETPOST("file"))) { + $isimage = image_format_supported(GETPOST("file")); // Create thumbs of logo if ($isimage > 0) { @@ -297,7 +297,7 @@ if ($action == 'addthumb' || $action == 'addthumbsquarred') { // Regenerate thu //$object->addThumbs($newfile); // We can't use addThumbs here yet because we need name of generated thumbs to add them into constants. TODO Check if need such constants. We should be able to retrieve value with get... // Create small thumb. Used on logon for example - $imgThumbSmall = vignette($conf->mycompany->dir_output.'/logos/'.$_GET["file"], $maxwidthsmall, $maxheightsmall, '_small', $quality); + $imgThumbSmall = vignette($conf->mycompany->dir_output.'/logos/'.GETPOST("file"), $maxwidthsmall, $maxheightsmall, '_small', $quality); if (image_format_supported($imgThumbSmall) >= 0 && preg_match('/([^\\/:]+)$/i', $imgThumbSmall, $reg)) { $imgThumbSmall = $reg[1]; // Save only basename dolibarr_set_const($db, $constant."_SMALL", $imgThumbSmall, 'chaine', 0, '', $conf->entity); @@ -306,7 +306,7 @@ if ($action == 'addthumb' || $action == 'addthumbsquarred') { // Regenerate thu } // Create mini thumbs. Used on menu or for setup page for example - $imgThumbMini = vignette($conf->mycompany->dir_output.'/logos/'.$_GET["file"], $maxwidthmini, $maxheightmini, '_mini', $quality); + $imgThumbMini = vignette($conf->mycompany->dir_output.'/logos/'.GETPOST("file"), $maxwidthmini, $maxheightmini, '_mini', $quality); if (image_format_supported($imgThumbSmall) >= 0 && preg_match('/([^\\/:]+)$/i', $imgThumbMini, $reg)) { $imgThumbMini = $reg[1]; // Save only basename dolibarr_set_const($db, $constant."_MINI", $imgThumbMini, 'chaine', 0, '', $conf->entity); @@ -642,7 +642,7 @@ print ''; if ($mysoc->country_code) { - print $formcompany->select_juridicalstatus($conf->global->MAIN_INFO_SOCIETE_FORME_JURIDIQUE, $mysoc->country_code, '', 'forme_juridique_code'); + print $formcompany->select_juridicalstatus(getDolGlobalString('MAIN_INFO_SOCIETE_FORME_JURIDIQUE'), $mysoc->country_code, '', 'forme_juridique_code'); } else { print $countrynotdefined; } @@ -760,12 +760,12 @@ if ($langs->transcountry("ProfId10", $mysoc->country_code) != '-') { // Intra-community VAT number print ''; -print ''; +print ''; print ''; // Object of the company print ''; -print ''; +print ''; print ''; print ''; @@ -882,7 +882,7 @@ if ($mysoc->useLocalTax(2)) { $tooltiphelp = ($tooltiphelp != "LocalTax2IsUsedExample" ? "".$langs->trans("Example").': '.$langs->transcountry("LocalTax2IsUsedExample", $mysoc->country_code)."\n" : ""); if (!isOnlyOneLocalTax(2)) { print '
      : '; - $formcompany->select_localtax(2, $conf->global->MAIN_INFO_VALUE_LOCALTAX2, "lt2"); + $formcompany->select_localtax(2, getDolGlobalString('MAIN_INFO_VALUE_LOCALTAX2'), "lt2"); } print '
      : '; print $form->selectarray("clt2", $opcions, getDolGlobalString('MAIN_INFO_LOCALTAX_CALC2')); diff --git a/htdocs/admin/contract.php b/htdocs/admin/contract.php index 89e09907a6e..6136ce996f3 100644 --- a/htdocs/admin/contract.php +++ b/htdocs/admin/contract.php @@ -96,6 +96,7 @@ if ($action == 'updateMask') { require_once $file; $module = new $classname($db); + '@phan-var-force ModelePDFContract $module'; if ($module->write_file($contract, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=contract&file=SPECIMEN.pdf"); diff --git a/htdocs/admin/delivery.php b/htdocs/admin/delivery.php index 2c66f284c7d..77396c41685 100644 --- a/htdocs/admin/delivery.php +++ b/htdocs/admin/delivery.php @@ -145,6 +145,7 @@ if ($action == 'specimen') { require_once $file; $module = new $classname($db); + '@phan-var-force ModelePDFDeliveryOrder $module'; if ($module->write_file($sending, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=delivery&file=SPECIMEN.pdf"); diff --git a/htdocs/admin/expedition.php b/htdocs/admin/expedition.php index 082d2a39741..af07348db7e 100644 --- a/htdocs/admin/expedition.php +++ b/htdocs/admin/expedition.php @@ -116,6 +116,7 @@ if ($action == 'updateMask') { require_once $file; $module = new $classname($db); + '@phan-var-force ModelePdfExpedition $module'; if ($module->write_file($exp, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=expedition&file=SPECIMEN.pdf"); diff --git a/htdocs/admin/expensereport.php b/htdocs/admin/expensereport.php index d0fa6cfd98b..088c7dad8ae 100644 --- a/htdocs/admin/expensereport.php +++ b/htdocs/admin/expensereport.php @@ -97,6 +97,7 @@ if ($action == 'updateMask') { require_once $file; $module = new $classname($db); + '@phan-var-force ModeleExpenseReport $module'; if ($module->write_file($expensespecimen, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=expensereport&file=SPECIMEN.pdf"); diff --git a/htdocs/admin/external_rss.php b/htdocs/admin/external_rss.php index 5d3228ae23a..5781b810489 100644 --- a/htdocs/admin/external_rss.php +++ b/htdocs/admin/external_rss.php @@ -7,6 +7,7 @@ * Copyright (C) 2005-2011 Regis Houssin * Copyright (C) 2011 Juanjo Menent * Copyright (C) 2020 Tobias Sekan + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -280,7 +281,7 @@ if ($resql) { print ''; print "".$langs->trans("Status").""; print ""; - if ($result > 0 && empty($rss->error)) { + if ($result > 0 && empty($rssparser->error)) { print ''.$langs->trans("Online").'
      '; } else { print ''.$langs->trans("Offline"); diff --git a/htdocs/admin/fichinter.php b/htdocs/admin/fichinter.php index 250d4d9e2cd..bb5c6d41f5a 100644 --- a/htdocs/admin/fichinter.php +++ b/htdocs/admin/fichinter.php @@ -96,6 +96,7 @@ if ($action == 'updateMask') { require_once $file; $module = new $classname($db); + '@phan-var-force ModelePDFFicheinter $module'; if ($module->write_file($inter, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=ficheinter&file=SPECIMEN.pdf"); diff --git a/htdocs/admin/holiday.php b/htdocs/admin/holiday.php index 1a8a343ea69..21ae01b1f3f 100644 --- a/htdocs/admin/holiday.php +++ b/htdocs/admin/holiday.php @@ -96,6 +96,7 @@ if ($action == 'updateMask') { require_once $file; $module = new $classname($db); + '@phan-var-force CommonDocGenerator $module'; if ($module->write_file($holiday, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=holiday&file=SPECIMEN.pdf"); diff --git a/htdocs/admin/hrm.php b/htdocs/admin/hrm.php index c55622f1a11..74d4bd26748 100644 --- a/htdocs/admin/hrm.php +++ b/htdocs/admin/hrm.php @@ -140,6 +140,7 @@ if ($action == 'update') { require_once $file; $module = new $classname($db); + '@phan-var-force CommonDocGenerator $module'; if ($module->write_file($tmpobject, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=".strtolower($tmpobjectkey)."&file=SPECIMEN.pdf"); diff --git a/htdocs/admin/invoice.php b/htdocs/admin/invoice.php index fa0e810f33b..649ef89f142 100644 --- a/htdocs/admin/invoice.php +++ b/htdocs/admin/invoice.php @@ -113,6 +113,7 @@ if ($action == 'updateMask') { require_once $file; $module = new $classname($db); + '@phan-var-force CommonDocGenerator $module'; if ($module->write_file($facture, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=facture&file=SPECIMEN.pdf"); diff --git a/htdocs/admin/knowledgemanagement.php b/htdocs/admin/knowledgemanagement.php index ef80a03cbcb..72a71d50949 100644 --- a/htdocs/admin/knowledgemanagement.php +++ b/htdocs/admin/knowledgemanagement.php @@ -123,6 +123,7 @@ if ($action == 'updateMask') { require_once $file; $module = new $className($db); + '@phan-var-force CommonDocGenerator $module'; if ($module->write_file($tmpobject, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=".strtolower($tmpobjectkey)."&file=SPECIMEN.pdf"); diff --git a/htdocs/admin/ldap_contacts.php b/htdocs/admin/ldap_contacts.php index f97b35f1968..1aa2eeb55c4 100644 --- a/htdocs/admin/ldap_contacts.php +++ b/htdocs/admin/ldap_contacts.php @@ -293,7 +293,7 @@ show_ldap_test_button($butlabel, $testlabel, $key, $dn, $objectclass); if (function_exists("ldap_connect")) { - if ($_GET["action"] == 'test') { + if ($action == 'test') { // Create object $object = new Contact($db); $object->initAsSpecimen(); diff --git a/htdocs/admin/ldap_members.php b/htdocs/admin/ldap_members.php index fda38fe67b8..2b32bed8391 100644 --- a/htdocs/admin/ldap_members.php +++ b/htdocs/admin/ldap_members.php @@ -444,7 +444,7 @@ if (getDolGlobalString('LDAP_MEMBER_ACTIVE')) { } if (function_exists("ldap_connect")) { - if ($_GET["action"] == 'testmember') { + if ($action == 'testmember') { // Create object $object = new Adherent($db); $object->initAsSpecimen(); diff --git a/htdocs/admin/ldap_members_types.php b/htdocs/admin/ldap_members_types.php index 277cac9a8fc..dc827857f8d 100644 --- a/htdocs/admin/ldap_members_types.php +++ b/htdocs/admin/ldap_members_types.php @@ -200,7 +200,7 @@ if (getDolGlobalInt('LDAP_MEMBER_TYPE_ACTIVE') === Ldap::SYNCHRO_DOLIBARR_TO_LDA } if (function_exists("ldap_connect")) { - if ($_GET["action"] == 'testmembertype') { + if ($action == 'testmembertype') { // Create object $object = new AdherentType($db); $object->initAsSpecimen(); diff --git a/htdocs/admin/mailman.php b/htdocs/admin/mailman.php index 4c014640d00..8d5adcbf6f1 100644 --- a/htdocs/admin/mailman.php +++ b/htdocs/admin/mailman.php @@ -80,7 +80,7 @@ if ($action == 'update' || $action == 'add') { // Action to activate a submodule of the 'adherent' module if ($action == 'set') { - $result = dolibarr_set_const($db, $_GET["name"], $_GET["value"], '', 0, '', $conf->entity); + $result = dolibarr_set_const($db, GETPOST("name", 'aZ09'), GETPOST("value"), '', 0, '', $conf->entity); if ($result < 0) { dol_print_error($db); } @@ -88,7 +88,7 @@ if ($action == 'set') { // Action to deactivate a submodule of the 'adherent' module if ($action == 'unset') { - $result = dolibarr_del_const($db, $_GET["name"], $conf->entity); + $result = dolibarr_del_const($db, GETPOST("name", 'aZ09'), $conf->entity); if ($result < 0) { dol_print_error($db); } diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index 546427463da..dcec50a89a4 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -1041,7 +1041,7 @@ foreach ($fieldlist as $field => $value) { } $sortfieldtouse = ($sortable ? $fieldlist[$field] : ''); if ($sortfieldtouse == 'type_template') { - $sortfieldtouse .= 'type_template,lang,position,label'; + $sortfieldtouse .= ',lang,position,label'; } print getTitleFieldOfList($valuetoshow, 0, $_SERVER["PHP_SELF"], $sortfieldtouse, ($page ? 'page='.$page.'&' : ''), $param, '', $sortfield, $sortorder, $css.' '); } diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index 435fb37e1f6..24dc394d0f8 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -30,7 +30,7 @@ * \brief Page to activate/disable all modules */ -if (!defined('CSRFCHECK_WITH_TOKEN') && (empty($_GET['action']) || $_GET['action'] != 'reset')) { // We force security except to disable modules so we can do it if problem of a module +if (!defined('CSRFCHECK_WITH_TOKEN') && (empty($_GET['action']) || $_GET['action'] != 'reset')) { // We force security except to disable modules so we can do it if a problem occurs on a module define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET } @@ -361,13 +361,17 @@ llxHeader('', $langs->trans("Setup"), $help_url, '', '', '', $morejs, $morecss, // Search modules dirs $modulesdir = dolGetModulesDirs(); -$arrayofnatures = array('core' => $langs->transnoentitiesnoconv("NativeModules"), 'external' => $langs->transnoentitiesnoconv("External").' - ['.$langs->trans("AllPublishers").']'); +$arrayofnatures = array( + 'core' => array('label' => $langs->transnoentitiesnoconv("NativeModules")), + 'external' => array('label' => $langs->transnoentitiesnoconv("External").' - ['.$langs->trans("AllPublishers").']') +); $arrayofwarnings = array(); // Array of warning each module want to show when activated $arrayofwarningsext = array(); // Array of warning each module want to show when we activate an external module $filename = array(); $modules = array(); $orders = array(); $categ = array(); +$publisherlogoarray = array(); $i = 0; // is a sequencer of modules found $j = 0; // j is module number. Automatically affected if module number not defined. @@ -427,9 +431,16 @@ foreach ($modulesdir as $dir) { $external = ($objMod->isCoreOrExternalModule() == 'external'); if ($external) { if ($publisher) { - $arrayofnatures['external_'.$publisher] = $langs->trans("External").' - '.$publisher; + // Check if there is a logo forpublisher + /* Do not show the company logo in combo. Make combo list dirty. + if (!empty($objMod->editor_squarred_logo)) { + $publisherlogoarray['external_'.$publisher] = img_picto('', $objMod->editor_squarred_logo, 'class="publisherlogoinline"'); + } + $publisherlogo = empty($publisherlogoarray['external_'.$publisher]) ? '' : $publisherlogoarray['external_'.$publisher]; + */ + $arrayofnatures['external_'.$publisher] = array('label' => $langs->trans("External").' - '.$publisher, 'data-html' => $langs->trans("External").' - '.$publisher.''); } else { - $arrayofnatures['external_'] = $langs->trans("External").' - '.$langs->trans("UnknownPublishers"); + $arrayofnatures['external_'] = array('label' => $langs->trans("External").' - ['.$langs->trans("UnknownPublishers").']'); } } ksort($arrayofnatures); @@ -641,7 +652,7 @@ if ($mode == 'common' || $mode == 'commonkanban') { $moreforfilter .= ''; $moreforfilter .= ' '; $moreforfilter .= '
      '; - $moreforfilter .= ''; + $moreforfilter .= ''; if ($search_keyword || ($search_nature && $search_nature != '-1') || ($search_version && $search_version != '-1') || ($search_status && $search_status != '-1')) { $moreforfilter .= ' '; $moreforfilter .= ''; @@ -864,6 +875,7 @@ if ($mode == 'common' || $mode == 'commonkanban') { if (!empty($objMod->disabled)) { $codeenabledisable .= $langs->trans("Disabled"); } elseif (!empty($objMod->always_enabled) || ((isModEnabled('multicompany') && $objMod->core_enabled) && ($user->entity || $conf->entity != 1))) { + // @phan-suppress-next-line PhanUndeclaredMethodCall if (method_exists($objMod, 'alreadyUsed') && $objMod->alreadyUsed()) { $codeenabledisable .= $langs->trans("Used"); } else { @@ -874,6 +886,7 @@ if ($mode == 'common' || $mode == 'commonkanban') { $disableSetup++; } } else { + // @phan-suppress-next-line PhanUndeclaredMethodCall if (!empty($objMod->warnings_unactivation[$mysoc->country_code]) && method_exists($objMod, 'alreadyUsed') && $objMod->alreadyUsed()) { $codeenabledisable .= 'warnings_unactivation[$mysoc->country_code]).'&value='.$modName.'&mode='.$mode.$param.'">'; $codeenabledisable .= img_picto($langs->trans("Activated").($warningstring ? ' '.$warningstring : ''), 'switch_on'); diff --git a/htdocs/admin/mrp.php b/htdocs/admin/mrp.php index f616df182c4..73470ecd219 100644 --- a/htdocs/admin/mrp.php +++ b/htdocs/admin/mrp.php @@ -91,6 +91,7 @@ if ($action == 'updateMask') { require_once $file; $module = new $classname($db); + '@phan-var-force CommonDocGenerator $module'; if ($module->write_file($mo, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=mrp&file=SPECIMEN.pdf"); diff --git a/htdocs/admin/notification.php b/htdocs/admin/notification.php index 43e29dfb535..d7bb4315638 100644 --- a/htdocs/admin/notification.php +++ b/htdocs/admin/notification.php @@ -189,35 +189,25 @@ print '
      '; print ''; print ''; -print '
      '; +print '
      '; print ''; print ''; print ''; print ''; print "\n"; + print ''; print ''; print ''; -print ''; -print ''; -print ''; print ''; @@ -231,6 +221,20 @@ if ($conf->use_javascript_ajax) { print ''; print ''; + +print ''; +print ''; +print ''; + + print ''; print ''; print ''; + + print '
      '.$langs->trans("Parameter").''.$langs->trans("Value").'
      '; print $langs->trans("NotificationEMailFrom").''; print img_picto('', 'email', 'class="pictofixedwidth"'); print ''; -if (getDolGlobalString('NOTIFICATION_EMAIL_FROM') && !isValidEmail($conf->global->NOTIFICATION_EMAIL_FROM)) { +if (getDolGlobalString('NOTIFICATION_EMAIL_FROM') && !isValidEmail(getDolGlobalString('NOTIFICATION_EMAIL_FROM'))) { print ' '.img_warning($langs->trans("ErrorBadEMail")); } print '
      '; -print $langs->trans("NotificationDisableConfirmMessageContact").''; -if ($conf->use_javascript_ajax) { - print ajax_constantonoff('NOTIFICATION_EMAIL_DISABLE_CONFIRM_MESSAGE_CONTACT'); -} else { - $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); - print $form->selectarray("NOTIFICATION_EMAIL_DISABLE_CONFIRM_MESSAGE_CONTACT", $arrval, getDolGlobalString('NOTIFICATION_EMAIL_DISABLE_CONFIRM_MESSAGE_CONTACT')); -} -print '
      '; print $langs->trans("NotificationDisableConfirmMessageUser").'
      '; +print $langs->trans("NotificationDisableConfirmMessageContact").''; +if ($conf->use_javascript_ajax) { + print ajax_constantonoff('NOTIFICATION_EMAIL_DISABLE_CONFIRM_MESSAGE_CONTACT'); +} else { + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $form->selectarray("NOTIFICATION_EMAIL_DISABLE_CONFIRM_MESSAGE_CONTACT", $arrval, getDolGlobalString('NOTIFICATION_EMAIL_DISABLE_CONFIRM_MESSAGE_CONTACT')); +} +print '
      '; print $langs->trans("NotificationDisableConfirmMessageFix").''; @@ -242,6 +246,8 @@ if ($conf->use_javascript_ajax) { } print '
      '; print '
      '; diff --git a/htdocs/admin/payment.php b/htdocs/admin/payment.php index 55dc6212a60..07ed45b2d10 100644 --- a/htdocs/admin/payment.php +++ b/htdocs/admin/payment.php @@ -1,6 +1,7 @@ * Copyright (C) 2020 Maxime DEMAREST + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -154,6 +155,7 @@ foreach ($dirmodels as $reldir) { require_once $dir.$filebis; $module = new $classname($db); + '@phan-var-force ModeleNumRefPayments $module'; // Show modules according to features level if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) { diff --git a/htdocs/admin/perms.php b/htdocs/admin/perms.php index 2c9084fa89c..ff8c77b8628 100644 --- a/htdocs/admin/perms.php +++ b/htdocs/admin/perms.php @@ -204,7 +204,7 @@ if ($result) { // Show break line print ''; - print ''; + print ''; print img_object('', $picto, 'class="pictoobjectwidth paddingright"').' '.$objMod->getName(); print '
      '; print ''; @@ -222,7 +222,7 @@ if ($result) { print ''; // Picto and label of module - print ''; + print ''; //print img_object('', $picto, 'class="pictoobjectwidth"').' '.$objMod->getName(); print ''; diff --git a/htdocs/admin/propal.php b/htdocs/admin/propal.php index 401db58d473..da671b176e4 100644 --- a/htdocs/admin/propal.php +++ b/htdocs/admin/propal.php @@ -96,6 +96,7 @@ if ($action == 'updateMask') { require_once $file; $module = new $classname($db); + '@phan-var-force CommonDocGenerator $module'; if ($module->write_file($propal, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=propal&file=SPECIMEN.pdf"); diff --git a/htdocs/admin/receiptprinter.php b/htdocs/admin/receiptprinter.php index 6b7c5f686ed..7f7fd08ed2e 100644 --- a/htdocs/admin/receiptprinter.php +++ b/htdocs/admin/receiptprinter.php @@ -64,6 +64,7 @@ if (!function_exists('gzdecode')) { * * @param string $data data to deflate * @return string data deflated + * @phan-suppress PhanRedefineFunctionInternal */ function gzdecode($data) { diff --git a/htdocs/admin/reception_setup.php b/htdocs/admin/reception_setup.php index b5f8e336b20..5d8c49b65fb 100644 --- a/htdocs/admin/reception_setup.php +++ b/htdocs/admin/reception_setup.php @@ -119,6 +119,7 @@ if ($action == 'updateMask') { require_once $file; $module = new $classname($db); + '@phan-var-force CommonDocGenerator $module'; if ($module->write_file($exp, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=reception&file=SPECIMEN.pdf"); diff --git a/htdocs/admin/security.php b/htdocs/admin/security.php index dd8278f19bf..e9bf40231d8 100644 --- a/htdocs/admin/security.php +++ b/htdocs/admin/security.php @@ -207,6 +207,7 @@ if (is_resource($handle)) { require_once $dir.'/'.$file; $obj = new $classname($db, $conf, $langs, $user); + '@phan-var-force ModeleGenPassword $obj'; $arrayhandler[$obj->id] = $obj; $i++; } diff --git a/htdocs/admin/security_file.php b/htdocs/admin/security_file.php index 0c191d9ae7b..ba2d0be6054 100644 --- a/htdocs/admin/security_file.php +++ b/htdocs/admin/security_file.php @@ -2,6 +2,7 @@ /* Copyright (C) 2004-2017 Laurent Destailleur * Copyright (C) 2005-2017 Regis Houssin * Copyright (C) 2013 Juanjo Menent + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -86,7 +87,7 @@ if ($action == 'updateform') { if (!preg_match('/^0/', $tmpumask)) { $tmpumask = '0'.$tmpumask; } - if (empty($tmpumask) || $tmpumask === '0') { + if (empty($tmpumask)) { // Also matches '0' $tmpumask = '0664'; } diff --git a/htdocs/admin/spip.php b/htdocs/admin/spip.php index f9009151061..c5d919c6de3 100644 --- a/htdocs/admin/spip.php +++ b/htdocs/admin/spip.php @@ -82,7 +82,7 @@ if ($action == 'update' || $action == 'add') { // Action activation d'un sous module du module adherent if ($action == 'set') { - $result = dolibarr_set_const($db, $_GET["name"], $_GET["value"], '', 0, '', $conf->entity); + $result = dolibarr_set_const($db, GETPOST("name", 'aZ09'), GETPOST("value"), '', 0, '', $conf->entity); if ($result < 0) { dol_print_error($db); } @@ -90,7 +90,7 @@ if ($action == 'set') { // Action deactivation d'un sous module du module adherent if ($action == 'unset') { - $result = dolibarr_del_const($db, $_GET["name"], $conf->entity); + $result = dolibarr_del_const($db, GETPOST("name", 'aZ09'), $conf->entity); if ($result < 0) { dol_print_error($db); } diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php index 5ac9f8d5cf4..b840a027850 100644 --- a/htdocs/admin/stock.php +++ b/htdocs/admin/stock.php @@ -123,6 +123,7 @@ if ($action == 'specimen') { require_once $file; $module = new $classname($db); + '@phan-var-force CommonDocGenerator $module'; if ($module->write_file($object, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=stock&file=SPECIMEN.pdf"); @@ -585,6 +586,7 @@ foreach ($dirmodels as $reldir) { require_once $dir.'/'.$file; $module = new $classname($db); + '@phan-var-force ModelePDFStock $module'; $modulequalified = 1; if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) { diff --git a/htdocs/admin/stocktransfer.php b/htdocs/admin/stocktransfer.php index dee8ebc3b14..b431b110fa4 100644 --- a/htdocs/admin/stocktransfer.php +++ b/htdocs/admin/stocktransfer.php @@ -105,6 +105,7 @@ if ($action == 'updateMask') { require_once $file; $module = new $classname($db); + '@phan-var-force CommonDocGenerator $module'; if ($module->write_file($tmpobject, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=".strtolower($tmpobjectkey)."&file=SPECIMEN.pdf"); diff --git a/htdocs/admin/supplier_invoice.php b/htdocs/admin/supplier_invoice.php index 38db853af92..c92f87c1784 100644 --- a/htdocs/admin/supplier_invoice.php +++ b/htdocs/admin/supplier_invoice.php @@ -116,6 +116,7 @@ if ($action == 'specimen') { // For invoices require_once $file; $module = new $classname($db, $facture); + '@phan-var-force CommonDocGenerator $module'; if ($module->write_file($facture, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=facture_fournisseur&file=SPECIMEN.pdf"); diff --git a/htdocs/admin/supplier_order.php b/htdocs/admin/supplier_order.php index ecfc2a68b93..101f57e7161 100644 --- a/htdocs/admin/supplier_order.php +++ b/htdocs/admin/supplier_order.php @@ -106,6 +106,7 @@ if ($action == 'specimen') { // For orders require_once $file; $module = new $classname($db, $commande); + '@phan-var-force CommonDocGenerator $module'; if ($module->write_file($commande, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=commande_fournisseur&file=SPECIMEN.pdf"); diff --git a/htdocs/admin/supplier_payment.php b/htdocs/admin/supplier_payment.php index e420a914155..42adc8e7364 100644 --- a/htdocs/admin/supplier_payment.php +++ b/htdocs/admin/supplier_payment.php @@ -117,6 +117,7 @@ if ($action == 'updateMask') { require_once $file; $module = new $classname($db); + '@phan-var-force CommonDocGenerator $module'; if ($module->write_file($paiementFourn, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=supplier_payment&file=SPECIMEN.pdf"); diff --git a/htdocs/admin/supplier_proposal.php b/htdocs/admin/supplier_proposal.php index 94197b4bdad..f4563df6118 100644 --- a/htdocs/admin/supplier_proposal.php +++ b/htdocs/admin/supplier_proposal.php @@ -95,6 +95,7 @@ if ($action == 'specimen') { require_once $file; $module = new $classname($db); + '@phan-var-force CommonDocGenerator $module'; if ($module->write_file($supplier_proposal, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=supplier_proposal&file=SPECIMEN.pdf"); @@ -261,6 +262,7 @@ foreach ($dirmodels as $reldir) { require_once $dir.'/'.$file.'.php'; $module = new $file(); + '@phan-var-force ModeleNumRefSupplierProposal $module'; // Show modules according to features level if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) { @@ -393,6 +395,7 @@ foreach ($dirmodels as $reldir) { require_once $dir.'/'.$file; $module = new $classname($db); + '@phan-var-force CommonDocGenerator $module'; $modulequalified = 1; if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) { diff --git a/htdocs/admin/syslog.php b/htdocs/admin/syslog.php index 5475e20d0d1..6503cc05ae6 100644 --- a/htdocs/admin/syslog.php +++ b/htdocs/admin/syslog.php @@ -4,6 +4,7 @@ * Copyright (C) 2007 Rodolphe Quiedeville * Copyright (C) 2013 Juanjo Menent * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -63,6 +64,7 @@ foreach ($dirsyslogs as $reldir) { require_once $newdir.$file.'.php'; $module = new $file(); + '@phan-var-force LogHandler $module'; // Show modules according to features level if ($module->getVersion() == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) { @@ -96,6 +98,7 @@ if ($action == 'set') { foreach ($syslogModules as $syslogHandler) { if (in_array($syslogHandler, $syslogModules)) { $module = new $syslogHandler(); + '@phan-var-force LogHandler $module'; if (in_array($syslogHandler, $selectedModules)) { $newActiveModules[] = $syslogHandler; @@ -118,6 +121,7 @@ if ($action == 'set') { // Check configuration foreach ($activeModules as $modulename) { $module = new $modulename(); + '@phan-var-force LogHandler $module'; $res = $module->checkConfiguration(); if (!$res) { $error++; @@ -210,6 +214,7 @@ print "\n"; foreach ($syslogModules as $moduleName) { $module = new $moduleName(); + '@phan-var-force LogHandler $module'; $moduleactive = (int) $module->isActive(); //print $moduleName." = ".$moduleactive." - ".$module->getName()." ".($moduleactive == -1)."
      \n"; diff --git a/htdocs/admin/system/modules.php b/htdocs/admin/system/modules.php index ee4d525609e..71a10e7e7c0 100644 --- a/htdocs/admin/system/modules.php +++ b/htdocs/admin/system/modules.php @@ -115,6 +115,7 @@ foreach ($modulesdir as $dir) { if (class_exists($modName)) { try { $objMod = new $modName($db); + '@phan-var-force DolibarrModules $objMod'; $modules[$objMod->numero] = $objMod; $modules_files[$objMod->numero] = $file; @@ -132,6 +133,7 @@ foreach ($modulesdir as $dir) { closedir($handle); } } +'@phan-var-force array $modules'; // create pre-filtered list for modules foreach ($modules as $key => $module) { diff --git a/htdocs/admin/system/phpinfo.php b/htdocs/admin/system/phpinfo.php index 3c410fbe0d4..3d154fe2b8a 100644 --- a/htdocs/admin/system/phpinfo.php +++ b/htdocs/admin/system/phpinfo.php @@ -115,7 +115,7 @@ if (versioncompare(versionphparray(), $arrayphpminversionerror) < 0) { print ''; print 'GET and POST support'; -if (!isset($_GET["testget"]) && !isset($_POST["testpost"]) && !isset($_GET["mainmenu"])) { // We must keep $_GET and $_POST here +if (!isset($_GET["testget"]) && !isset($_POST["testpost"]) && !isset($_GET["mainmenu"])) { // We must keep $_GET and $_POST here. This is a specific test. print 'Warning '.$langs->trans("PHPSupportPOSTGETKo"); print ' ('.$langs->trans("Recheck").')'; } else { diff --git a/htdocs/admin/ticket.php b/htdocs/admin/ticket.php index 60cc1ce67b5..f55ddd2d846 100644 --- a/htdocs/admin/ticket.php +++ b/htdocs/admin/ticket.php @@ -3,6 +3,7 @@ * Copyright (C) 2016 Christophe Battarel * Copyright (C) 2022-2023 Udo Tamm * Copyright (C) 2023 Alexandre Spangaro + * Copyright (C) 2024 MDW * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -289,6 +290,7 @@ foreach ($dirmodels as $reldir) { include_once $dir.'/'.$file.'.php'; $module = new $file(); + '@phan-var-force ModeleNumRefTicket $module'; // Show modules according to features level if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) { @@ -423,6 +425,7 @@ foreach ($dirmodels as $reldir) { require_once $dir.'/'.$file; $module = new $classname($db); + '@phan-var-force CommonDocGenerator $module'; $modulequalified = 1; if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) { diff --git a/htdocs/admin/tools/dolibarr_import.php b/htdocs/admin/tools/dolibarr_import.php index 7fd6a95a4c9..8313c5f1c0f 100644 --- a/htdocs/admin/tools/dolibarr_import.php +++ b/htdocs/admin/tools/dolibarr_import.php @@ -166,7 +166,7 @@ if (in_array($type, array('mysql', 'mysqli'))) { print '
      '; print ajax_autoselect('restorecommand'); - if (empty($_GET["showpass"]) && $dolibarr_main_db_pass) { + if (!GETPOST("showpass") && $dolibarr_main_db_pass) { print '
      '.$langs->trans("UnHidePassword").''; } //else print '
      '.$langs->trans("HidePassword").''; @@ -205,8 +205,6 @@ if (in_array($type, array('mysql', 'mysqli'))) { print '
      '; print '
      '; print ajax_autoselect('restorecommand'); - //if (empty($_GET["showpass"]) && $dolibarr_main_db_pass) print '
      '.$langs->trans("UnHidePassword").''; - //else print '
      '.$langs->trans("HidePassword").''; print '
      '; print '
      '; diff --git a/htdocs/admin/tools/listevents.php b/htdocs/admin/tools/listevents.php index 902239fca39..5b2d106e295 100644 --- a/htdocs/admin/tools/listevents.php +++ b/htdocs/admin/tools/listevents.php @@ -3,6 +3,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2015 Bahfir Abbes * Copyright (C) 2018 Frédéric France + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -299,22 +300,22 @@ if ($result) { $param .= '&search_prefix_session='.urlencode($search_prefix_session); } if ($date_startmonth) { - $param .= "&date_startmonth=".urlencode($date_startmonth); + $param .= "&date_startmonth=".((int) $date_startmonth); } if ($date_startday) { - $param .= "&date_startday=".urlencode($date_startday); + $param .= "&date_startday=".((int) $date_startday); } if ($date_startyear) { - $param .= "&date_startyear=".urlencode($date_startyear); + $param .= "&date_startyear=".((int) $date_startyear); } if ($date_endmonth) { - $param .= "&date_endmonth=".urlencode($date_endmonth); + $param .= "&date_endmonth=".((int) $date_endmonth); } if ($date_endday) { - $param .= "&date_endday=".urlencode($date_endday); + $param .= "&date_endday=".((int) $date_endday); } if ($date_endyear) { - $param .= "&date_endyear=".urlencode($date_endyear); + $param .= "&date_endyear=".((int) $date_endyear); } $center = ''; diff --git a/htdocs/admin/user.php b/htdocs/admin/user.php index 6cd21cd1567..4e52671dd61 100644 --- a/htdocs/admin/user.php +++ b/htdocs/admin/user.php @@ -7,6 +7,7 @@ * Copyright (C) 2005-2011 Regis Houssin * Copyright (C) 2015 Juanjo Menent * Copyright (C) 2020 Frédéric France + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -246,6 +247,7 @@ foreach ($dirmodels as $reldir) { require_once $dir.'/'.$file; $module = new $classname($db); + '@phan-var-force CommonDocGenerator $module'; $modulequalified = 1; if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) { diff --git a/htdocs/admin/usergroup.php b/htdocs/admin/usergroup.php index 598b8a687e8..fcd73691cde 100644 --- a/htdocs/admin/usergroup.php +++ b/htdocs/admin/usergroup.php @@ -6,6 +6,7 @@ * Copyright (C) 2004 Benoit Mortier * Copyright (C) 2005-2011 Regis Houssin * Copyright (C) 2015 Juanjo Menent + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -169,6 +170,7 @@ foreach ($dirmodels as $reldir) { require_once $dir.'/'.$file; $module = new $classname($db); + '@phan-var-force CommonDocGenerator $module'; $modulequalified = 1; if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) { diff --git a/htdocs/admin/website.php b/htdocs/admin/website.php index b517491d14c..1a1bc1815dd 100644 --- a/htdocs/admin/website.php +++ b/htdocs/admin/website.php @@ -257,7 +257,7 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { $sql .= ","; } $sql .= $field."="; - if ($_POST[$listfieldvalue[$i]] == '') { + if (GETPOST($listfieldvalue[$i]) == '') { $sql .= "null"; } else { $sql .= "'".$db->escape(GETPOST($listfieldvalue[$i]))."'"; @@ -300,11 +300,6 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { $db->rollback(); } } - //$_GET["id"]=GETPOST('id', 'int'); // Force affichage dictionnaire en cours d'edition -} - -if (GETPOST('actioncancel', 'alpha')) { - //$_GET["id"]=GETPOST('id', 'int'); // Force affichage dictionnaire en cours d'edition } if ($action == 'confirm_delete' && $confirm == 'yes') { // delete diff --git a/htdocs/admin/workstation.php b/htdocs/admin/workstation.php index 11d0b08e7f3..d7b350a9831 100644 --- a/htdocs/admin/workstation.php +++ b/htdocs/admin/workstation.php @@ -107,6 +107,7 @@ if ($action == 'updateMask') { require_once $file; $module = new $classname($db); + '@phan-var-force CommonDocGenerator $module'; if ($module->write_file($tmpobject, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=".strtolower($tmpobjectkey)."&file=SPECIMEN.pdf"); @@ -260,6 +261,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { require_once $dir.'/'.$file.'.php'; $module = new $file($db); + '@phan-var-force CommonNumRefGenerator $module'; // Show modules according to features level if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) { @@ -399,6 +401,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { require_once $dir.'/'.$file; $module = new $classname($db); + '@phan-var-force CommonDocGenerator $module'; $modulequalified = 1; if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) { diff --git a/htdocs/api/admin/index.php b/htdocs/api/admin/index.php index 4a9abc9f307..8ac6eed0201 100644 --- a/htdocs/api/admin/index.php +++ b/htdocs/api/admin/index.php @@ -150,7 +150,7 @@ print ' '.$langs->trans("Example").': '.$langs->trans("IPListExample"); print ''; print ''; print ''; -print ''; +print ''; print ''; print ''; diff --git a/htdocs/api/class/api.class.php b/htdocs/api/class/api.class.php index 63d504b14cb..1436eabd4b6 100644 --- a/htdocs/api/class/api.class.php +++ b/htdocs/api/class/api.class.php @@ -2,6 +2,7 @@ /* Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2016 Laurent Destailleur * Copyright (C) 2020 Frédéric France + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -73,8 +74,6 @@ class DolibarrApi /** * Check and convert a string depending on its type/name. * - * Display a short message an return a http code 200 - * * @param string $field Field name * @param string|array $value Value to check/clean * @param Object $object Object @@ -84,16 +83,45 @@ class DolibarrApi { // phpcs:enable if (!is_array($value)) { - // TODO Use type detected in $object->fields if $object known and we can + // Sanitize the value using its type declared into ->fields of $object + if (!empty($object->fields) && !empty($object->fields[$field]) && !empty($object->fields[$field]['type'])) { + if (strpos($object->fields[$field]['type'], 'int') || strpos($object->fields[$field]['type'], 'double') || in_array($object->fields[$field]['type'], array('real', 'price', 'stock'))) { + return sanitizeVal($value, 'int'); + } + if ($object->fields[$field]['type'] == 'html') { + return sanitizeVal($value, 'restricthtml'); + } + if ($object->fields[$field]['type'] == 'select') { + // Check values are in the list of possible 'options' + // TODO + } + if ($object->fields[$field]['type'] == 'sellist' || $object->fields[$field]['type'] == 'checkbox') { + // TODO + } + if ($object->fields[$field]['type'] == 'boolean' || $object->fields[$field]['type'] == 'radio') { + // TODO + } + if ($object->fields[$field]['type'] == 'email') { + return sanitizeVal($value, 'email'); + } + if ($object->fields[$field]['type'] == 'password') { + return sanitizeVal($value, 'none'); + } + // Others will use 'alphanohtml' + } + if (in_array($field, array('note', 'note_private', 'note_public', 'desc', 'description'))) { return sanitizeVal($value, 'restricthtml'); } else { return sanitizeVal($value, 'alphanohtml'); } - } else { - // TODO Recall _checkValForAPI for each element of array + } else { // Example when $field = 'extrafields' and $value = content of $object->array_options + $newarrayvalue = array(); + foreach ($value as $tmpkey => $tmpvalue) { + $newarrayvalue[$tmpkey] = $this->_checkValForAPI($tmpkey, $tmpvalue, $object); + } - return $value; + return $newarrayvalue; } } @@ -107,16 +135,41 @@ class DolibarrApi */ protected function _filterObjectProperties($object, $properties) { + // phpcs:enable // If properties is empty, we return all properties if (empty($properties)) { return $object; } - // Else we filter properties + + // Copy of exploded array for efficiency + $arr_properties = explode(',', $properties); + $magic_properties = array(); + $real_properties = get_object_vars($object); + + // Unsetting real properties may unset magic properties. + // We keep a copy of the requested magic properties + foreach ($arr_properties as $key) { + if (!array_key_exists($key, $real_properties)) { + // Not a real property, + // check if $key is a magic property (we want to keep '$obj->$key') + if (property_exists($object, $key) && isset($object->$key)) { + $magic_properties[$key] = $object->$key; + } + } + } + + // Filter real properties (may indirectly unset magic properties) foreach (get_object_vars($object) as $key => $value) { - if (!in_array($key, explode(',', $properties))) { + if (!in_array($key, $arr_properties)) { unset($object->$key); } } + + // Restore the magic properties + foreach ($magic_properties as $key => $value) { + $object->$key = $value; + } + return $object; } diff --git a/htdocs/api/class/api_access.class.php b/htdocs/api/class/api_access.class.php index 8e4bdb0db9f..61f664d8562 100644 --- a/htdocs/api/class/api_access.class.php +++ b/htdocs/api/class/api_access.class.php @@ -106,7 +106,7 @@ class DolibarrApiAccess implements iAuthenticate // api key can be provided in url with parameter api_key=xxx or ni header with header DOLAPIKEY:xxx $api_key = ''; - if (isset($_GET['api_key'])) { // For backward compatibility + if (isset($_GET['api_key'])) { // For backward compatibility. Keep $_GET here. // TODO Add option to disable use of api key on url. Return errors if used. $api_key = $_GET['api_key']; } diff --git a/htdocs/api/index.php b/htdocs/api/index.php index 4b3385fe5ee..31e8dcf47c7 100644 --- a/htdocs/api/index.php +++ b/htdocs/api/index.php @@ -167,6 +167,7 @@ if (!empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/swagger.json' || $ $refreshcache = true; if (!is_writable($conf->api->dir_temp)) { print 'Erreur temp dir api/temp not writable'; + header('HTTP/1.1 500 temp dir api/temp not writable'); exit(0); } } diff --git a/htdocs/asset/admin/setup.php b/htdocs/asset/admin/setup.php index 0016c5e82e5..eea47281a3c 100644 --- a/htdocs/asset/admin/setup.php +++ b/htdocs/asset/admin/setup.php @@ -119,6 +119,7 @@ if ($action == 'updateMask') { require_once $file; $module = new $classname($db); + '@phan-var-force CommonDocGenerator $module'; if ($module->write_file($tmpobject, $langs) > 0) { header("Location: ".DOL_URL_ROOT."/document.php?modulepart=".strtolower($tmpobjectkey)."&file=SPECIMEN.pdf"); @@ -232,6 +233,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { require_once $dir.'/'.$file.'.php'; $module = new $file($db); + '@phan-var-force CommonNumRefGenerator $module'; // Show modules according to features level if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) { @@ -371,6 +373,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { require_once $dir.'/'.$file; $module = new $classname($db); + '@phan-var-force CommonDocGenerator $module'; $modulequalified = 1; if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) { diff --git a/htdocs/asset/card.php b/htdocs/asset/card.php index 434ee1f3318..24af02996b7 100644 --- a/htdocs/asset/card.php +++ b/htdocs/asset/card.php @@ -194,8 +194,6 @@ if ($action == 'create') { print dol_get_fiche_head(array(), ''); - // Set some default values - //if (! GETPOSTISSET('fieldname')) $_POST['fieldname'] = 'myvalue'; print ''."\n"; diff --git a/htdocs/asset/class/asset.class.php b/htdocs/asset/class/asset.class.php index 4c016282171..51b28f18427 100644 --- a/htdocs/asset/class/asset.class.php +++ b/htdocs/asset/class/asset.class.php @@ -158,7 +158,7 @@ class Asset extends CommonObject public $status; /** - * @var Asset object oldcopy + * @var static object oldcopy */ public $oldcopy; diff --git a/htdocs/asset/model/card.php b/htdocs/asset/model/card.php index 31544663a62..d0d413d543e 100644 --- a/htdocs/asset/model/card.php +++ b/htdocs/asset/model/card.php @@ -180,8 +180,6 @@ if ($action == 'create') { print dol_get_fiche_head(array(), ''); - // Set some default values - //if (! GETPOSTISSET('fieldname')) $_POST['fieldname'] = 'myvalue'; print '
      ' . "\n"; diff --git a/htdocs/barcode/codeinit.php b/htdocs/barcode/codeinit.php index 0852c9d6586..73c19e1f96b 100644 --- a/htdocs/barcode/codeinit.php +++ b/htdocs/barcode/codeinit.php @@ -1,6 +1,7 @@ * Copyright (C) 2018 Ferran Marcet + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -86,6 +87,7 @@ if (getDolGlobalString('BARCODE_THIRDPARTY_ADDON_NUM')) { } $modBarCodeThirdparty = new $file(); + '@phan-var-force ModeleNumRefBarCode $module'; break; } } @@ -190,6 +192,7 @@ if (getDolGlobalString('BARCODE_PRODUCT_ADDON_NUM')) { } $modBarCodeProduct = new $file(); + '@phan-var-force ModeleNumRefBarCode $module'; break; } } diff --git a/htdocs/barcode/printsheet.php b/htdocs/barcode/printsheet.php index 6ee4e9c9ac7..608297551b8 100644 --- a/htdocs/barcode/printsheet.php +++ b/htdocs/barcode/printsheet.php @@ -24,6 +24,7 @@ * \brief Page to print sheets with barcodes using the document templates into core/modules/printsheets */ +// Do not use GETPOST, the function does not exists yet. if (!empty($_POST['mode']) && $_POST['mode'] === 'label') { // Page is called to build a PDF and output, we must not renew the token. if (!defined('NOTOKENRENEWAL')) { define('NOTOKENRENEWAL', '1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on) @@ -179,6 +180,7 @@ if (empty($reshook)) { // Load barcode class for generating barcode image $classname = "mod".ucfirst($generator); $module = new $classname($db); + '@phan-var-force ModeleBarCode $module'; if ($generator != 'tcpdfbarcode') { // May be phpbarcode $template = 'standardlabel'; diff --git a/htdocs/blockedlog/admin/blockedlog_list.php b/htdocs/blockedlog/admin/blockedlog_list.php index 2604e35f362..b321745f90d 100644 --- a/htdocs/blockedlog/admin/blockedlog_list.php +++ b/htdocs/blockedlog/admin/blockedlog_list.php @@ -2,6 +2,7 @@ /* Copyright (C) 2017 ATM Consulting * Copyright (C) 2017-2018 Laurent Destailleur * Copyright (C) 2018 Frédéric France + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -349,25 +350,25 @@ if ($search_fk_user > 0) { $param .= '&search_fk_user='.urlencode($search_fk_user); } if ($search_startyear > 0) { - $param .= '&search_startyear='.urlencode($search_startyear); + $param .= '&search_startyear='.((int) $search_startyear); } if ($search_startmonth > 0) { - $param .= '&search_startmonth='.urlencode($search_startmonth); + $param .= '&search_startmonth='.((int) $search_startmonth); } if ($search_startday > 0) { - $param .= '&search_startday='.urlencode($search_startday); + $param .= '&search_startday='.((int) $search_startday); } if ($search_endyear > 0) { - $param .= '&search_endyear='.urlencode((string) ($search_endyear)); + $param .= '&search_endyear='.((int) $search_endyear); } if ($search_endmonth > 0) { - $param .= '&search_endmonth='.urlencode((string) ($search_endmonth)); + $param .= '&search_endmonth='.((int) $search_endmonth); } if ($search_endday > 0) { - $param .= '&search_endday='.urlencode((string) ($search_endday)); + $param .= '&search_endday='.((int) $search_endday); } if ($search_showonlyerrors > 0) { - $param .= '&search_showonlyerrors='.urlencode((string) ($search_showonlyerrors)); + $param .= '&search_showonlyerrors='.((int) $search_showonlyerrors); } if ($optioncss != '') { $param .= '&optioncss='.urlencode($optioncss); diff --git a/htdocs/blockedlog/class/blockedlog.class.php b/htdocs/blockedlog/class/blockedlog.class.php index 64f69ea390d..79f267f32ac 100644 --- a/htdocs/blockedlog/class/blockedlog.class.php +++ b/htdocs/blockedlog/class/blockedlog.class.php @@ -371,13 +371,13 @@ class BlockedLog } /** - * Populate properties of log from object data + * Populate properties of log from object data * - * @param Object $object object to store - * @param string $action action - * @param string $amounts amounts - * @param User $fuser User object (forced) - * @return int >0 if OK, <0 if KO + * @param CommonObject $object object to store + * @param string $action action + * @param string $amounts amounts + * @param ?User $fuser User object (forced) + * @return int >0 if OK, <0 if KO */ public function setObjectData(&$object, $action, $amounts, $fuser = null) { @@ -1096,7 +1096,7 @@ class BlockedLog * @param string $search_ref search ref * @param string $search_amount search amount * @param string $search_code search code - * @return array|int Array of object log or <0 if error + * @return BlockedLog[]|int<-2,-1> Array of object log or <0 if error */ public function getLog($element, $fk_object, $limit = 0, $sortfield = '', $sortorder = '', $search_fk_user = -1, $search_start = -1, $search_end = -1, $search_ref = '', $search_amount = '', $search_code = '') { diff --git a/htdocs/bom/bom_card.php b/htdocs/bom/bom_card.php index 5753ce0bc89..a6210efa27a 100644 --- a/htdocs/bom/bom_card.php +++ b/htdocs/bom/bom_card.php @@ -164,7 +164,7 @@ if (empty($reshook)) { $idprod = $bom_child->fk_product; } } else { - $idprod = (!empty(GETPOSTINT('idprodservice')) ? GETPOSTINT('idprodservice') : GETPOSTINT('idprod')); + $idprod = (GETPOSTINT('idprodservice') ? GETPOSTINT('idprodservice') : GETPOSTINT('idprod')); } $qty = price2num(GETPOST('qty', 'alpha'), 'MS'); diff --git a/htdocs/bom/class/api_boms.class.php b/htdocs/bom/class/api_boms.class.php index f551600797a..3f9fe328199 100644 --- a/htdocs/bom/class/api_boms.class.php +++ b/htdocs/bom/class/api_boms.class.php @@ -196,11 +196,11 @@ class Boms extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->bom->context['caller'] = $request_data['caller']; + $this->bom->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->bom->$field = $value; + $this->bom->$field = $this->_checkValForAPI($field, $value, $this->bom); } $this->checkRefNumbering(); @@ -243,11 +243,18 @@ class Boms extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->bom->context['caller'] = $request_data['caller']; + $this->bom->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->bom->$field = $value; + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->bom->array_options[$index] = $this->_checkValForAPI('extrafields', $val, $this->bom); + } + continue; + } + + $this->bom->$field = $this->_checkValForAPI($field, $value, $this->bom); } $this->checkRefNumbering(); @@ -280,7 +287,7 @@ class Boms extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('bom', $this->bom->id, 'bom_bom')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if (!$this->bom->delete(DolibarrApiAccess::$user)) { @@ -531,6 +538,14 @@ class Boms extends DolibarrApi unset($object->fk_incoterms); unset($object->label_incoterms); unset($object->location_incoterms); + unset($object->multicurrency_code); + unset($object->multicurrency_tx); + unset($object->multicurrency_total_ht); + unset($object->multicurrency_total_ttc); + unset($object->multicurrency_total_tva); + unset($object->multicurrency_total_localtax1); + unset($object->multicurrency_total_localtax2); + // If object has lines, remove $db property if (isset($object->lines) && is_array($object->lines) && count($object->lines) > 0) { diff --git a/htdocs/bom/tpl/objectline_create.tpl.php b/htdocs/bom/tpl/objectline_create.tpl.php index cf927bc763c..f76695eb2c1 100644 --- a/htdocs/bom/tpl/objectline_create.tpl.php +++ b/htdocs/bom/tpl/objectline_create.tpl.php @@ -196,11 +196,11 @@ if ($filtertype != 1) { print ''; } - $coldisplay += $colspan; - print ''; - print ''; +$coldisplay += $colspan; +print ''; +print ''; ?> diff --git a/htdocs/bom/tpl/objectline_view.tpl.php b/htdocs/bom/tpl/objectline_view.tpl.php index 6489f833759..463a92d4ee8 100644 --- a/htdocs/bom/tpl/objectline_view.tpl.php +++ b/htdocs/bom/tpl/objectline_view.tpl.php @@ -351,11 +351,12 @@ if ($resql) { print ''.price(price2num($sub_bom_product->pmp * $sub_bom_line->qty * (float) $line->qty, 'MT')).''; $total_cost .= $sub_bom_product->pmp * $sub_bom_line->qty * (float) $line->qty; } else { // Minimum purchase price if cost price and PMP aren't defined - $sql_supplier_price = 'SELECT MIN(price) AS min_price, quantity AS qty FROM '.MAIN_DB_PREFIX.'product_fournisseur_price'; - $sql_supplier_price .= ' WHERE fk_product = '. (int) $sub_bom_product->id; + $sql_supplier_price = "SELECT MIN(price) AS min_price, quantity AS qty FROM ".MAIN_DB_PREFIX."product_fournisseur_price"; + $sql_supplier_price .= " WHERE fk_product = ". (int) $sub_bom_product->id; + $sql_supplier_price .= " GROUP BY quantity ORDER BY quantity ASC"; $resql_supplier_price = $object->db->query($sql_supplier_price); if ($resql_supplier_price) { - $obj = $object->db->fetch_object($resql_supplier_price); + $obj = $object->db->fetch_object($resql_supplier_price); // Take first value so the ref with the smaller minimum quantity if (!empty($obj->qty) && !empty($sub_bom_line->qty) && !empty($line->qty)) { $line_cost = $obj->min_price / $obj->qty * $sub_bom_line->qty * (float) $line->qty; } else { diff --git a/htdocs/bookcal/availabilities_card.php b/htdocs/bookcal/availabilities_card.php index bc62dd76842..4ab6e667e35 100644 --- a/htdocs/bookcal/availabilities_card.php +++ b/htdocs/bookcal/availabilities_card.php @@ -253,8 +253,6 @@ if ($action == 'create') { print dol_get_fiche_head(array(), ''); - // Set some default values - //if (! GETPOSTISSET('fieldname')) $_POST['fieldname'] = 'myvalue'; print '
      '; - print ''; - print '
      '; +print ''; +print '
      '."\n"; diff --git a/htdocs/bookcal/calendar_card.php b/htdocs/bookcal/calendar_card.php index 2b86d58e41d..2f267666132 100644 --- a/htdocs/bookcal/calendar_card.php +++ b/htdocs/bookcal/calendar_card.php @@ -226,8 +226,6 @@ if ($action == 'create') { print dol_get_fiche_head(array(), ''); - // Set some default values - //if (! GETPOSTISSET('fieldname')) $_POST['fieldname'] = 'myvalue'; print '
      '."\n"; diff --git a/htdocs/bookmarks/bookmarks.lib.php b/htdocs/bookmarks/bookmarks.lib.php index 711e4fa5a49..edd6988d38b 100644 --- a/htdocs/bookmarks/bookmarks.lib.php +++ b/htdocs/bookmarks/bookmarks.lib.php @@ -29,7 +29,7 @@ */ function printDropdownBookmarksList() { - global $conf, $user, $db, $langs, $sortfield, $sortorder; + global $user, $db, $langs, $sortfield, $sortorder; require_once DOL_DOCUMENT_ROOT.'/bookmarks/class/bookmark.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php'; @@ -40,7 +40,7 @@ function printDropdownBookmarksList() $url = $_SERVER["PHP_SELF"]; $url_param = array(); if (!empty($_SERVER["QUERY_STRING"])) { - if (is_array($_GET)) { + if (is_array($_GET)) { // Parse the original GET URL. So we must keep $_GET here. foreach ($_GET as $key => $val) { if (is_array($val)) { foreach ($val as $tmpsubval) { diff --git a/htdocs/categories/card.php b/htdocs/categories/card.php index 06510e44aa7..2a23a4a8784 100644 --- a/htdocs/categories/card.php +++ b/htdocs/categories/card.php @@ -6,6 +6,7 @@ * Copyright (C) 2013 Florian Henry * Copyright (C) 2015 Raphaël Doursenaud * Copyright (C) 2020 Frédéric France + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -81,6 +82,9 @@ if ($origin) { if ($catorigin && $type == Categorie::TYPE_PRODUCT) { $idCatOrigin = $catorigin; } +if (!GETPOSTISSET('parent') && $catorigin) { + $parent = $catorigin; +} $object = new Categorie($db); @@ -165,7 +169,6 @@ if (empty($reshook)) { $result = $object->create($user); if ($result > 0) { $action = 'confirmed'; - $_POST["addcat"] = ''; } else { setEventMessages($object->error, $object->errors, 'errors'); } @@ -220,14 +223,13 @@ llxHeader("", $langs->trans("Categories"), $help_url); if ($user->hasRight('categorie', 'creer')) { // Create or add - if ($action == 'create' || GETPOST("addcat") == 'addcat') { + if ($action == 'create' || $action == 'add') { dol_set_focus('#label'); print ''; print ''; print ''; print ''; - print ''; print ''; print ''; print ''; @@ -240,7 +242,7 @@ if ($user->hasRight('categorie', 'creer')) { print load_fiche_titre($langs->trans("CreateCat")); - print dol_get_fiche_head(''); + print dol_get_fiche_head(); print '
      '; @@ -269,7 +271,7 @@ if ($user->hasRight('categorie', 'creer')) { // Parent category print ''; @@ -282,7 +284,7 @@ if ($user->hasRight('categorie', 'creer')) { print '
      '.$langs->trans("AddIn").''; print img_picto($langs->trans("ParentCategory"), 'category', 'class="pictofixedwidth"'); - print $form->select_all_categories($type, $catorigin, 'parent'); + print $form->select_all_categories($type, $parent, 'parent'); print ajax_combobox('parent'); print '
      '; - print dol_get_fiche_end(''); + print dol_get_fiche_end(); print '
      '; print ''; diff --git a/htdocs/categories/class/api_categories.class.php b/htdocs/categories/class/api_categories.class.php index 79b5007a241..f3b8c011f11 100644 --- a/htdocs/categories/class/api_categories.class.php +++ b/htdocs/categories/class/api_categories.class.php @@ -99,7 +99,7 @@ class Categories extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('categorie', $this->category->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if ($include_childs) { @@ -203,11 +203,11 @@ class Categories extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->category->context['caller'] = $request_data['caller']; + $this->category->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->category->$field = $value; + $this->category->$field = $this->_checkValForAPI($field, $value, $this->category); } if ($this->category->create(DolibarrApiAccess::$user) < 0) { throw new RestException(500, 'Error when creating category', array_merge(array($this->category->error), $this->category->errors)); @@ -234,7 +234,7 @@ class Categories extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('categorie', $this->category->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach ($request_data as $field => $value) { @@ -243,11 +243,11 @@ class Categories extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->category->context['caller'] = $request_data['caller']; + $this->category->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->category->$field = $value; + $this->category->$field = $this->_checkValForAPI($field, $value, $this->category); } if ($this->category->update(DolibarrApiAccess::$user) > 0) { @@ -274,7 +274,7 @@ class Categories extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('categorie', $this->category->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if (!$this->category->delete(DolibarrApiAccess::$user)) { @@ -767,7 +767,7 @@ class Categories extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('categorie', $this->category->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->category->getObjectsInCateg($type, $onlyids); diff --git a/htdocs/categories/photos.php b/htdocs/categories/photos.php index bd40d078fa1..f44052afbd8 100644 --- a/htdocs/categories/photos.php +++ b/htdocs/categories/photos.php @@ -95,12 +95,12 @@ if (empty($reshook)) { } } - if ($action == 'confirm_delete' && $_GET["file"] && $confirm == 'yes' && $user->hasRight('categorie', 'creer')) { - $object->delete_photo($upload_dir."/".$_GET["file"]); + if ($action == 'confirm_delete' && GETPOST("file") && $confirm == 'yes' && $user->hasRight('categorie', 'creer')) { + $object->delete_photo($upload_dir."/".GETPOST("file")); } - if ($action == 'addthumb' && $_GET["file"]) { - $object->addThumbs($upload_dir."/".$_GET["file"]); + if ($action == 'addthumb' && GETPOST("file")) { + $object->addThumbs($upload_dir."/".GETPOST("file")); } } @@ -133,10 +133,10 @@ if ($object->id) { dol_banner_tab($object, 'label', $linkback, ($user->socid ? 0 : 1), 'label', 'label', $morehtmlref, '&type='.$type, 0, '', '', 1); /* - * Confirmation de la suppression de photo - */ + * Confirmation deletion of picture + */ if ($action == 'delete') { - print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&type='.$type.'&file='.$_GET["file"], $langs->trans('DeletePicture'), $langs->trans('ConfirmDeletePicture'), 'confirm_delete', '', 0, 1); + print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&type='.urlencode($type).'&file='.urlencode(GETPOST("file")), $langs->trans('DeletePicture'), $langs->trans('ConfirmDeletePicture'), 'confirm_delete', '', 0, 1); } print '
      '; diff --git a/htdocs/categories/viewcat.php b/htdocs/categories/viewcat.php index 9dbbd684cf7..113a1cc1ad1 100644 --- a/htdocs/categories/viewcat.php +++ b/htdocs/categories/viewcat.php @@ -507,6 +507,7 @@ if ($type == Categorie::TYPE_PRODUCT) { dol_print_error($db, $object->error, $object->errors); } else { /** @var Product[] $prods */ + '@phan-var-force Product[] $prods'; // Form to add record into the category $showclassifyform = 1; if ($showclassifyform) { @@ -594,6 +595,7 @@ if ($type == Categorie::TYPE_CUSTOMER) { dol_print_error($db, $object->error, $object->errors); } else { /** @var Societe[] $socs */ + '@phan-var-force Societe[] $socs'; // Form to add record into a category $showclassifyform = 1; if ($showclassifyform) { @@ -680,6 +682,7 @@ if ($type == Categorie::TYPE_SUPPLIER) { dol_print_error($db, $object->error, $object->errors); } else { /** @var Fournisseur[] $socs */ + '@phan-var-force Fournisseur[] $socs'; // Form to add record into a category $showclassifyform = 1; if ($showclassifyform) { @@ -769,6 +772,7 @@ if ($type == Categorie::TYPE_MEMBER) { dol_print_error($db, $object->error, $object->errors); } else { /** @var Adherent[] $members */ + '@phan-var-force Adherent[] $members'; // Form to add record into a category $showclassifyform = 1; if ($showclassifyform) { @@ -857,6 +861,7 @@ if ($type == Categorie::TYPE_CONTACT) { dol_print_error($db, $object->error, $object->errors); } else { /** @var Contact[] $contacts */ + '@phan-var-force Contact[] $contacts'; // Form to add record into a category $showclassifyform = 1; if ($showclassifyform) { @@ -950,6 +955,7 @@ if ($type == Categorie::TYPE_ACCOUNT) { dol_print_error($db, $object->error, $object->errors); } else { /** @var Account[] $accounts */ + '@phan-var-force Account[] $accounts'; // Form to add record into a category $showclassifyform = 1; if ($showclassifyform) { @@ -1039,6 +1045,7 @@ if ($type == Categorie::TYPE_PROJECT) { dol_print_error($db, $object->error, $object->errors); } else { /** @var Project $object */ + '@phan-var-force Project $object'; // Form to add record into a category $showclassifyform = 1; if ($showclassifyform) { @@ -1126,6 +1133,7 @@ if ($type == Categorie::TYPE_USER) { dol_print_error($db, $object->error, $object->errors); } else { /** @var User[] $users */ + '@phan-var-force User[] $users'; // Form to add record into a category $showclassifyform = 1; if ($showclassifyform) { @@ -1212,6 +1220,7 @@ if ($type == Categorie::TYPE_WAREHOUSE) { dol_print_error($db, $object->error, $object->errors); } else { /** @var Entrepot[] $objects */ + '@phan-var-force Entrepot[] $objects'; print ''; print ''; print ''; @@ -1279,6 +1288,7 @@ if ($type == Categorie::TYPE_TICKET) { dol_print_error($db, $object->error, $object->errors); } else { /** @var Ticket[] $tickets */ + '@phan-var-force Ticket[] $tickets'; // Form to add record into a category $showclassifyform = 1; if ($showclassifyform) { diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index 09e73b188f8..7f8afbecf48 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -60,14 +60,14 @@ class ActionComm extends CommonObject public $picto = 'action'; /** - * @var int 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int<0,2> 0=No test on entity, 1=Test with field entity, 2=Test with link by societe */ public $ismultientitymanaged = 1; /** - * @var integer 0=Default - * 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user - * 2=Same than 1 but accept record if fksoc is empty + * @var int<0,2> 0=Default + * 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user + * 2=Same than 1 but accept record if fksoc is empty */ public $restrictiononfksoc = 2; @@ -129,20 +129,20 @@ class ActionComm extends CommonObject * @var string Agenda event label * @deprecated Use $label */ - public $libelle; + private $libelle; /** - * @var integer Date creation record (datec) + * @var int Date creation record (datec) */ public $datec; /** - * @var integer Duration (duree) + * @var int Duration (duree) */ public $duree; /** - * @var integer Date modification record (tms) + * @var int Date modification record (tms) */ public $datem; @@ -171,33 +171,33 @@ class ActionComm extends CommonObject public $usermodid; /** - * @var integer Date action start (datep) + * @var int Date action start (datep) */ public $datep; /** - * @var integer Date action end (datef) + * @var int Date action end (datef) */ public $datef; /** - * @var integer This is date start action (datep) but modified to not be outside calendar view. + * @var int This is date start action (datep) but modified to not be outside calendar view. */ public $date_start_in_calendar; /** - * @var integer This is date end action (datef) but modified to not be outside calendar view. + * @var int This is date end action (datef) but modified to not be outside calendar view. */ public $date_end_in_calendar; /** - * @var integer Date action end (datep2) + * @var int Date action end (datep2) */ public $datep2; /** * @var int -1=Unknown duration - * @deprecated + * @deprecated Use ($datef - $datep) */ public $durationp = -1; @@ -212,7 +212,7 @@ class ActionComm extends CommonObject public $ponctuel; /** - * @var integer Percentage + * @var int<-1,100> Percentage */ public $percentage; @@ -232,7 +232,7 @@ class ActionComm extends CommonObject public $priority; /** - * @var array Array of users + * @var array}> Array of users */ public $userassigned = array(); @@ -242,7 +242,7 @@ class ActionComm extends CommonObject public $userownerid; /** - * @var int[] Array of contact ids + * @var array,answer_status:int,transparency:int<0,1>}> Array of contact ids */ public $socpeopleassigned = array(); @@ -252,7 +252,7 @@ class ActionComm extends CommonObject public $otherassigned = array(); /** - * @var array Array of reminders + * @var array Array of reminders */ public $reminders = array(); @@ -268,14 +268,14 @@ class ActionComm extends CommonObject /** - * @var Societe|null Company linked to action (optional) + * @var ?Societe Company linked to action (optional) * @deprecated * @see $socid */ public $societe; /** - * @var Contact|null Contact linked to action (optional) + * @var ?Contact Contact linked to action (optional) * @deprecated * @see $contact_id */ @@ -308,7 +308,7 @@ class ActionComm extends CommonObject public $icalname; /** - * @var int<0,3> Ical color + * @var string Ical color (Hex value for color on 6 nibles) */ public $icalcolor; @@ -318,7 +318,7 @@ class ActionComm extends CommonObject public $extraparams; /** - * @var array Actions + * @var array Actions */ public $actions = array(); @@ -377,12 +377,21 @@ class ActionComm extends CommonObject public $status; /** + * @var string IP address + */ + public $ip; + + /* * Properties to manage the recurring events */ - public $recurid; /* A string YYYYMMDDHHMMSS shared by allevent of same series */ - public $recurrule; /* Rule of recurring */ - public $recurdateend; /* Repeat until this date */ + /** @var string A string YYYYMMDDHHMMSS shared by allevent of same series */ + public $recurid; + /** @var string Rule of recurring */ + public $recurrule; + /** @var string Repeat until this date */ + public $recurdateend; + /** @var int Duration of phone call when the event is a phone call */ public $calling_duration; @@ -405,6 +414,19 @@ class ActionComm extends CommonObject public $fields = array(); + /** + * Provide list of deprecated properties and replacements + * + * @return array Old property to new property mapping + */ + protected function deprecatedProperties() + { + return array( + 'libelle' => 'label', + ) + parent::deprecatedProperties(); + } + + /** * Constructor * @@ -419,9 +441,9 @@ class ActionComm extends CommonObject * Add an action/event into database. * $this->type_id OR $this->type_code must be set. * - * @param User $user Object user making action - * @param int $notrigger 1 = disable triggers, 0 = enable triggers - * @return int Id of created event, < 0 if KO + * @param User $user Object user making action + * @param int<0,1> $notrigger 1 = disable triggers, 0 = enable triggers + * @return int Id of created event, < 0 if KO */ public function create(User $user, $notrigger = 0) { @@ -775,12 +797,12 @@ class ActionComm extends CommonObject /** * Load object from database * - * @param int $id Id of action to get - * @param string $ref Ref of action to get - * @param string $ref_ext Ref ext to get - * @param string $email_msgid Email msgid - * @param int $loadresources 1=Load also resources - * @return int Return integer <0 if KO, >0 if OK + * @param int $id Id of action to get + * @param string $ref Ref of action to get + * @param string $ref_ext Ref ext to get + * @param string $email_msgid Email msgid + * @param int<0,1> $loadresources 1=Load also resources + * @return int<-1,1> Return integer <0 if KO, >0 if OK */ public function fetch($id, $ref = '', $ref_ext = '', $email_msgid = '', $loadresources = 1) { @@ -926,7 +948,7 @@ class ActionComm extends CommonObject /** * Initialize $this->userassigned & this->socpeopleassigned array with list of id of user and contact assigned to event * - * @return int Return integer <0 if KO, >0 if OK + * @return int<-1,1> Return integer <0 if KO, >0 if OK */ public function fetchResources() { @@ -972,7 +994,7 @@ class ActionComm extends CommonObject * Initialize this->userassigned array with list of id of user assigned to event * * @param bool $override Override $this->userownerid when empty. TODO This should be false by default. True is here to fix corrupted data. - * @return int Return integer <0 if KO, >0 if OK + * @return int<-1,1> Return integer <0 if KO, >0 if OK */ public function fetch_userassigned($override = true) { @@ -1017,9 +1039,9 @@ class ActionComm extends CommonObject /** * Delete event from database * - * @param User $user User making the delete - * @param int $notrigger 1 = disable triggers, 0 = enable triggers - * @return int Return integer <0 if KO, >0 if OK + * @param User $user User making the delete + * @param int<0,1> $notrigger 1 = disable triggers, 0 = enable triggers + * @return int<-2,1> Return integer <0 if KO, >0 if OK */ public function delete($user, $notrigger = 0) { @@ -1113,9 +1135,9 @@ class ActionComm extends CommonObject * Update action into database * If percentage = 100, on met a jour date 100% * - * @param User $user Object user making change - * @param int $notrigger 1 = disable triggers, 0 = enable triggers - * @return int Return integer <0 if KO, >0 if OK + * @param User $user Object user making change + * @param int<0,1> $notrigger 1 = disable triggers, 0 = enable triggers + * @return int<-2,1> Return integer <0 if KO, >0 if OK */ public function update(User $user, $notrigger = 0) { @@ -1436,6 +1458,7 @@ class ActionComm extends CommonObject $resql = $this->db->query($sql); if ($resql) { + $response = null; // Ensure the variable is defined if (empty($load_state_board)) { $agenda_static = new ActionComm($this->db); $response = new WorkboardResponse(); @@ -1451,6 +1474,8 @@ class ActionComm extends CommonObject // This assignment in condition is not a bug. It allows walking the results. while ($obj = $this->db->fetch_object($resql)) { if (empty($load_state_board)) { + '@phan-var-force WorkboardResponse $response + @phan-var-force ActionComm $agenda_static'; $response->nbtodo++; $agenda_static->datep = $this->db->jdate($obj->dp); if ($agenda_static->hasDelay()) { @@ -1515,8 +1540,8 @@ class ActionComm extends CommonObject /** * Return the label of the status * - * @param int $mode 0=Long label, 1=Short label, 2=Picto+Short label, 3=Picto, 4=Picto+Short label, 5=Short label+Picto, 6=Picto+Long label, 7=Very short label+Picto - * @param int $hidenastatus 1=Show nothing if status is "Not applicable" + * @param int<0,7> $mode 0=Long label, 1=Short label, 2=Picto+Short label, 3=Picto, 4=Picto+Short label, 5=Short label+Picto, 6=Picto+Long label, 7=Very short label+Picto + * @param int<0,1> $hidenastatus 1=Show nothing if status is "Not applicable" * @return string String with status */ public function getLibStatut($mode, $hidenastatus = 0) @@ -1528,11 +1553,11 @@ class ActionComm extends CommonObject /** * Return label of action status * - * @param int $percent Percent - * @param int $mode 0=Long label, 1=Short label, 2=Picto+Short label, 3=Picto, 4=Picto+Short label, 5=Short label+Picto, 6=Picto+Long label, 7=Very short label+Picto - * @param int $hidenastatus 1=Show nothing if status is "Not applicable" - * @param int|string $datestart Date start of event - * @return string Label + * @param int<0,100> $percent Percent + * @param int<0,7> $mode 0=Long label, 1=Short label, 2=Picto+Short label, 3=Picto, 4=Picto+Short label, 5=Short label+Picto, 6=Picto+Long label, 7=Very short label+Picto + * @param int<0,1> $hidenastatus 1=Show nothing if status is "Not applicable" + * @param int|string $datestart Date start of event + * @return string Label */ public function LibStatut($percent, $mode, $hidenastatus = 0, $datestart = '') { @@ -1580,9 +1605,9 @@ class ActionComm extends CommonObject /** * getTooltipContentArray - * @param array $params params to construct tooltip data + * @param array $params params to construct tooltip data * @since v18 - * @return array + * @return array{picto:string,ref?:string,title?:string,labeltype?:string,location?:string,transparency?:string,space?:string,mailtopic?:string,mailfrom?:string,mailto?:string,mailcc?:string,description?:string,note?:string,categories?:string} */ public function getTooltipContentArray($params) { @@ -1603,7 +1628,6 @@ class ActionComm extends CommonObject $labeltype = $langs->trans('ActionAC_MANUAL'); } } - $datas['picto'] = img_picto('', $this->picto).' '.$langs->trans('Action').''; if (!empty($this->ref)) { $datas['ref'] = '
      '.$langs->trans('Ref').': '.dol_escape_htmltag($this->ref); @@ -1658,13 +1682,13 @@ class ActionComm extends CommonObject * Return URL of event * Use $this->id, $this->type_code, $this->label and $this->type_label * - * @param int $withpicto 0 = No picto, 1 = Include picto into link, 2 = Only picto - * @param int $maxlength Max number of characters into label. If negative, use the ref as label. - * @param string $classname Force style class on a link - * @param string $option '' = Link to action, 'birthday'= Link to contact, 'holiday' = Link to leave - * @param int $overwritepicto 1 = Overwrite picto with this one - * @param int $notooltip 1 = Disable tooltip - * @param int $save_lastsearch_value -1 = Auto, 0 = No save of lastsearch_values when clicking, 1 = Save lastsearch_values whenclicking + * @param int<0,2> $withpicto 0 = No picto, 1 = Include picto into link, 2 = Only picto + * @param int $maxlength Max number of characters into label. If negative, use the ref as label. + * @param string $classname Force style class on a link + * @param string $option '' = Link to action, 'birthday'= Link to contact, 'holiday' = Link to leave + * @param int<0,1> $overwritepicto 1 = Overwrite picto with this one + * @param int<0,1> $notooltip 1 = Disable tooltip + * @param int<-1,1> $save_lastsearch_value -1 = Auto, 0 = No save of lastsearch_values when clicking, 1 = Save lastsearch_values whenclicking * @return string Chaine avec URL */ public function getNomUrl($withpicto = 0, $maxlength = 0, $classname = '', $option = '', $overwritepicto = 0, $notooltip = 0, $save_lastsearch_value = -1) @@ -1690,9 +1714,6 @@ class ActionComm extends CommonObject } $label = $this->label; - if (empty($label)) { - $label = $this->libelle; // For backward compatibility - } $result = ''; @@ -1903,7 +1924,7 @@ class ActionComm extends CommonObject * Existing categories are left untouch. * * @param int[]|int $categories Category or categories IDs - * @return int Return integer <0 if KO, >0 if OK + * @return int<-1,1> Return integer <0 if KO, >0 if OK */ public function setCategories($categories) { @@ -1948,9 +1969,9 @@ class ActionComm extends CommonObject * @param string $type The type of the export 'event' or 'journal' * @param integer $cachedelay Do not rebuild file if date older than cachedelay seconds * @param string $filename The name for the exported file. - * @param array $filters Array of filters. Example array('notolderthan'=>99, 'year'=>..., 'idfrom'=>..., 'notactiontype'=>'systemauto', 'project'=>123, ...) - * @param integer $exportholiday 0 = don't integrate holidays into the export, 1 = integrate holidays into the export - * @return integer -1 = error on build export file, 0 = export okay + * @param array $filters Array of filters. Example array('notolderthan'=>99, 'year'=>..., 'idfrom'=>..., 'notactiontype'=>'systemauto', 'project'=>123, ...) + * @param int<0,1> $exportholiday 0 = don't integrate holidays into the export, 1 = integrate holidays into the export + * @return int<-1,1> -1 = error on build export file, 0 = export okay */ public function build_exportfile($format, $type, $cachedelay, $filename, $filters, $exportholiday = 0) { @@ -2124,7 +2145,7 @@ class ActionComm extends CommonObject $condition = '<>'; } $userforfilter = new User($this->db); - $result = $userforfilter->fetch('', $logina); + $result = $userforfilter->fetch(0, $logina); if ($result > 0) { $sql .= " AND a.fk_user_author ".$condition." ".$userforfilter->id; } elseif ($result < 0 || $condition == '=') { @@ -2139,7 +2160,7 @@ class ActionComm extends CommonObject $condition = '<>'; } $userforfilter = new User($this->db); - $result = $userforfilter->fetch('', $logint); + $result = $userforfilter->fetch(0, $logint); if ($result > 0) { $sql .= " AND ar.fk_element = ".((int) $userforfilter->id); } elseif ($result < 0 || $condition == '=') { @@ -2288,8 +2309,8 @@ class ActionComm extends CommonObject } if (getDolGlobalString('AGENDA_EXPORT_FIX_TZ')) { - $timestampStart = $timestampStart - ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600); - $timestampEnd = $timestampEnd - ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600); + $timestampStart -= ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600); + $timestampEnd -= ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600); } $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); @@ -2395,7 +2416,7 @@ class ActionComm extends CommonObject * Used to build previews or test instances. * id must be 0 if object instance is a specimen. * - * @return int >0 if ok + * @return int<1,1> >0 if ok */ public function initAsSpecimen() { @@ -2486,7 +2507,7 @@ class ActionComm extends CommonObject * @param string $type Type of reminder 'browser' or 'email' * @param int $fk_user Id of user * @param bool $onlypast true = get only past reminder, false = get all reminders linked to this - * @return int 0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK) + * @return int<-1,max> < if OK, else count of number of reminders */ public function loadReminders($type = '', $fk_user = 0, $onlypast = true) { @@ -2547,7 +2568,7 @@ class ActionComm extends CommonObject * Send reminders by emails * CAN BE A CRON TASK * - * @return int 0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK) + * @return int<-1,1>|string 0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK) */ public function sendEmailsReminder() { @@ -2589,6 +2610,7 @@ class ActionComm extends CommonObject if ($resql) { require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; $formmail = new FormMail($this->db); + $to = null; // Ensure 'to' is defined for static analysis while ($obj = $this->db->fetch_object($resql)) { $res = $actionCommReminder->fetch($obj->id); @@ -2721,10 +2743,10 @@ class ActionComm extends CommonObject /** * Update the percent value of a event with the given id * - * @param int $id The id of the event - * @param int $percent The new percent value for the event - * @param int $usermodid The user who modified the percent - * @return int 1 when update of the event was suscessfull, otherwise -1 + * @param int $id The id of the event + * @param int<0,100> $percent The new percent value for the event + * @param int $usermodid The user who modified the percent + * @return int<-1,1> 1 when update of the event was successful, otherwise -1 */ public function updatePercent($id, $percent, $usermodid = 0) { diff --git a/htdocs/comm/action/class/api_agendaevents.class.php b/htdocs/comm/action/class/api_agendaevents.class.php index 6aa5bd090d8..4f1e49d5166 100644 --- a/htdocs/comm/action/class/api_agendaevents.class.php +++ b/htdocs/comm/action/class/api_agendaevents.class.php @@ -84,7 +84,7 @@ class AgendaEvents extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('agenda', $this->actioncomm->id, 'actioncomm', '', 'fk_soc', 'id')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } return $this->_cleanObjectDatas($this->actioncomm); } @@ -204,7 +204,7 @@ class AgendaEvents extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->actioncomm->context['caller'] = $request_data['caller']; + $this->actioncomm->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } @@ -253,7 +253,7 @@ class AgendaEvents extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('actioncomm', $this->actioncomm->id, 'actioncomm', '', 'fk_soc', 'id')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach ($request_data as $field => $value) { if ($field == 'id') { @@ -261,7 +261,7 @@ class AgendaEvents extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->actioncomm->context['caller'] = $request_data['caller']; + $this->actioncomm->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } @@ -304,7 +304,7 @@ class AgendaEvents extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('actioncomm', $this->actioncomm->id, 'actioncomm', '', 'fk_soc', 'id')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if (!$this->actioncomm->delete(DolibarrApiAccess::$user)) { diff --git a/htdocs/comm/action/document.php b/htdocs/comm/action/document.php index ccda6ff5be1..fb8c8dd2417 100644 --- a/htdocs/comm/action/document.php +++ b/htdocs/comm/action/document.php @@ -52,7 +52,6 @@ if ($user->socid) { $socid = $user->socid; } if ($user->socid > 0) { - unset($_GET["action"]); $action = ''; } diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 37d2c7054c1..d1bd15fdc55 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -916,7 +916,6 @@ if ($resql) { $event->type = $obj->type_type; $event->type_picto = $obj->type_picto; - $event->libelle = $obj->label; // deprecated $event->label = $obj->label; $event->percentage = $obj->percent; @@ -2166,17 +2165,15 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa // Show title $titletoshow = $daterange; - $titletoshow .= ($titletoshow ? ' ' : '').dol_escape_htmltag($event->label ? $event->label : $event->libelle); + $titletoshow .= ($titletoshow ? ' ' : '').dol_escape_htmltag($event->label); if ($event->type_code != 'ICALEVENT') { - $savlabel = $event->label ? $event->label : $event->libelle; + $savlabel = $event->label; $event->label = $titletoshow; - $event->libelle = $titletoshow; // deprecatd // Note: List of users are inside $event->userassigned. Link may be clickable depending on permissions of user. $titletoshow = (($event->type_picto || $event->type_code) ? $event->getTypePicto() : ''); $titletoshow .= $event->getNomUrl(0, $maxnbofchar, 'cal_event cal_event_title valignmiddle', '', 0, 0); // do not add 'inline-block' in css here: it makes the title transformed completely into '...' $event->label = $savlabel; - $event->libelle = $savlabel; } // Loop on each assigned user diff --git a/htdocs/comm/action/list.php b/htdocs/comm/action/list.php index 106be0c0b25..92ff8ff8450 100644 --- a/htdocs/comm/action/list.php +++ b/htdocs/comm/action/list.php @@ -1084,8 +1084,8 @@ while ($i < $imaxinloop) { // Description if (!empty($arrayfields['a.note']['checked'])) { - print ''; $text = dolGetFirstLineOfText(dol_string_nohtmltag($actionstatic->note_private, 1)); + print ''; print $form->textwithtooltip(dol_trunc($text, 48), $actionstatic->note_private); print ''; } diff --git a/htdocs/comm/action/peruser.php b/htdocs/comm/action/peruser.php index 97098383652..3daeca53c6e 100644 --- a/htdocs/comm/action/peruser.php +++ b/htdocs/comm/action/peruser.php @@ -99,10 +99,10 @@ if (!$user->hasRight('agenda', 'allactions', 'read') || $filter == 'mine') { // $mode = 'show_peruser'; $resourceid = GETPOSTINT("search_resourceid") ? GETPOSTINT("search_resourceid") : GETPOSTINT("resourceid"); -$year = GETPOSTINT("year") ? GETPOSTINT("year") : date("Y"); -$month = GETPOSTINT("month") ? GETPOSTINT("month") : date("m"); -$week = GETPOSTINT("week") ? GETPOSTINT("week") : date("W"); -$day = GETPOSTINT("day") ? GETPOSTINT("day") : date("d"); +$year = GETPOSTINT("year") ? GETPOSTINT("year") : idate("Y"); +$month = GETPOSTINT("month") ? GETPOSTINT("month") : idate("m"); +$week = GETPOSTINT("week") ? GETPOSTINT("week") : idate("W"); +$day = GETPOSTINT("day") ? GETPOSTINT("day") : idate("d"); $pid = GETPOSTISSET("search_projectid") ? GETPOSTINT("search_projectid", 3) : GETPOSTINT("projectid", 3); $status = GETPOSTISSET("search_status") ? GETPOST("search_status", 'aZ09') : GETPOST("status", 'aZ09'); // status may be 0, 50, 100, 'todo', 'na' or -1 $type = GETPOSTISSET("search_type") ? GETPOST("search_type", 'alpha') : GETPOST("type", 'alpha'); @@ -170,12 +170,12 @@ if (GETPOST('viewcal', 'alpha') && $mode != 'show_day' && $mode != 'show_week' & } // View by month if (GETPOST('viewweek', 'alpha') || $mode == 'show_week') { $mode = 'show_week'; - $week = ($week ? $week : date("W")); - $day = ($day ? $day : date("d")); + $week = ($week ? $week : idate("W")); + $day = ($day ? $day : idate("d")); } // View by week if (GETPOST('viewday', 'alpha') || $mode == 'show_day') { $mode = 'show_day'; - $day = ($day ? $day : date("d")); + $day = ($day ? $day : idate("d")); } // View by day $object = new ActionComm($db); @@ -257,7 +257,7 @@ $next_year = $next['year']; $next_month = $next['month']; $next_day = $next['day']; -$max_day_in_month = date("t", dol_mktime(0, 0, 0, $month, 1, $year)); +$max_day_in_month = idate("t", dol_mktime(0, 0, 0, $month, 1, $year)); $tmpday = $first_day; //print 'xx'.$prev_year.'-'.$prev_month.'-'.$prev_day; @@ -313,16 +313,16 @@ if ($mode != 'show_peruser') { $param .= '&mode='.urlencode($mode); } if ($begin_h != '') { - $param .= '&begin_h='.urlencode($begin_h); + $param .= '&begin_h='.((int) $begin_h); } if ($end_h != '') { - $param .= '&end_h='.urlencode($end_h); + $param .= '&end_h='.((int) $end_h); } if ($begin_d != '') { - $param .= '&begin_d='.urlencode($begin_d); + $param .= '&begin_d='.((int) $begin_d); } if ($end_d != '') { - $param .= '&end_d='.urlencode($end_d); + $param .= '&end_d='.((int) $end_d); } if ($search_categ_cus != 0) { $param .= '&search_categ_cus='.urlencode((string) ($search_categ_cus)); @@ -358,7 +358,7 @@ $lastdaytoshow = dol_time_plus_duree($firstdaytoshow, $nb_weeks_to_show, 'd'); //print dol_print_date($firstdaytoshow, 'dayhour', 'gmt'); //print dol_print_date($lastdaytoshow,'dayhour', 'gmt'); -$max_day_in_month = date("t", dol_mktime(0, 0, 0, $month, 1, $year, 'gmt')); +$max_day_in_month = idate("t", dol_mktime(0, 0, 0, $month, 1, $year, 'gmt')); $tmpday = $first_day; $picto = 'calendarweek'; @@ -482,18 +482,18 @@ $newcardbutton = ''; if ($user->hasRight('agenda', 'myactions', 'create') || $user->hasRight('agenda', 'allactions', 'create')) { $tmpforcreatebutton = dol_getdate(dol_now(), true); - $newparam .= '&month='.urlencode(str_pad($month, 2, "0", STR_PAD_LEFT)).'&year='.urlencode($tmpforcreatebutton['year']); + $newparam .= '&month='.urlencode(str_pad((string) $month, 2, "0", STR_PAD_LEFT)).'&year='.((int) $tmpforcreatebutton['year']); if ($begin_h !== '') { - $newparam .= '&begin_h='.urlencode($begin_h); + $newparam .= '&begin_h='.((int) $begin_h); } if ($end_h !== '') { - $newparam .= '&end_h='.urlencode($end_h); + $newparam .= '&end_h='.((int) $end_h); } if ($begin_d !== '') { - $newparam .= '&begin_d='.urlencode($begin_d); + $newparam .= '&begin_d='.((int) $begin_d); } if ($end_d !== '') { - $newparam .= '&end_d='.urlencode($end_d); + $newparam .= '&end_d='.((int) $end_d); } $urltocreateaction = DOL_URL_ROOT.'/comm/action/card.php?action=create'; diff --git a/htdocs/comm/index.php b/htdocs/comm/index.php index 77f0c7ea647..4b7aa0ca172 100644 --- a/htdocs/comm/index.php +++ b/htdocs/comm/index.php @@ -422,6 +422,8 @@ if (isModEnabled('order') && $user->hasRight('commande', 'lire')) { */ if ((isModEnabled("fournisseur") && !getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD') && $user->hasRight("fournisseur", "commande", "lire")) || (isModEnabled("supplier_order") && $user->hasRight("supplier_order", "lire"))) { + $supplierorderstatic = new CommandeFournisseur($db); + $sql = "SELECT cf.rowid, cf.ref, cf.ref_supplier, cf.total_ht, cf.total_tva, cf.total_ttc, cf.fk_statut as status"; $sql .= ", s.rowid as socid, s.nom as name, s.name_alias"; $sql .= ", s.code_client, s.code_compta, s.client"; @@ -639,7 +641,7 @@ if (isModEnabled("societe") && $user->hasRight('societe', 'lire')) { } $num = $db->num_rows($resql); - startSimpleTable($langs->trans($header, min($max, $num)), "societe/list.php", "type=p,c", 1); + startSimpleTable($langs->trans($header, min($max, $num)), "societe/list.php", "type=p,c&sortfield=s.tms&sortorder=DESC", 1, -1, 'company'); if ($num) { $i = 0; diff --git a/htdocs/comm/mailing/card.php b/htdocs/comm/mailing/card.php index 8a876bda03c..a3d84f89d64 100644 --- a/htdocs/comm/mailing/card.php +++ b/htdocs/comm/mailing/card.php @@ -972,7 +972,7 @@ if ($action == 'create') { if (getDolGlobalString('MAILING_SMTP_SETUP_EMAILS_FOR_QUESTIONS')) { setEventMessages($langs->trans("MailSendSetupIs3", getDolGlobalString('MAILING_SMTP_SETUP_EMAILS_FOR_QUESTIONS')), null, 'warnings'); } - $_GET["action"] = ''; + $action = ''; } elseif (getDolGlobalInt('MAILING_LIMIT_SENDBYWEB') < 0) { if (getDolGlobalString('MAILING_LIMIT_WARNING_PHPMAIL') && $sendingmode == 'mail') { setEventMessages($langs->transnoentitiesnoconv($conf->global->MAILING_LIMIT_WARNING_PHPMAIL), null, 'warnings'); @@ -987,7 +987,7 @@ if ($action == 'create') { if ($conf->file->mailing_limit_sendbyweb != '-1') { // MAILING_LIMIT_SENDBYWEB was set to -1 in database, but it is allowed to increase it. setEventMessages($langs->trans("MailingNeedCommand2"), null, 'warnings'); // You can send online with constant... } - $_GET["action"] = ''; + $action = ''; } else { if (getDolGlobalString('MAILING_LIMIT_WARNING_PHPMAIL') && $sendingmode == 'mail') { setEventMessages($langs->transnoentitiesnoconv($conf->global->MAILING_LIMIT_WARNING_PHPMAIL), null, 'warnings'); diff --git a/htdocs/comm/mailing/index.php b/htdocs/comm/mailing/index.php index 8fee4a7935f..5b1b092fdd3 100644 --- a/htdocs/comm/mailing/index.php +++ b/htdocs/comm/mailing/index.php @@ -3,6 +3,7 @@ * Copyright (C) 2005-2009 Laurent Destailleur * Copyright (C) 2010 Regis Houssin * Copyright (C) 2019 Nicolas ZABOURI + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -101,6 +102,7 @@ if (is_resource($handle)) { $classname = "mailing_".$modulename; require_once $file; $mailmodule = new $classname($db); + '@phan-var-force MailingTargets $mailmodule'; $qualified = 1; foreach ($mailmodule->require_module as $key) { diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 8044e284b73..af70409a70a 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -552,9 +552,9 @@ if (empty($reshook)) { $object->origin_id = $originid; // Possibility to add external linked objects with hooks - $object->linked_objects [$object->origin] = $object->origin_id; - if (is_array($_POST['other_linked_objects']) && !empty($_POST['other_linked_objects'])) { - $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']); + $object->linked_objects[$object->origin] = $object->origin_id; + if (GETPOSTISARRAY('other_linked_objects')) { + $object->linked_objects = array_merge($object->linked_objects, GETPOST('other_linked_objects', 'array:int')); } $id = $object->create($user); diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php index 546d40d052d..94a8647974f 100644 --- a/htdocs/comm/propal/class/api_proposals.class.php +++ b/htdocs/comm/propal/class/api_proposals.class.php @@ -132,7 +132,7 @@ class Proposals extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } // Add external contacts ids. @@ -156,14 +156,12 @@ class Proposals extends DolibarrApi * @param int $limit Limit for list * @param int $page Page number * @param string $thirdparty_ids Thirdparty ids to filter commercial proposals (example '1' or '1,2,3') {@pattern /^[0-9,]*$/i} - * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.datec:<:'20160101')" + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.datec:<:'2016-01-01')" * @param string $properties Restrict the data returned to these properties. Ignored if empty. Comma separated list of properties names * @return array Array of order objects */ public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '', $properties = '') { - global $db, $conf; - if (!DolibarrApiAccess::$user->hasRight('propal', 'lire')) { throw new RestException(403); } @@ -257,11 +255,11 @@ class Proposals extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->propal->context['caller'] = $request_data['caller']; + $this->propal->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->propal->$field = $value; + $this->propal->$field = $this->_checkValForAPI($field, $value, $this->propal); } /*if (isset($request_data["lines"])) { $lines = array(); @@ -299,7 +297,7 @@ class Proposals extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $sql = ''; @@ -341,7 +339,7 @@ class Proposals extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $request_data = (object) $request_data; @@ -407,7 +405,7 @@ class Proposals extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $errors = []; @@ -488,7 +486,7 @@ class Proposals extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $request_data = (object) $request_data; @@ -566,7 +564,7 @@ class Proposals extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $updateRes = $this->propal->deleteLine($lineid, $id); @@ -607,7 +605,7 @@ class Proposals extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->propal->add_contact($contactid, $type, 'external'); @@ -651,7 +649,7 @@ class Proposals extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $contacts = $this->propal->liste_contact(); @@ -688,7 +686,7 @@ class Proposals extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach ($request_data as $field => $value) { if ($field == 'id') { @@ -696,11 +694,17 @@ class Proposals extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->propal->context['caller'] = $request_data['caller']; + $this->propal->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); + continue; + } + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->propal->array_options[$index] = $this->_checkValForAPI($field, $val, $this->propal); + } continue; } - $this->propal->$field = $value; + $this->propal->$field = $this->_checkValForAPI($field, $value, $this->propal); } // update end of validity date @@ -737,7 +741,7 @@ class Proposals extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if (!$this->propal->delete(DolibarrApiAccess::$user)) { @@ -771,7 +775,7 @@ class Proposals extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->propal->setDraft(DolibarrApiAccess::$user); @@ -788,7 +792,7 @@ class Proposals extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->propal->fetchObjectLinked(); @@ -827,7 +831,7 @@ class Proposals extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->propal->valid(DolibarrApiAccess::$user, $notrigger); @@ -844,7 +848,7 @@ class Proposals extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->propal->fetchObjectLinked(); @@ -874,7 +878,7 @@ class Proposals extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->propal->closeProposal(DolibarrApiAccess::$user, $status, $note_private, $notrigger); @@ -891,7 +895,7 @@ class Proposals extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->propal->fetchObjectLinked(); @@ -918,7 +922,7 @@ class Proposals extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->propal->classifyBilled(DolibarrApiAccess::$user); @@ -932,7 +936,7 @@ class Proposals extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->propal->fetchObjectLinked(); diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 35e268885b8..8e875f598ac 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -130,7 +130,7 @@ class Propal extends CommonObject public $ref_customer; /** - * @var Propal oldcopy with propal properties + * @var static oldcopy with propal properties */ public $oldcopy; @@ -4012,10 +4012,13 @@ class PropaleLigne extends CommonObjectLine public $marge_tx; public $marque_tx; + /** + * 1: frais de port + * 2: ecotaxe + * 3: option line (when qty = 0) + * @var int special code + */ public $special_code; // Tag for special lines (exclusive tags) - // 1: frais de port - // 2: ecotaxe - // 3: option line (when qty = 0) public $info_bits = 0; // Some other info: // Bit 0: 0 si TVA normal - 1 if TVA NPR diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index 117511e1f87..1769bafaaad 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -15,7 +15,7 @@ * Copyright (C) 2018 Nicolas ZABOURI * Copyright (C) 2019-2021 Alexandre Spangaro * Copyright (C) 2021 Anthony Berton - * Copyright (C) 2021 Frédéric France + * Copyright (C) 2021-2024 Frédéric France * Copyright (C) 2022 Josep Lluís Amador * Copyright (C) 2024 MDW * @@ -2166,7 +2166,7 @@ while ($i < $imaxinloop) { $userstatic->lastname = $obj->lastname; $userstatic->firstname = $obj->firstname; $userstatic->email = $obj->user_email; - $userstatic->statut = $obj->user_statut; + $userstatic->status = $obj->user_statut; $userstatic->entity = $obj->user_entity; $userstatic->photo = $obj->photo; $userstatic->office_phone = $obj->office_phone; @@ -2207,7 +2207,7 @@ while ($i < $imaxinloop) { $userstatic->lastname = $val['lastname']; $userstatic->firstname = $val['firstname']; $userstatic->email = $val['email']; - $userstatic->statut = $val['statut']; + $userstatic->status = $val['statut']; $userstatic->entity = $val['entity']; $userstatic->photo = $val['photo']; $userstatic->login = $val['login']; diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index d70dab85cb7..7256ee8e790 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -128,7 +128,7 @@ class Orders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } // Add external contacts ids @@ -273,11 +273,11 @@ class Orders extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->commande->context['caller'] = $request_data['caller']; + $this->commande->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->commande->$field = $value; + $this->commande->$field = $this->_checkValForAPI($field, $value, $this->commande); } /*if (isset($request_data["lines"])) { $lines = array(); @@ -315,7 +315,7 @@ class Orders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->commande->getLinesArray(); $result = array(); @@ -347,7 +347,7 @@ class Orders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $request_data = (object) $request_data; @@ -414,7 +414,7 @@ class Orders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $request_data = (object) $request_data; @@ -482,7 +482,7 @@ class Orders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $updateRes = $this->commande->deleteLine(DolibarrApiAccess::$user, $lineid, $id); @@ -518,7 +518,7 @@ class Orders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $contacts = $this->commande->liste_contact(-1, 'external', 0, $type); @@ -551,7 +551,7 @@ class Orders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->commande->add_contact($contactid, $type, 'external'); @@ -599,7 +599,7 @@ class Orders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $contacts = $this->commande->liste_contact(); @@ -641,7 +641,7 @@ class Orders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach ($request_data as $field => $value) { if ($field == 'id') { @@ -649,11 +649,17 @@ class Orders extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->commande->context['caller'] = $request_data['caller']; + $this->commande->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); + continue; + } + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->commande->array_options[$index] = $this->_checkValForAPI($field, $val, $this->commande); + } continue; } - $this->commande->$field = $value; + $this->commande->$field = $this->_checkValForAPI($field, $value, $this->commande); } // Update availability @@ -687,7 +693,7 @@ class Orders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if (!$this->commande->delete(DolibarrApiAccess::$user)) { @@ -737,7 +743,7 @@ class Orders extends DolibarrApi $result = $this->commande->fetch_thirdparty(); // do not check result, as failure is not fatal (used only for mail notification substitutes) if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->commande->valid(DolibarrApiAccess::$user, $idwarehouse, $notrigger); @@ -835,7 +841,7 @@ class Orders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->commande->fetchObjectLinked(); @@ -863,7 +869,7 @@ class Orders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->commande->cloture(DolibarrApiAccess::$user, $notrigger); @@ -880,7 +886,7 @@ class Orders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->commande->fetchObjectLinked(); @@ -908,7 +914,7 @@ class Orders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->commande->setDraft(DolibarrApiAccess::$user, $idwarehouse); @@ -925,7 +931,7 @@ class Orders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->commande->fetchObjectLinked(); diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index ac6213ed0b7..05e3e590183 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -6,7 +6,7 @@ * Copyright (C) 2012 Juanjo Menent * Copyright (C) 2013 Christophe Battarel * Copyright (C) 2013 Cédric Salvador - * Copyright (C) 2015-2018 Frédéric France + * Copyright (C) 2015-2024 Frédéric France * Copyright (C) 2015 Marcos García * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2016-2023 Ferran Marcet @@ -496,6 +496,7 @@ if (empty($reshook)) { $rang = ($nbOrders > 1) ? -1 : $lines[$i]->rang; //there may already be rows from previous orders if (!empty($createbills_onebythird)) { + $TFactThirdNbLines[$cmd->socid]++; $rang = $TFactThirdNbLines[$cmd->socid]; } @@ -531,9 +532,6 @@ if (empty($reshook)) { ); if ($result > 0) { $lineid = $result; - if (!empty($createbills_onebythird)) { //increment rang to keep order - $TFactThirdNbLines[$cmd->socid]++; - } } else { $lineid = 0; $error++; @@ -682,8 +680,8 @@ if (empty($reshook)) { $db->rollback(); $action = 'create'; - $_GET["origin"] = $_POST["origin"]; - $_GET["originid"] = $_POST["originid"]; + $_GET["origin"] = $_POST["origin"]; // Keep GET and POST here ? + $_GET["originid"] = $_POST["originid"]; // Keep GET and POST here ? if (!empty($errors)) { setEventMessages(null, $errors, 'errors'); } else { @@ -1734,14 +1732,6 @@ if (!empty($arrayfields['total_mark_rate']['checked'])) { print ''; } -// Extra fields -include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; - -// Fields from hook -$parameters = array('arrayfields' => $arrayfields); -$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object, $action); // Note that $action and $object may have been modified by hook -print $hookmanager->resPrint; - // Date creation if (!empty($arrayfields['c.datec']['checked'])) { print ''; @@ -1785,17 +1775,28 @@ if (!empty($arrayfields['shippable']['checked'])) { } print ''; } + +// Extra fields +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; + +// Fields from hook +$parameters = array('arrayfields' => $arrayfields); +$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object, $action); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; + // Status billed if (!empty($arrayfields['c.facture']['checked'])) { print ''; print $form->selectyesno('search_billed', $search_billed, 1, 0, 1, 1); print ''; } + // Import key if (!empty($arrayfields['c.import_key']['checked'])) { print ''; print ''; } + // Status if (!empty($arrayfields['c.fk_statut']['checked'])) { print ''; @@ -1970,13 +1971,6 @@ if (!empty($arrayfields['total_mark_rate']['checked'])) { $totalarray['nbfield']++; } -// Extra fields -include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; - -// Hook fields -$parameters = array('arrayfields' => $arrayfields, 'param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder, 'totalarray' => &$totalarray); -$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook -print $hookmanager->resPrint; if (!empty($arrayfields['c.datec']['checked'])) { print_liste_field_titre($arrayfields['c.datec']['label'], $_SERVER["PHP_SELF"], "c.date_creation", "", $param, '', $sortfield, $sortorder, 'center nowrap '); $totalarray['nbfield']++; @@ -2001,6 +1995,14 @@ if (!empty($arrayfields['shippable']['checked'])) { print_liste_field_titre($arrayfields['shippable']['label'], $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'center '); $totalarray['nbfield']++; } +// Extra fields +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; + +// Hook fields +$parameters = array('arrayfields' => $arrayfields, 'param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder, 'totalarray' => &$totalarray); +$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; + if (!empty($arrayfields['c.facture']['checked'])) { print_liste_field_titre($arrayfields['c.facture']['label'], $_SERVER["PHP_SELF"], 'c.facture', '', $param, '', $sortfield, $sortorder, 'center '); $totalarray['nbfield']++; @@ -2503,7 +2505,7 @@ while ($i < $imaxinloop) { $userstatic->lastname = $val['lastname']; $userstatic->firstname = $val['firstname']; $userstatic->email = $val['email']; - $userstatic->statut = $val['statut']; + $userstatic->status = $val['statut']; $userstatic->entity = $val['entity']; $userstatic->photo = $val['photo']; $userstatic->login = $val['login']; @@ -2577,13 +2579,6 @@ while ($i < $imaxinloop) { } } - // Extra fields - include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; - // Fields from hook - $parameters = array('arrayfields' => $arrayfields, 'obj' => $obj, 'i' => $i, 'totalarray' => &$totalarray); - $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - // Date creation if (!empty($arrayfields['c.datec']['checked'])) { print ''; @@ -2740,6 +2735,13 @@ while ($i < $imaxinloop) { } } + // Extra fields + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; + // Fields from hook + $parameters = array('arrayfields' => $arrayfields, 'obj' => $obj, 'i' => $i, 'totalarray' => &$totalarray); + $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + // Billed if (!empty($arrayfields['c.facture']['checked'])) { print ''; diff --git a/htdocs/commande/list_det.php b/htdocs/commande/list_det.php index 0e8f09ed021..bd076d8cccc 100644 --- a/htdocs/commande/list_det.php +++ b/htdocs/commande/list_det.php @@ -6,7 +6,7 @@ * Copyright (C) 2012 Juanjo Menent * Copyright (C) 2013 Christophe Battarel * Copyright (C) 2013 Cédric Salvador - * Copyright (C) 2015-2018 Frédéric France + * Copyright (C) 2015-2024 Frédéric France * Copyright (C) 2015 Marcos García * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2016-2021 Ferran Marcet @@ -1909,7 +1909,7 @@ if ($resql) { $userstatic->lastname = $obj->lastname; $userstatic->firstname = $obj->firstname; $userstatic->email = $obj->user_email; - $userstatic->statut = $obj->user_statut; + $userstatic->status = $obj->user_statut; $userstatic->entity = $obj->entity; $userstatic->photo = $obj->photo; $userstatic->office_phone = $obj->office_phone; @@ -1951,7 +1951,7 @@ if ($resql) { $userstatic->lastname = $val['lastname']; $userstatic->firstname = $val['firstname']; $userstatic->email = $val['email']; - $userstatic->statut = $val['statut']; + $userstatic->status = $val['statut']; $userstatic->entity = $val['entity']; $userstatic->photo = $val['photo']; $userstatic->login = $val['login']; diff --git a/htdocs/compta/accounting-files.php b/htdocs/compta/accounting-files.php index 36b12bf6b36..e20eeed6436 100644 --- a/htdocs/compta/accounting-files.php +++ b/htdocs/compta/accounting-files.php @@ -27,7 +27,7 @@ * \brief Page to show portoflio and files of a thirdparty and download it */ -if ((array_key_exists('action', $_GET) && $_GET['action'] == 'dl') || (array_key_exists('action', $_POST) && $_POST['action'] == 'dl')) { // To not replace token when downloading file +if ((array_key_exists('action', $_GET) && $_GET['action'] == 'dl') || (array_key_exists('action', $_POST) && $_POST['action'] == 'dl')) { // To not replace token when downloading file. Keep $_GET and $_POST here if (!defined('NOTOKENRENEWAL')) { define('NOTOKENRENEWAL', '1'); } diff --git a/htdocs/compta/bank/bankentries_list.php b/htdocs/compta/bank/bankentries_list.php index 82184b9ecb7..8b32d9d9220 100644 --- a/htdocs/compta/bank/bankentries_list.php +++ b/htdocs/compta/bank/bankentries_list.php @@ -87,8 +87,8 @@ $search_dv_end = dol_mktime(0, 0, 0, GETPOSTINT('search_end_dvmonth'), GETPOSTIN $search_thirdparty_user = GETPOST("search_thirdparty", 'alpha') ? GETPOST("search_thirdparty", 'alpha') : GETPOST("thirdparty", 'alpha'); $search_req_nb = GETPOST("req_nb", 'alpha'); $search_num_releve = GETPOST("search_num_releve", 'alpha'); -$search_conciliated = GETPOSTINT("search_conciliated"); -$search_fk_bordereau = GETPOSTINT("search_fk_bordereau"); +$search_conciliated = GETPOST("search_conciliated", 'int'); +$search_fk_bordereau = GETPOST("search_fk_bordereau", 'int'); $optioncss = GETPOST('optioncss', 'alpha'); $toselect = GETPOST('toselect', 'array'); $num_releve = GETPOST("num_releve", "alpha"); @@ -152,7 +152,7 @@ $search_array_options = $extrafields->getOptionalsFromPost('banktransaction', '' $arrayfields = array( 'b.rowid' => array('label' => $langs->trans("Ref"), 'checked' => 1,'position' => 10), 'b.label' => array('label' => $langs->trans("Description"), 'checked' => 1,'position' => 20), - 'b.dateo' => array('label' => $langs->trans("DateOperationShort"), 'checked' => 1,'position' => 30), + 'b.dateo' => array('label' => $langs->trans("DateOperationShort"), 'checked' => -1,'position' => 30), 'b.datev' => array('label' => $langs->trans("DateValueShort"), 'checked' => 1,'position' => 40), 'type' => array('label' => $langs->trans("Type"), 'checked' => 1,'position' => 50), 'b.num_chq' => array('label' => $langs->trans("Numero"), 'checked' => 1,'position' => 60), @@ -1798,7 +1798,8 @@ if ($resql) { if ($objp->num_releve) { print ' '; } - print 'rowid]) ? ' checked' : '').'>'; + $tmparray = GETPOST('rowid', 'array:int'); + print 'rowid]) ? ' checked' : '').'>'; } } print ''; diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index 25b52d8fc1c..60f34320312 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -69,7 +69,7 @@ $extrafields->fetch_name_optionals_label($object->table_element); $hookmanager->initHooks(array('bankcard', 'globalcard')); // Security check -$id = GETPOSTINT("id") ? GETPOSTINT("id") : GETPOSTINT('ref'); +$id = GETPOSTINT("id") ? GETPOSTINT("id") : GETPOST('ref'); $fieldid = GETPOSTINT("id") ? 'rowid' : 'ref'; if (GETPOSTINT("id") || GETPOST("ref")) { @@ -319,11 +319,11 @@ if (empty($reshook)) { $categories = GETPOST('categories', 'array'); $object->setCategories($categories); - $_GET["id"] = GETPOSTINT("id"); // Force chargement page en mode visu + $id = GETPOSTINT("id"); // Force load of this page } else { $error++; setEventMessages($object->error, $object->errors, 'errors'); - $action = 'edit'; // Force chargement page edition + $action = 'edit'; // Force load of page in edit mode } } diff --git a/htdocs/compta/bank/class/api_bankaccounts.class.php b/htdocs/compta/bank/class/api_bankaccounts.class.php index a05b8dfd965..94576ab0ebc 100644 --- a/htdocs/compta/bank/class/api_bankaccounts.class.php +++ b/htdocs/compta/bank/class/api_bankaccounts.class.php @@ -161,7 +161,7 @@ class BankAccounts extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $account->context['caller'] = $request_data['caller']; + $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } @@ -343,7 +343,7 @@ class BankAccounts extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $account->context['caller'] = $request_data['caller']; + $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } diff --git a/htdocs/compta/bank/list.php b/htdocs/compta/bank/list.php index 76a3f8e2abd..12a0dff52ec 100644 --- a/htdocs/compta/bank/list.php +++ b/htdocs/compta/bank/list.php @@ -58,7 +58,7 @@ $mode = GETPOST('mode', 'aZ'); $search_ref = GETPOST('search_ref', 'alpha'); $search_label = GETPOST('search_label', 'alpha'); $search_number = GETPOST('search_number', 'alpha'); -$search_status = GETPOST('search_status') ? GETPOST('search_status', 'alpha') : 'opened'; // 'all' or '' means 'opened' +$search_status = GETPOST('search_status', 'alpha'); $optioncss = GETPOST('optioncss', 'alpha'); $search_category_list = ""; @@ -212,10 +212,10 @@ if (!empty($extrafields->attributes[$object->table_element]['label']) && is_arra $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (b.rowid = ef.fk_object)"; } $sql .= " WHERE b.entity IN (".getEntity('bank_account').")"; -if ($search_status == 'opened') { +if ($search_status === 'opened') { $sql .= " AND clos = 0"; } -if ($search_status == 'closed') { +if ($search_status === 'closed') { $sql .= " AND clos = 1"; } if ($search_ref != '') { @@ -334,7 +334,7 @@ if ($search_label != '') { if ($search_number != '') { $param .= '&search_number='.urlencode($search_number); } -if ($search_status != '') { +if ($search_status != '' && $search_status != '-1') { $param .= '&search_status='.urlencode($search_status); } if ($show_files) { diff --git a/htdocs/compta/bank/treso.php b/htdocs/compta/bank/treso.php index ef683b833af..c43d85e1f60 100644 --- a/htdocs/compta/bank/treso.php +++ b/htdocs/compta/bank/treso.php @@ -85,7 +85,7 @@ if (GETPOST("account") || GETPOST("ref")) { } if (GETPOST("ref")) { $result = $object->fetch(0, GETPOST("ref")); - $_GET["account"] = $object->id; + $id = $object->id; } $title = $object->ref.' - '.$langs->trans("PlannedTransactions"); diff --git a/htdocs/compta/cashcontrol/cashcontrol_card.php b/htdocs/compta/cashcontrol/cashcontrol_card.php index 74cce92938d..b16ed740d01 100644 --- a/htdocs/compta/cashcontrol/cashcontrol_card.php +++ b/htdocs/compta/cashcontrol/cashcontrol_card.php @@ -66,7 +66,7 @@ if (!$sortorder) { $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'thirdpartylist'; if ($contextpage == 'takepos') { - $_GET['optioncss'] = 'print'; + $optioncss = 'print'; } $arrayofpaymentmode = array('cash' => 'Cash', 'cheque' => 'Cheque', 'card' => 'CreditCard'); diff --git a/htdocs/compta/cashcontrol/report.php b/htdocs/compta/cashcontrol/report.php index c59c5be8b34..18c41bc47f9 100644 --- a/htdocs/compta/cashcontrol/report.php +++ b/htdocs/compta/cashcontrol/report.php @@ -37,7 +37,7 @@ if (!defined('NOBROWSERNOTIF')) { define('NOBROWSERNOTIF', '1'); // Disable browser notification } -$_GET['optioncss'] = "print"; +$optioncss = "print"; // Load Dolibarr environment require '../../main.inc.php'; diff --git a/htdocs/compta/clients.php b/htdocs/compta/clients.php index c7963e95090..aa361fa1010 100644 --- a/htdocs/compta/clients.php +++ b/htdocs/compta/clients.php @@ -151,16 +151,16 @@ if ($resql) { print ''; print ''; - print ''; + print ''; print ' '; print ''; - print ''; + print ''; print ''; print ''; - print ''; + print ''; print ''; print ''; diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index a847b7ca292..f13654b0a31 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -1547,8 +1547,8 @@ if (empty($reshook)) { } } - if (is_array($_POST['other_linked_objects']) && !empty($_POST['other_linked_objects'])) { - $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']); + if (GETPOSTISARRAY('other_linked_objects')) { + $object->linked_objects = array_merge($object->linked_objects, GETPOST('other_linked_objects', 'array:int')); } $id = $object->create($user); // This include class to add_object_linked() and add add_contact() @@ -2080,8 +2080,8 @@ if (empty($reshook)) { } else { $db->rollback(); $action = 'create'; - $_GET["origin"] = $_POST["origin"]; - $_GET["originid"] = $_POST["originid"]; + $_GET["origin"] = $_POST["origin"]; // Keep GET and POST here ? + $_GET["originid"] = $_POST["originid"]; // Keep GET and POST here ? setEventMessages($object->error, $object->errors, 'errors'); } } elseif ($action == 'addline' && GETPOST('submitforalllines', 'alpha') && GETPOST('vatforalllines', 'alpha') !== '') { diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php index 40abcfbca07..80126d347b6 100644 --- a/htdocs/compta/facture/class/api_invoices.class.php +++ b/htdocs/compta/facture/class/api_invoices.class.php @@ -146,7 +146,7 @@ class Invoices extends DolibarrApi $this->invoice->remaintopay = price2num($this->invoice->total_ttc - $this->invoice->totalpaid - $this->invoice->totalcreditnotes - $this->invoice->totaldeposits, 'MT'); if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } // Add external contacts ids @@ -300,11 +300,11 @@ class Invoices extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->invoice->context['caller'] = $request_data['caller']; + $this->invoice->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->invoice->$field = $value; + $this->invoice->$field = $this->_checkValForAPI($field, $value, $this->invoice); } if (!array_key_exists('date', $request_data)) { $this->invoice->date = dol_now(); @@ -426,7 +426,7 @@ class Invoices extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->invoice->getLinesArray(); $result = array(); @@ -462,7 +462,7 @@ class Invoices extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $request_data = (object) $request_data; @@ -538,7 +538,7 @@ class Invoices extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('invoice', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->invoice->add_contact($contactid, $type, 'external'); @@ -582,7 +582,7 @@ class Invoices extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('invoice', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $contacts = $this->invoice->liste_contact(); @@ -624,7 +624,7 @@ class Invoices extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('facture', $id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->invoice->fetch($id); @@ -659,7 +659,7 @@ class Invoices extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach ($request_data as $field => $value) { @@ -668,11 +668,17 @@ class Invoices extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->invoice->context['caller'] = $request_data['caller']; + $this->invoice->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); + continue; + } + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->invoice->array_options[$index] = $this->_checkValForAPI($field, $val, $this->invoice); + } continue; } - $this->invoice->$field = $value; + $this->invoice->$field = $this->_checkValForAPI($field, $value, $this->invoice); // If cond reglement => update date lim reglement if ($field == 'cond_reglement_id') { @@ -711,7 +717,7 @@ class Invoices extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->invoice->delete(DolibarrApiAccess::$user); @@ -764,7 +770,7 @@ class Invoices extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $request_data = (object) $request_data; @@ -851,7 +857,7 @@ class Invoices extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->invoice->add_contact($fk_socpeople, $type_contact, $source, $notrigger); @@ -865,7 +871,7 @@ class Invoices extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } return $this->_cleanObjectDatas($this->invoice); @@ -899,7 +905,7 @@ class Invoices extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->invoice->setDraft(DolibarrApiAccess::$user, $idwarehouse); @@ -916,7 +922,7 @@ class Invoices extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } return $this->_cleanObjectDatas($this->invoice); @@ -951,7 +957,7 @@ class Invoices extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->invoice->validate(DolibarrApiAccess::$user, $force_number, $idwarehouse, $notrigger); @@ -968,7 +974,7 @@ class Invoices extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } // copy from order @@ -1004,7 +1010,7 @@ class Invoices extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->invoice->setPaid(DolibarrApiAccess::$user, $close_code, $close_note); @@ -1022,7 +1028,7 @@ class Invoices extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } return $this->_cleanObjectDatas($this->invoice); @@ -1053,7 +1059,7 @@ class Invoices extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->invoice->setUnpaid(DolibarrApiAccess::$user); @@ -1071,7 +1077,7 @@ class Invoices extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } return $this->_cleanObjectDatas($this->invoice); @@ -1099,7 +1105,7 @@ class Invoices extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $discountcheck = new DiscountAbsolute($this->db); @@ -1142,7 +1148,7 @@ class Invoices extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if ($this->invoice->paye) { @@ -1313,7 +1319,7 @@ class Invoices extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('facture', $id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->invoice->fetch($id); @@ -1360,7 +1366,7 @@ class Invoices extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('facture', $id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $discount = new DiscountAbsolute($this->db); $result = $discount->fetch($discountid); @@ -1399,7 +1405,7 @@ class Invoices extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('facture', $id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->invoice->fetch($id); @@ -1811,7 +1817,7 @@ class Invoices extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('facturerec', $this->template_invoice->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } // Add external contacts ids diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index 1ed0209e4b0..09ee7806eed 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -129,6 +129,10 @@ class FactureRec extends CommonInvoice public $unit_frequency; public $rang; + + /** + * @var int special code + */ public $special_code; public $usenewprice = 0; @@ -1387,16 +1391,6 @@ class FactureRec extends CommonInvoice $error++; } } - if (!$error && !$notrigger) { - // Call trigger - $result = $facturerec->call_trigger('BILLREC_CREATEBILL', $user); - if ($result < 0) { - $this->errors = $facturerec->errors; - $this->error = $facturerec->error; - $error++; - } - // End call triggers - } } else { $error++; $this->error = "Failed to load invoice template with id=".$line->rowid.", entity=".$conf->entity."\n"; diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index e5ef7421291..883019bddc8 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -221,7 +221,7 @@ class Facture extends CommonInvoice public $tab_next_situation_invoice = array(); /** - * @var Facture object oldcopy + * @var static object oldcopy */ public $oldcopy; @@ -1090,7 +1090,6 @@ class Facture extends CommonInvoice if ($result < 0) { $error++; } - // End call triggers } if (!$error) { @@ -3952,8 +3951,8 @@ class Facture extends CommonInvoice $this->line->tva_tx = $txtva; $this->line->localtax1_tx = ($total_localtax1 ? $localtaxes_type[1] : 0); $this->line->localtax2_tx = ($total_localtax2 ? $localtaxes_type[3] : 0); - $this->line->localtax1_type = empty($localtaxes_type[0]) ? '' : $localtaxes_type[0]; - $this->line->localtax2_type = empty($localtaxes_type[2]) ? '' : $localtaxes_type[2]; + $this->line->localtax1_type = empty($localtaxes_type[0]) ? 0 : $localtaxes_type[0]; + $this->line->localtax2_type = empty($localtaxes_type[2]) ? 0 : $localtaxes_type[2]; $this->line->total_ht = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_ht) : $total_ht); // For credit note and if qty is negative, total is negative $this->line->total_ttc = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_ttc) : $total_ttc); // For credit note and if qty is negative, total is negative @@ -4212,8 +4211,8 @@ class Facture extends CommonInvoice $this->line->tva_tx = $txtva; $this->line->localtax1_tx = $txlocaltax1; $this->line->localtax2_tx = $txlocaltax2; - $this->line->localtax1_type = empty($localtaxes_type[0]) ? '' : $localtaxes_type[0]; - $this->line->localtax2_type = empty($localtaxes_type[2]) ? '' : $localtaxes_type[2]; + $this->line->localtax1_type = empty($localtaxes_type[0]) ? 0 : $localtaxes_type[0]; + $this->line->localtax2_type = empty($localtaxes_type[2]) ? 0 : $localtaxes_type[2]; $this->line->remise_percent = $remise_percent; $this->line->subprice = ($this->type == self::TYPE_CREDIT_NOTE ? -abs($pu_ht) : $pu_ht); // For credit note, unit price always negative, always positive otherwise @@ -4635,6 +4634,7 @@ class Facture extends CommonInvoice } $obj = new $classname(); + '@phan-var-force CommonNumRefGenerator $obj'; $numref = $obj->getNextValue($soc, $this, $mode); @@ -6553,7 +6553,7 @@ class FactureLigne extends CommonInvoiceLine $sql .= ", date_end=".(!empty($this->date_end) ? "'".$this->db->idate($this->date_end)."'" : "null"); $sql .= ", product_type=".$this->product_type; $sql .= ", info_bits='".$this->db->escape($this->info_bits)."'"; - $sql .= ", special_code='".$this->db->escape($this->special_code)."'"; + $sql .= ", special_code=" . (int) $this->special_code; if (empty($this->skip_update_total)) { $sql .= ", total_ht=".price2num($this->total_ht); $sql .= ", total_tva=".price2num($this->total_tva); diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 645737d1f7f..a6da251aa7c 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -17,6 +17,7 @@ * Copyright (C) 2023 Nick Fragoulis * Copyright (C) 2023 Joachim Kueter * Copyright (C) 2024 MDW + * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -144,8 +145,6 @@ $search_datelimit_end = dol_mktime(23, 59, 59, $search_datelimit_endmonth, $sear $search_categ_cus = GETPOSTINT("search_categ_cus"); $search_product_category = GETPOSTINT('search_product_category'); $search_fac_rec_source_title = GETPOST("search_fac_rec_source_title", 'alpha'); -$search_btn = GETPOST('button_search', 'alpha'); -$search_remove_btn = GETPOST('button_removefilter', 'alpha'); $search_late = GETPOST('search_late'); if ($search_late == 'late') { @@ -2421,7 +2420,6 @@ if ($num > 0) { $userstatic->lastname = $obj->lastname; $userstatic->firstname = $obj->firstname; $userstatic->email = $obj->user_email; - $userstatic->statut = $obj->user_statut; // deprecated $userstatic->status = $obj->user_statut; $userstatic->entity = $obj->entity; $userstatic->photo = $obj->photo; @@ -2464,7 +2462,6 @@ if ($num > 0) { $userstatic->lastname = $val['lastname']; $userstatic->firstname = $val['firstname']; $userstatic->email = $val['email']; - $userstatic->statut = $val['statut']; // deprecated $userstatic->status = $val['statut']; $userstatic->entity = $val['entity']; $userstatic->photo = $val['photo']; diff --git a/htdocs/compta/facture/prelevement.php b/htdocs/compta/facture/prelevement.php index 2371f6ff59a..0b0b394ace7 100644 --- a/htdocs/compta/facture/prelevement.php +++ b/htdocs/compta/facture/prelevement.php @@ -6,6 +6,7 @@ * Copyright (C) 2010-2014 Juanjo Menent * Copyright (C) 2017 Ferran Marcet * Copyright (C) 2018-2024 Frédéric France + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -64,7 +65,7 @@ if ($type == 'bank-transfer') { // Load object if ($id > 0 || !empty($ref)) { $ret = $object->fetch($id, $ref); - $isdraft = (($object->statut == FactureFournisseur::STATUS_DRAFT) ? 1 : 0); + $isdraft = (($object->status == FactureFournisseur::STATUS_DRAFT) ? 1 : 0); if ($ret > 0) { $object->fetch_thirdparty(); } @@ -146,7 +147,7 @@ if (empty($reshook)) { } else { // We refresh object data $ret = $object->fetch($id, $ref); - $isdraft = (($object->statut == Facture::STATUS_DRAFT) ? 1 : 0); + $isdraft = (($object->status == Facture::STATUS_DRAFT) ? 1 : 0); if ($ret > 0) { $object->fetch_thirdparty(); } @@ -161,7 +162,7 @@ if (empty($reshook)) { } else { // We refresh object data $ret = $object->fetch($id, $ref); - $isdraft = (($object->statut == FactureFournisseur::STATUS_DRAFT) ? 1 : 0); + $isdraft = (($object->status == FactureFournisseur::STATUS_DRAFT) ? 1 : 0); if ($ret > 0) { $object->fetch_thirdparty(); } @@ -280,7 +281,7 @@ if ($object->id > 0) { //$resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT); $resteapayer = price2num($object->total_ttc - $totalpaid - $totalcreditnotes - $totaldeposits, 'MT'); - if ($object->paye) { + if ($object->paid) { $resteapayer = 0; } $resteapayeraffiche = $resteapayer; @@ -755,7 +756,7 @@ if ($object->id > 0) { } // Add a transfer request - if ($object->statut > $object::STATUS_DRAFT && $object->paye == 0 && $num == 0) { + if ($object->status > $object::STATUS_DRAFT && $object->paid == 0 && $num == 0) { if ($resteapayer > 0) { if ($user_perms) { $remaintopaylesspendingdebit = $resteapayer - $pending; @@ -794,7 +795,7 @@ if ($object->id > 0) { } } else { if ($num == 0) { - if ($object->statut > $object::STATUS_DRAFT) { + if ($object->status > $object::STATUS_DRAFT) { print ''.$buttonlabel.''; } else { print ''.$buttonlabel.''; diff --git a/htdocs/compta/index.php b/htdocs/compta/index.php index 59fae4217d6..0d20375bcb5 100644 --- a/htdocs/compta/index.php +++ b/htdocs/compta/index.php @@ -11,6 +11,7 @@ * Copyright (C) 2020 Josep Lluís Amador * Copyright (C) 2021-2024 Frédéric France * Copyright (C) 2024 Rafael San José + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -339,7 +340,9 @@ if ((isModEnabled('fournisseur') && !getDolGlobalString('MAIN_USE_NEW_SUPPLIERMO $facstatic->total_tva = $obj->total_tva; $facstatic->total_ttc = $obj->total_ttc; $facstatic->statut = $obj->status; + $facstatic->status = $obj->status; $facstatic->paye = $obj->paye; + $facstatic->paid = $obj->paye; $facstatic->type = $obj->type; $facstatic->ref_supplier = $obj->ref_supplier; diff --git a/htdocs/compta/localtax/card.php b/htdocs/compta/localtax/card.php index e302bcc2ee1..9b3ec6e2544 100644 --- a/htdocs/compta/localtax/card.php +++ b/htdocs/compta/localtax/card.php @@ -87,7 +87,7 @@ if ($action == 'add' && !$cancel) { } else { $db->rollback(); setEventMessages($object->error, $object->errors, 'errors'); - $_GET["action"] = "create"; + $action = "create"; } } diff --git a/htdocs/compta/paiement/card.php b/htdocs/compta/paiement/card.php index 535d07b84dd..2d55dc4f84e 100644 --- a/htdocs/compta/paiement/card.php +++ b/htdocs/compta/paiement/card.php @@ -288,8 +288,8 @@ if ($action == 'delete') { // Confirmation of payment validation if ($action == 'valide') { - $facid = $_GET['facid']; - print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id.'&facid='.$facid, $langs->trans("ValidatePayment"), $langs->trans("ConfirmValidatePayment"), 'confirm_validate', '', 0, 2); + $facid = GETPOSTINT('facid'); + print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id.'&facid='.((int) $facid), $langs->trans("ValidatePayment"), $langs->trans("ConfirmValidatePayment"), 'confirm_validate', '', 0, 2); } $linkback = ''.$langs->trans("BackToList").''; diff --git a/htdocs/compta/paiement/cheque/class/remisecheque.class.php b/htdocs/compta/paiement/cheque/class/remisecheque.class.php index 71496b46c6f..70274fd13c3 100644 --- a/htdocs/compta/paiement/cheque/class/remisecheque.class.php +++ b/htdocs/compta/paiement/cheque/class/remisecheque.class.php @@ -450,6 +450,7 @@ class RemiseCheque extends CommonObject } $obj = new $classname(); + '@phan-var-force CommonNumRefGenerator $obj'; $numref = ""; $numref = $obj->getNextValue($mysoc, $this); @@ -590,6 +591,7 @@ class RemiseCheque extends CommonObject $classname = 'BordereauCheque'.ucfirst($model); $docmodel = new $classname($this->db); + '@phan-var-force CommonDocGenerator $module'; $sql = "SELECT b.banque, b.emetteur, b.amount, b.num_chq"; $sql .= " FROM ".MAIN_DB_PREFIX."bank as b"; diff --git a/htdocs/compta/paiement/cheque/index.php b/htdocs/compta/paiement/cheque/index.php index 98d938a23af..bd110ba8169 100644 --- a/htdocs/compta/paiement/cheque/index.php +++ b/htdocs/compta/paiement/cheque/index.php @@ -177,8 +177,8 @@ foreach ($arrayofpaymentmodetomanage as $val) { print ''.$checkdepositstatic->getNomUrl(1).''; print ''.dol_print_date($db->jdate($objp->db), 'day').''; print ''.$accountstatic->getNomUrl(1).''; - print ''.$objp->nbcheque.''; - print ''.price($objp->amount).''; + print ''.dol_escape_htmltag($objp->nbcheque).''; + print ''.price($objp->amount).''; print ''.$checkdepositstatic->LibStatut($objp->status, 3).''; print ''; diff --git a/htdocs/compta/payment_sc/card.php b/htdocs/compta/payment_sc/card.php index 9288421622e..482c9594d29 100644 --- a/htdocs/compta/payment_sc/card.php +++ b/htdocs/compta/payment_sc/card.php @@ -245,7 +245,7 @@ print '
      '; /* if (!empty($conf->global->BILL_ADD_PAYMENT_VALIDATION)) { - if ($user->socid == 0 && $object->statut == 0 && $_GET['action'] == '') + if ($user->socid == 0 && $object->statut == 0 && $action == '') { if ($user->hasRight('facture', 'paiement')){ print ''.$langs->trans('Valid').''; diff --git a/htdocs/compta/payment_vat/card.php b/htdocs/compta/payment_vat/card.php index 4d9d34abc75..df69e995365 100644 --- a/htdocs/compta/payment_vat/card.php +++ b/htdocs/compta/payment_vat/card.php @@ -150,17 +150,6 @@ if ($action == 'delete') { print $form->formconfirm('card.php?id='.$object->id, $langs->trans("DeletePayment"), $langs->trans("ConfirmDeletePayment"), 'confirm_delete', '', 0, 2); } -/* - * Validation confirmation of payment - */ -/* -if ($action == 'valide') -{ - $facid = $_GET['facid']; - print $form->formconfirm('card.php?id='.$object->id.'&facid='.$facid, $langs->trans("ValidatePayment"), $langs->trans("ConfirmValidatePayment"), 'confirm_valide','',0,2); - -} -*/ $linkback = ''.$langs->trans("BackToList").''; @@ -283,18 +272,6 @@ if ($resql) { */ print '
      '; -/* -if (!empty($conf->global->BILL_ADD_PAYMENT_VALIDATION)) -{ - if ($user->socid == 0 && $object->statut == 0 && $_GET['action'] == '') - { - if ($user->hasRight('facture', 'paiement')) { - print ''.$langs->trans('Valid').''; - } - } -} -*/ - if ($action == '') { if ($user->hasRight('tax', 'charges', 'supprimer')) { if (!$disable_delete) { diff --git a/htdocs/compta/paymentbybanktransfer/index.php b/htdocs/compta/paymentbybanktransfer/index.php index 9b42490727d..1135ff97b42 100644 --- a/htdocs/compta/paymentbybanktransfer/index.php +++ b/htdocs/compta/paymentbybanktransfer/index.php @@ -4,6 +4,7 @@ * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2011 Juanjo Menent * Copyright (C) 2013 Florian Henry + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -159,6 +160,7 @@ if (isModEnabled('supplier_invoice')) { $invoicestatic->status = $obj->fk_statut; $invoicestatic->statut = $obj->fk_statut; // For backward compatibility $invoicestatic->paye = $obj->paye; + $invoicestatic->paid = $obj->paye; $invoicestatic->type = $obj->type; $invoicestatic->date = $db->jdate($obj->datef); $invoicestatic->date_echeance = $db->jdate($obj->date_lim_reglement); diff --git a/htdocs/compta/sociales/payments.php b/htdocs/compta/sociales/payments.php index b97882242e3..fe85314f123 100644 --- a/htdocs/compta/sociales/payments.php +++ b/htdocs/compta/sociales/payments.php @@ -7,6 +7,7 @@ * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2019 Nicolas ZABOURI * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -307,7 +308,7 @@ while ($i < min($num, $limit)) { $userstatic->admin = $obj->admin; $userstatic->login = $obj->login; $userstatic->email = $obj->email; - $userstatic->statut = $obj->statut; + $userstatic->status = $obj->statut; print $userstatic->getNomUrl(1); print "\n"; } diff --git a/htdocs/contact/agenda.php b/htdocs/contact/agenda.php index 2c1a0d2ab99..5ef2652268c 100644 --- a/htdocs/contact/agenda.php +++ b/htdocs/contact/agenda.php @@ -144,7 +144,7 @@ if (empty($reshook)) { $form = new Form($db); -$title = (getDolGlobalString('SOCIETE_ADDRESSES_MANAGEMENT') ? $langs->trans("Contacts") : $langs->trans("ContactsAddresses")); +$title = $langs->trans("ContactEvents"); if (getDolGlobalString('MAIN_HTML_TITLE') && preg_match('/contactnameonly/', getDolGlobalString('MAIN_HTML_TITLE')) && $object->lastname) { $title = $object->lastname; } diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index 16087378bf2..1e0e14dbbc4 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -574,7 +574,6 @@ if (getDolGlobalString('MAIN_HTML_TITLE') && preg_match('/contactnameonly/', get $title = $object->lastname; } $help_url = 'EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas'; -$title = (getDolGlobalString('SOCIETE_ADDRESSES_MANAGEMENT') ? $langs->trans("NewContact") : $langs->trans("NewContactAddress")); llxHeader('', $title, $help_url); diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index 080cc4d5f95..833919df82d 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -337,7 +337,7 @@ class Contact extends CommonObject /** * Old copy - * @var Contact + * @var static */ public $oldcopy; // To contains a clone of this when we need to save old properties of object @@ -975,7 +975,7 @@ class Contact extends CommonObject * Load object contact. * * @param int $id Id of contact - * @param User $user Load also alerts of this user (subscribing to alerts) that want alerts about this contact + * @param ?User $user Load also alerts of this user (subscribing to alerts) that want alerts about this contact * @param string $ref_ext External reference, not given by Dolibarr * @param string $email Email * @param int $loadalsoroles Load also roles. Try to always 0 here and load roles with a separate call of fetchRoles(). diff --git a/htdocs/contact/consumption.php b/htdocs/contact/consumption.php index 66067b00e6e..158229e620a 100644 --- a/htdocs/contact/consumption.php +++ b/htdocs/contact/consumption.php @@ -111,7 +111,7 @@ $formother = new FormOther($db); $productstatic = new Product($db); $objsoc = new Societe($db); -$title = (getDolGlobalString('SOCIETE_ADDRESSES_MANAGEMENT') ? $langs->trans("Contacts") : $langs->trans("ContactsAddresses")); +$title = $langs->trans("ContactRelatedItems"); $help_url = 'EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas'; llxHeader('', $title, $help_url); diff --git a/htdocs/contact/document.php b/htdocs/contact/document.php index c4b216d2679..efc55ac0e5b 100644 --- a/htdocs/contact/document.php +++ b/htdocs/contact/document.php @@ -110,7 +110,7 @@ include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php'; $form = new Form($db); -$title = (getDolGlobalString('SOCIETE_ADDRESSES_MANAGEMENT') ? $langs->trans("Contacts") : $langs->trans("ContactsAddresses")); +$title = $langs->trans("ContactLinkedFiles"); if (getDolGlobalString('MAIN_HTML_TITLE') && preg_match('/contactnameonly/', getDolGlobalString('MAIN_HTML_TITLE')) && $object->lastname) { $title = $object->lastname; } diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index c7058f80d68..43b6294a5b5 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -57,7 +57,7 @@ $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'co $mode = GETPOST('mode', 'alpha'); if ($contextpage == 'poslist') { - $_GET['optioncss'] = 'print'; + $optioncss = 'print'; } // Security check diff --git a/htdocs/contact/note.php b/htdocs/contact/note.php index 1f7a328e614..1f956e94821 100644 --- a/htdocs/contact/note.php +++ b/htdocs/contact/note.php @@ -78,7 +78,7 @@ if (empty($reshook)) { $now = dol_now(); -$title = (getDolGlobalString('SOCIETE_ADDRESSES_MANAGEMENT') ? $langs->trans("Contacts") : $langs->trans("ContactsAddresses")); +$title = $langs->trans("ContactNotes"); $form = new Form($db); diff --git a/htdocs/contact/perso.php b/htdocs/contact/perso.php index 90028857f99..0661a80b685 100644 --- a/htdocs/contact/perso.php +++ b/htdocs/contact/perso.php @@ -3,6 +3,7 @@ * Copyright (C) 2004-2011 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2018-2021 Frédéric France + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -119,7 +120,7 @@ if ($action == 'update' && !GETPOST("cancel") && $user->hasRight('societe', 'con $now = dol_now(); -$title = (getDolGlobalString('SOCIETE_ADDRESSES_MANAGEMENT') ? $langs->trans("Contacts") : $langs->trans("ContactsAddresses")); +$title = $langs->trans("ContactPersonalData"); if (getDolGlobalString('MAIN_HTML_TITLE') && preg_match('/contactnameonly/', getDolGlobalString('MAIN_HTML_TITLE')) && $object->lastname) { $title = $object->lastname; } @@ -294,8 +295,8 @@ if ($action == 'edit') { print '   '; //var_dump($birthdatearray); - $ageyear = convertSecondToTime($now - $object->birthday, 'year') - 1970; - $agemonth = convertSecondToTime($now - $object->birthday, 'month') - 1; + $ageyear = (int) convertSecondToTime($now - $object->birthday, 'year') - 1970; + $agemonth = (int) convertSecondToTime($now - $object->birthday, 'month') - 1; if ($ageyear >= 2) { print '('.$ageyear.' '.$langs->trans("DurationYears").')'; } elseif ($agemonth >= 2) { diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 97ce15937e2..23890c825c7 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -289,8 +289,8 @@ if (empty($reshook)) { // Possibility to add external linked objects with hooks $object->linked_objects[$object->origin] = $object->origin_id; - if (is_array($_POST['other_linked_objects']) && !empty($_POST['other_linked_objects'])) { - $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']); + if (GETPOSTISARRAY('other_linked_objects')) { + $object->linked_objects = array_merge($object->linked_objects, GETPOST('other_linked_objects', 'array:int')); } $id = $object->create($user); @@ -707,7 +707,7 @@ if (empty($reshook)) { if (!empty($date_start_update) && !empty($date_end_update) && $date_start_update > $date_end_update) { setEventMessages($langs->trans("Error").': '.$langs->trans("DateStartPlanned").' > '.$langs->trans("DateEndPlanned"), null, 'errors'); $action = 'editline'; - $_GET['rowid'] = GETPOST('elrowid'); + $_GET['rowid'] = GETPOST('elrowid'); // Keep $_GET here. Used by GETPOST('rowid') later $error++; } diff --git a/htdocs/contrat/class/api_contracts.class.php b/htdocs/contrat/class/api_contracts.class.php index cee27733140..c599ad6d82e 100644 --- a/htdocs/contrat/class/api_contracts.class.php +++ b/htdocs/contrat/class/api_contracts.class.php @@ -75,7 +75,7 @@ class Contracts extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->contract->fetchObjectLinked(); @@ -192,11 +192,11 @@ class Contracts extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->contract->context['caller'] = $request_data['caller']; + $this->contract->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->contract->$field = $value; + $this->contract->$field = $this->_checkValForAPI($field, $value, $this->contract); } /*if (isset($request_data["lines"])) { $lines = array(); @@ -233,7 +233,7 @@ class Contracts extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->contract->getLinesArray(); $result = array(); @@ -265,7 +265,7 @@ class Contracts extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $request_data = (object) $request_data; @@ -323,7 +323,7 @@ class Contracts extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $request_data = (object) $request_data; @@ -386,7 +386,7 @@ class Contracts extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $updateRes = $this->contract->active_line(DolibarrApiAccess::$user, $lineid, $datestart, $dateend, $comment); @@ -424,7 +424,7 @@ class Contracts extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $updateRes = $this->contract->close_line(DolibarrApiAccess::$user, $lineid, $datestart, $comment); @@ -464,7 +464,7 @@ class Contracts extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } // TODO Check the lineid $lineid is a line of object @@ -496,7 +496,7 @@ class Contracts extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach ($request_data as $field => $value) { if ($field == 'id') { @@ -504,11 +504,17 @@ class Contracts extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->contract->context['caller'] = $request_data['caller']; + $this->contract->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); + continue; + } + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->contract->array_options[$index] = $this->_checkValForAPI($field, $val, $this->contract);; + } continue; } - $this->contract->$field = $value; + $this->contract->$field = $this->_checkValForAPI($field, $value, $this->contract); } if ($this->contract->update(DolibarrApiAccess::$user) > 0) { @@ -624,7 +630,7 @@ class Contracts extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->contract->closeAll(DolibarrApiAccess::$user, $notrigger); diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index c00f4d28c76..ece3aebabd0 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -346,6 +346,7 @@ class Contrat extends CommonObject } $obj = new $classname(); + '@phan-var-force CommonNumRefGenerator $obj'; $numref = $obj->getNextValue($soc, $this); if ($numref != "") { @@ -1064,6 +1065,7 @@ class Contrat extends CommonObject $result = dol_include_once('/core/modules/contract/'.$module.'.php'); if ($result > 0) { $modCodeContract = new $module(); + '@phan-var-force CommonNumRefGenerator $modCodeContrat'; if (!empty($modCodeContract->code_auto)) { // Force the ref to a draft value if numbering module is an automatic numbering @@ -2686,6 +2688,7 @@ class Contrat extends CommonObject require_once DOL_DOCUMENT_ROOT."/core/modules/contract/" . getDolGlobalString('CONTRACT_ADDON').'.php'; $obj = getDolGlobalString('CONTRACT_ADDON'); $modContract = new $obj(); + '@phan-var-force CommonNumRefGenerator $modContrat'; $clonedObj->ref = $modContract->getNextValue($objsoc, $clonedObj); // get extrafields so they will be clone diff --git a/htdocs/contrat/document.php b/htdocs/contrat/document.php index 6f19a21fa69..28a1c9455e2 100644 --- a/htdocs/contrat/document.php +++ b/htdocs/contrat/document.php @@ -47,7 +47,6 @@ $ref = GETPOST('ref', 'alpha'); // Security check if ($user->socid > 0) { - unset($_GET["action"]); $action = ''; $socid = $user->socid; } diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index 43c7b8da85b..90d39b3846a 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -10,6 +10,7 @@ * Copyright (C) 2019 Nicolas Zabouri * Copyright (C) 2021 Alexandre Spangaro * Copyright (C) 2024 MDW + * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1255,7 +1256,7 @@ while ($i < $imaxinloop) { $userstatic->lastname = $val['lastname']; $userstatic->firstname = $val['firstname']; $userstatic->email = $val['email']; - $userstatic->statut = $val['statut']; + $userstatic->status = $val['statut']; $userstatic->entity = $val['entity']; $userstatic->photo = $val['photo']; $userstatic->login = $val['login']; diff --git a/htdocs/core/actions_linkedfiles.inc.php b/htdocs/core/actions_linkedfiles.inc.php index ed0d8b4e8ec..7820754cae3 100644 --- a/htdocs/core/actions_linkedfiles.inc.php +++ b/htdocs/core/actions_linkedfiles.inc.php @@ -119,7 +119,7 @@ if (GETPOST('sendit', 'alpha') && getDolGlobalString('MAIN_UPLOAD_DOC') && !empt // Delete file/link if ($action == 'confirm_deletefile' && $confirm == 'yes' && !empty($permissiontoadd)) { - $urlfile = GETPOST('urlfile', 'alpha', 0, null, null, 1); // Do not use urldecode here ($_GET and $_REQUEST are already decoded by PHP). + $urlfile = GETPOST('urlfile', 'alpha', 0, null, null, 1); if (GETPOST('section', 'alpha')) { // For a delete from the ECM module, upload_dir is ECM root dir and urlfile contains relative path from upload_dir $file = $upload_dir.(preg_match('/\/$/', $upload_dir) ? '' : '/').$urlfile; diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index 2fca6e22a33..1cf74e70817 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -167,7 +167,7 @@ if (!$error && $massaction == 'confirm_presend') { $receiver = array($receiver); } } - if (!trim($_POST['sendto']) && count($receiver) == 0 && count($listofobjectthirdparties) == 1) { // if only one recipient, receiver is mandatory + if (!trim(GETPOST('sendto', 'alphawithlgt')) && count($receiver) == 0 && count($listofobjectthirdparties) == 1) { // if only one recipient, receiver is mandatory $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Recipient")), null, 'warnings'); $massaction = 'presend'; @@ -195,7 +195,7 @@ if (!$error && $massaction == 'confirm_presend') { // Define $sendto $tmparray = array(); - if (trim($_POST['sendto'])) { + if (trim(GETPOST('sendto', 'alphawithlgt'))) { // Recipients are provided into free text $tmparray[] = trim(GETPOST('sendto', 'alphawithlgt')); } @@ -222,7 +222,7 @@ if (!$error && $massaction == 'confirm_presend') { } } $tmparray = array(); - if (trim($_POST['sendtocc'])) { + if (trim(GETPOST('sendtocc', 'alphawithlgt'))) { $tmparray[] = trim(GETPOST('sendtocc', 'alphawithlgt')); } if (count($receivercc) > 0) { @@ -1544,6 +1544,48 @@ if (!$error && ($massaction == 'affectcommercial' || ($action == 'affectcommerci } } +if (!$error && ($massaction == 'unassigncommercial' || ($action == 'unassigncommercial' && $confirm == 'yes')) && $permissiontoadd) { + $db->begin(); + + $objecttmp = new $objectclass($db); + $nbok = 0; + + foreach ($toselect as $toselectid) { + $result = $objecttmp->fetch($toselectid); + if ($result > 0) { + if (in_array($objecttmp->element, array('societe'))) { + $TCommercial = GETPOST("commercial", "alpha"); + if (is_array($TCommercial)) { + foreach ($TCommercial as $commercial) { + $result = $objecttmp->del_commercial($user, $commercial); + } + } + } + if ($result <= 0) { + setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); + $error++; + break; + } else { + $nbok++; + } + } else { + setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); + $error++; + break; + } + } + + if (!$error) { + if ($nbok > 1) { + setEventMessages($langs->trans("CommercialsDisaffected", $nbok), null, 'mesgs'); + } else { + setEventMessages($langs->trans("CommercialDisaffected"), null, 'mesgs'); + } + $db->commit(); + } else { + $db->rollback(); + } +} // Approve for leave only if (!$error && ($massaction == 'approveleave' || ($action == 'approveleave' && $confirm == 'yes')) && $permissiontoapprove) { $db->begin(); diff --git a/htdocs/core/actions_printing.inc.php b/htdocs/core/actions_printing.inc.php index 496e23c99b3..f96c57ad6a9 100644 --- a/htdocs/core/actions_printing.inc.php +++ b/htdocs/core/actions_printing.inc.php @@ -1,6 +1,7 @@ * Copyright (C) 2014-2018 Frederic France + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -47,6 +48,7 @@ if ($action == 'print_file' && $user->hasRight('printing', 'read')) { require_once $classfile; $classname = 'printing_'.$driver; $printer = new $classname($db); + '@phan-var-force PrintingDriver $printer'; $langs->load($printer::LANGFILE); //print '
      '.print_r($printer, true).'
      '; diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php index 7c8efdb5a98..d3039b5ccaf 100644 --- a/htdocs/core/actions_sendmails.inc.php +++ b/htdocs/core/actions_sendmails.inc.php @@ -190,12 +190,12 @@ if (($action == 'send' || $action == 'relance') && !GETPOST('addfile') && !GETPO } $tmparray = array(); - if (trim($_POST['sendto'])) { + if (trim(GETPOST('sendto', 'alphawithlgt'))) { // Recipients are provided into free text field $tmparray[] = trim(GETPOST('sendto', 'alphawithlgt')); } - if (isset($_POST['tomail']) && trim($_POST['tomail'])) { + if (trim(GETPOST('tomail', 'alphawithlgt'))) { // Recipients are provided into free hidden text field $tmparray[] = trim(GETPOST('tomail', 'alphawithlgt')); } @@ -238,7 +238,7 @@ if (($action == 'send' || $action == 'relance') && !GETPOST('addfile') && !GETPO } } $tmparray = array(); - if (trim($_POST['sendtocc'])) { + if (trim(GETPOST('sendtocc', 'alphawithlgt'))) { $tmparray[] = trim(GETPOST('sendtocc', 'alphawithlgt')); } if (count($receivercc) > 0) { diff --git a/htdocs/core/ajax/ajaxdirtree.php b/htdocs/core/ajax/ajaxdirtree.php index 47e980cfd6c..4c8ea0fd144 100644 --- a/htdocs/core/ajax/ajaxdirtree.php +++ b/htdocs/core/ajax/ajaxdirtree.php @@ -1,6 +1,6 @@ - * Copyright (C) 2018 Frédéric France + * Copyright (C) 2018-2024 Frédéric France * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify @@ -308,7 +308,7 @@ if (empty($conf->use_javascript_ajax) || getDolGlobalString('MAIN_ECM_DISABLE_JS print ''; $userstatic->id = $val['fk_user_c']; $userstatic->lastname = $val['login_c']; - $userstatic->statut = $val['statut_c']; + $userstatic->status = $val['statut_c']; $htmltooltip = ''.$langs->trans("ECMSection").': '.$val['label'].'
      '; $htmltooltip = ''.$langs->trans("Type").': '.$langs->trans("ECMSectionManual").'
      '; $htmltooltip .= ''.$langs->trans("ECMCreationUser").': '.$userstatic->getNomUrl(1, '', false, 1).'
      '; @@ -482,7 +482,7 @@ function treeOutputForAbsoluteDir($sqltree, $selecteddir, $fullpathselecteddir, print ''; $userstatic->id = isset($val['fk_user_c']) ? $val['fk_user_c'] : 0; $userstatic->lastname = isset($val['login_c']) ? $val['login_c'] : 0; - $userstatic->statut = isset($val['statut_c']) ? $val['statut_c'] : 0; + $userstatic->status = isset($val['statut_c']) ? $val['statut_c'] : 0; $htmltooltip = ''.$langs->trans("ECMSection").': '.$val['label'].'
      '; $htmltooltip = ''.$langs->trans("Type").': '.$langs->trans("ECMSectionManual").'
      '; $htmltooltip .= ''.$langs->trans("ECMCreationUser").': '.$userstatic->getNomUrl(1, '', false, 1).'
      '; diff --git a/htdocs/core/ajax/fetchKnowledgeRecord.php b/htdocs/core/ajax/fetchKnowledgeRecord.php index 6e4f1ddd953..9445546b849 100644 --- a/htdocs/core/ajax/fetchKnowledgeRecord.php +++ b/htdocs/core/ajax/fetchKnowledgeRecord.php @@ -35,8 +35,8 @@ if (!defined('NOREQUIRESOC')) { if (!defined('NOREQUIREMENU')) { define('NOREQUIREMENU', '1'); } -// If there is no need to load and show top and left menu -if (!empty($_GET['public'])) { // GETPOST() is not yet defined so we use $_GET +// If we need access without being logged. +if (!empty($_GET['public'])) { // Keep $_GET here. GETPOST() is not yet defined so we use $_GET if (!defined("NOLOGIN")) { define("NOLOGIN", '1'); } diff --git a/htdocs/core/ajax/flowjs-server.php b/htdocs/core/ajax/flowjs-server.php index dfe8b4ad2ce..12fd91e12a0 100644 --- a/htdocs/core/ajax/flowjs-server.php +++ b/htdocs/core/ajax/flowjs-server.php @@ -74,8 +74,6 @@ if (!empty($conf->$module->dir_temp)) { top_httphead(); -dol_syslog(implode(',', $_GET)); - $result = false; if (!empty($upload_dir)) { diff --git a/htdocs/core/ajax/locationincoterms.php b/htdocs/core/ajax/locationincoterms.php index 5d541238466..6be6645c1b4 100644 --- a/htdocs/core/ajax/locationincoterms.php +++ b/htdocs/core/ajax/locationincoterms.php @@ -63,8 +63,7 @@ top_httphead(); //print ''."\n"; -dol_syslog('location_incoterms call with MAIN_USE_LOCATION_INCOTERMS_DICTIONNARY='.(!getDolGlobalString('MAIN_USE_LOCATION_INCOTERMS_DICTIONNARY') ? '' : $conf->global->MAIN_USE_LOCATION_INCOTERMS_DICTIONNARY)); -//var_dump($_GET); +dol_syslog('location_incoterms call with MAIN_USE_LOCATION_INCOTERMS_DICTIONNARY='.getDolGlobalString('MAIN_USE_LOCATION_INCOTERMS_DICTIONNARY', '')); // Generation of list of zip-town if (GETPOST('location_incoterms')) { diff --git a/htdocs/core/ajax/onlineSign.php b/htdocs/core/ajax/onlineSign.php index de58f75c303..8d04732aea4 100644 --- a/htdocs/core/ajax/onlineSign.php +++ b/htdocs/core/ajax/onlineSign.php @@ -48,7 +48,7 @@ if (!defined('NOIPCHECK')) { if (!defined('NOBROWSERNOTIF')) { define('NOBROWSERNOTIF', '1'); } -$entity = (!empty($_GET['entity']) ? (int) $_GET['entity'] : (!empty($_POST['entity']) ? (int) $_POST['entity'] : 1)); +$entity = (!empty($_GET['entity']) ? (int) $_GET['entity'] : (!empty($_POST['entity']) ? (int) $_POST['entity'] : 1)); // Keep $_GET and $_POST here. GETPOST not yet defined. if (is_numeric($entity)) { define("DOLENTITY", $entity); } @@ -61,7 +61,7 @@ $signature = GETPOST('signaturebase64'); $ref = GETPOST('ref', 'aZ09'); $mode = GETPOST('mode', 'aZ09'); // 'proposal', ... $SECUREKEY = GETPOST("securekey"); // Secure key -$online_sign_name = GETPOST("onlinesignname") ? GETPOST("onlinesignname") : ''; +$online_sign_name = GETPOST("onlinesignname"); $error = 0; $response = ""; diff --git a/htdocs/core/ajax/saveinplace.php b/htdocs/core/ajax/saveinplace.php index 6b337a88c68..47fd89b1659 100644 --- a/htdocs/core/ajax/saveinplace.php +++ b/htdocs/core/ajax/saveinplace.php @@ -127,7 +127,7 @@ if (!empty($field) && !empty($element) && !empty($table_element) && !empty($fk_e $newelement = $element; } - $_POST['action'] = 'update'; // Hack so restrictarea will test permissions on write too + $_POST['action'] = 'update'; // Keep this. It is a hack so restrictarea will test permissions on write too $feature = $newelement; $feature2 = $subelement; diff --git a/htdocs/core/ajax/selectobject.php b/htdocs/core/ajax/selectobject.php index aa702375d3e..f7c4726ac80 100644 --- a/htdocs/core/ajax/selectobject.php +++ b/htdocs/core/ajax/selectobject.php @@ -149,7 +149,6 @@ $form = new Form($db); top_httphead($outjson ? 'application/json' : 'text/html'); //print ''."\n"; -//print_r($_GET); $arrayresult = $form->selectForFormsList($objecttmp, $htmlname, '', 0, $searchkey, '', '', '', 0, 1, 0, '', $filter); diff --git a/htdocs/core/ajax/ziptown.php b/htdocs/core/ajax/ziptown.php index 21ccd582933..6ecfbb387f9 100644 --- a/htdocs/core/ajax/ziptown.php +++ b/htdocs/core/ajax/ziptown.php @@ -57,7 +57,6 @@ if (!getDolGlobalString('MAIN_USE_ZIPTOWN_DICTIONNARY')) { //print ''."\n"; dol_syslog('ziptown call with MAIN_USE_ZIPTOWN_DICTIONNARY='.getDolGlobalString('MAIN_USE_ZIPTOWN_DICTIONNARY')); -//var_dump($_GET); // Generation of list of zip-town if (GETPOST('zipcode') || GETPOST('town')) { diff --git a/htdocs/core/boxes/box_birthdays.php b/htdocs/core/boxes/box_birthdays.php index 050611acc00..ffb16d94071 100644 --- a/htdocs/core/boxes/box_birthdays.php +++ b/htdocs/core/boxes/box_birthdays.php @@ -2,7 +2,7 @@ /* Copyright (C) 2003-2007 Rodolphe Quiedeville * Copyright (C) 2004-2010 Laurent Destailleur * Copyright (C) 2005-2009 Regis Houssin - * Copyright (C) 2015 Frederic France + * Copyright (C) 2015-2024 Frédéric France * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify @@ -119,7 +119,7 @@ class box_birthdays extends ModeleBoxes $userstatic->firstname = $data[$j]->firstname; $userstatic->lastname = $data[$j]->lastname; $userstatic->email = $data[$j]->email; - $userstatic->statut = $data[$j]->status; + $userstatic->status = $data[$j]->status; $dateb = $this->db->jdate($data[$j]->datea); $age = idate('Y', dol_now()) - idate('Y', $dateb); diff --git a/htdocs/core/boxes/box_dolibarr_state_board.php b/htdocs/core/boxes/box_dolibarr_state_board.php index 9785396a49a..73631c07bc9 100644 --- a/htdocs/core/boxes/box_dolibarr_state_board.php +++ b/htdocs/core/boxes/box_dolibarr_state_board.php @@ -3,6 +3,7 @@ * Copyright (C) 2004-2010 Laurent Destailleur * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2015-2024 Frederic France + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -69,7 +70,7 @@ class box_dolibarr_state_board extends ModeleBoxes $hookmanager->initHooks(array('index')); $object = new stdClass(); $action = ''; - $parameters =array(); + $parameters = array(); $hookmanager->executeHooks('addStatisticLine', $parameters, $object, $action); $boxstatItems = array(); $boxstatFromHook = ''; @@ -254,6 +255,7 @@ class box_dolibarr_state_board extends ModeleBoxes $board = new $class($this->db); if (method_exists($board, 'load_state_board')) { + // @phan-suppress-next-line PhanUndeclaredMethod (Legacy, not present in core). $board->load_state_board(); } elseif (method_exists($board, 'loadStateBoard')) { $board->loadStateBoard(); diff --git a/htdocs/core/boxes/box_factures_fourn_imp.php b/htdocs/core/boxes/box_factures_fourn_imp.php index 777cea5a2ed..7806477433a 100644 --- a/htdocs/core/boxes/box_factures_fourn_imp.php +++ b/htdocs/core/boxes/box_factures_fourn_imp.php @@ -138,6 +138,7 @@ class box_factures_fourn_imp extends ModeleBoxes //$alreadypaid = $facturestatic->getSommePaiement(); $facturestatic->paye = $objp->paye; + $facturestatic->paid = $objp->paye; $facturestatic->alreadypaid = $objp->am; $thirdpartystatic->id = $objp->socid; diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 8c565e1602f..c517f9dfad4 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -52,7 +52,7 @@ class CMailFile public $subject; public $addr_from; // From: Label and EMail of sender (must include '<>'). For example '' or 'John Doe ' or ''). Note that with gmail smtps, value here is forced by google to account (but not the reply-to). // Sender: Who send the email ("Sender" has sent emails on behalf of "From"). - // Use it when the "From" is an email of a domain that is a SPF protected domain, and sending smtp server is not this domain. In such case, add Sender field with an email of the protected domain. + // Use it when the "From" is an email of a domain that is a SPF protected domain, and the sending smtp server is not this domain. In such case, add Sender field with an email of the protected domain. // Return-Path: Email where to send bounds. public $reply_to; // Reply-To: Email where to send replies from mailer software (mailer use From if reply-to not defined, Gmail use gmail account if reply-to not defined) public $errors_to; // Errors-To: Email where to send errors. @@ -114,7 +114,19 @@ class CMailFile * @var string Message-ID of the email to send (generated) */ public $msgid; + + /** + * @var string Value to use in In-reply-to when email is set as an answer of another email (The Msg-Id of received email) + */ + public $in_reply_to; + + /** + * @var string References to add to the email to send (generated from the email we answer) + */ + public $references; + public $headers; + public $message; /** @@ -172,10 +184,12 @@ class CMailFile * @param string $trackid Tracking string (contains type and id of related element) * @param string $moreinheader More in header. $moreinheader must contains the "\r\n" at end of each line * @param string $sendcontext 'standard', 'emailing', 'ticket', 'password', ... (used to define which sending mode and parameters to use) - * @param string $replyto Reply-to email (will be set to same value than From by default if not provided) + * @param string $replyto Reply-to email (will be set to the same value than From by default if not provided) * @param string $upload_dir_tmp Temporary directory (used to convert images embedded as img src=data:image) + * @param string $in_reply_to Message-ID of the message we reply Token + * @param string $references String with list of Message-ID of the thread ('<123> <456> ...') */ - public function __construct($subject, $to, $from, $msg, $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $addr_cc = "", $addr_bcc = "", $deliveryreceipt = 0, $msgishtml = 0, $errors_to = '', $css = '', $trackid = '', $moreinheader = '', $sendcontext = 'standard', $replyto = '', $upload_dir_tmp = '') + public function __construct($subject, $to, $from, $msg, $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $addr_cc = "", $addr_bcc = "", $deliveryreceipt = 0, $msgishtml = 0, $errors_to = '', $css = '', $trackid = '', $moreinheader = '', $sendcontext = 'standard', $replyto = '', $upload_dir_tmp = '', $in_reply_to = '', $references = '') { global $conf, $dolibarr_main_data_root, $user; @@ -428,6 +442,8 @@ class CMailFile $this->reply_to = dol_sanitizeEmail($replyto); $this->errors_to = dol_sanitizeEmail($errors_to); $this->trackid = $trackid; + $this->in_reply_to = $in_reply_to; + $this->references = $references; // Set arrays with attached files info $this->filename_list = $filename_list; $this->mimetype_list = $mimetype_list; @@ -462,7 +478,7 @@ class CMailFile $text_body = ""; $files_encoded = ""; - // Define smtp_headers (this also set ->msgid) + // Define smtp_headers (this also set SMTP headers from ->msgid, ->in_reply_to and ->references) $smtp_headers = $this->write_smtpheaders(); if (!empty($moreinheader)) { $smtp_headers .= $moreinheader; // $moreinheader contains the \r\n @@ -516,15 +532,23 @@ class CMailFile $smtps->setSubject($subjecttouse); $smtps->setTO($this->getValidAddress($this->addr_to, 0, 1)); $smtps->setFrom($this->getValidAddress($this->addr_from, 0, 1)); - $smtps->setTrackId($this->trackid); $smtps->setReplyTo($this->getValidAddress($this->reply_to, 0, 1)); - //X-Dolibarr-TRACKID is generated inside the smtps->getHeader + $smtps->setTrackId($this->trackid); + + if (!empty($this->in_reply_to)) { + $smtps->setInReplyTo($this->in_reply_to); + } + if (!empty($this->references)) { + $smtps->setReferences($this->references); + } if (!empty($moreinheader)) { $smtps->setMoreInHeader($moreinheader); } + //X-Dolibarr-TRACKID, In-Reply-To, References and $moreinheader will be added to header inside the smtps->getHeader + if (!empty($this->html)) { if (!empty($css)) { $this->css = $css; @@ -592,8 +616,14 @@ class CMailFile $msgid = $headers->get('Message-ID'); $msgid->setId($headerID); + // Add 'In-Reply-To:' header + if (!empty($this->in_reply_to)) { + $headers->addIdHeader('In-Reply-To', $this->in_reply_to); + } // Add 'References:' header - //$headers->addIdHeader('References', $headerID); + if (!empty($this->references)) { + $headers->addIdHeader('References', $this->references); + } if (!empty($moreinheader)) { $moreinheaderarray = preg_split('/[\r\n]+/', $moreinheader); @@ -1543,16 +1573,23 @@ class CMailFile $trackid = $this->trackid; if ($trackid) { - // References is kept in response and Message-ID is returned into In-Reply-To: $this->msgid = time().'.phpmail-dolibarr-'.$trackid.'@'.$host; $out .= 'Message-ID: <'.$this->msgid.">".$this->eol2; // Uppercase seems replaced by phpmail - //$out .= 'References: <'.$this->msgid.">".$this->eol2; $out .= 'X-Dolibarr-TRACKID: '.$trackid.'@'.$host.$this->eol2; } else { $this->msgid = time().'.phpmail@'.$host; $out .= 'Message-ID: <'.$this->msgid.">".$this->eol2; } + // Add 'In-Reply-To:' header with the Message-Id we answer + if (!empty($this->in_reply_to)) { + $out .= 'In-Reply-To: <'.$this->in_reply_to.'>'.$this->eol2; + } + // Add 'References:' header with list of all Message-ID in thread history + if (!empty($this->references)) { + $out .= 'References: '.$this->references.$this->eol2; + } + if (!empty($_SERVER['REMOTE_ADDR'])) { $out .= "X-RemoteAddr: ".$_SERVER['REMOTE_ADDR'].$this->eol2; } diff --git a/htdocs/core/class/comment.class.php b/htdocs/core/class/comment.class.php index f60f5c44183..9ffa0d60a1e 100644 --- a/htdocs/core/class/comment.class.php +++ b/htdocs/core/class/comment.class.php @@ -77,7 +77,7 @@ class Comment extends CommonObject public $comments = array(); /** - * @var Comment Object oldcopy + * @var static Object oldcopy */ public $oldcopy; diff --git a/htdocs/core/class/commoninvoice.class.php b/htdocs/core/class/commoninvoice.class.php index 769de345f4e..d78747713bc 100644 --- a/htdocs/core/class/commoninvoice.class.php +++ b/htdocs/core/class/commoninvoice.class.php @@ -2002,18 +2002,19 @@ abstract class CommonInvoiceLine extends CommonObjectLine /** * List of special options to define line: - * '1': shipment cost lines - * '2': ecotaxe - * '3': ?? - * 'idorcodeofmodule': a meaning for the module - * @var string + * 1: shipment cost lines + * 2: ecotaxe + * 3: ?? + * id of module: a meaning for the module + * @var int */ - public $special_code = ''; + public $special_code = 0; /** * @deprecated Use user_creation_id */ public $fk_user_author; + /** * @deprecated Use user_modification_id */ diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 9f93e22fcda..d862ee2607e 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -875,7 +875,6 @@ abstract class CommonObject return array( 'alreadypaid' => 'totalpaid', 'cond_reglement' => 'depr_cond_reglement', - 'modelpdf' => 'model_pdf', 'note' => 'note_private', 'commandeFournisseur' => 'origin_object', 'expedition' => 'origin_object', @@ -2047,25 +2046,25 @@ abstract class CommonObject /** * Read linked origin object. * Set ->origin_object - * Set also ->expedition or ->livraison or ->commandFournisseur (deprecated) + * Set also ->expedition or ->livraison or ->commandeFournisseur (deprecated) * * @return void */ public function fetch_origin() { // phpcs:enable - if ($this->origin == 'shipping') { - $this->origin = 'expedition'; - } - if ($this->origin == 'delivery') { - $this->origin = 'livraison'; - } - if ($this->origin == 'order_supplier' || $this->origin == 'supplier_order') { - $this->origin = 'commandeFournisseur'; - } - $origin = $this->origin ? $this->origin : $this->origin_type; + if ($origin == 'shipping') { + $origin = 'expedition'; + } + if ($origin == 'delivery') { + $origin = 'livraison'; + } + if ($origin == 'order_supplier' || $origin == 'supplier_order') { + $origin = 'commandeFournisseur'; + } + $classname = ucfirst($origin); $this->origin_object = new $classname($this->db); $this->origin_object->fetch($this->origin_id); @@ -5636,7 +5635,7 @@ abstract class CommonObject * Common function for all objects extending CommonObject for generating documents * * @param string $modelspath Relative folder where generators are placed - * @param string $modele Generator to use. Caller must set it to obj->model_pdf or $_POST for example. + * @param string $modele Generator to use. Caller must set it to from obj->model_pdf or from GETPOST for example. * @param Translate $outputlangs Output language to use * @param int $hidedetails 1 to hide details. 0 by default * @param int $hidedesc 1 to hide product description. 0 by default @@ -6016,8 +6015,6 @@ abstract class CommonObject **/ public function getDefaultCreateValueFor($fieldname, $alternatevalue = null, $type = 'alphanohtml') { - global $_POST; - // If param here has been posted, we use this value first. if (GETPOSTISSET($fieldname)) { return GETPOST($fieldname, $type, 3); @@ -6176,8 +6173,6 @@ abstract class CommonObject */ public function setValuesForExtraLanguages($onlykey = '') { - global $_POST, $langs; - // Get extra fields foreach ($_POST as $postfieldkey => $postfieldvalue) { $tmparray = explode('-', $postfieldkey); @@ -8304,7 +8299,12 @@ abstract class CommonObject $value = ''.$langs->trans("Encrypted").''; //$value = preg_replace('/./i', '*', $value); } elseif ($type == 'array') { - $value = implode('
      ', $value); + if (is_array($value)) { + $value = implode('
      ', $value); + } else { + dol_syslog(__METHOD__.' Expected array from dol_eval, but got '.gettype($value), LOG_ERR); + return 'Error unexpected result from code evaluation'; + } } else { // text|html|varchar $value = dol_htmlentitiesbr($value); } diff --git a/htdocs/core/class/commonobjectline.class.php b/htdocs/core/class/commonobjectline.class.php index 92a84376184..3b0a1b11321 100644 --- a/htdocs/core/class/commonobjectline.class.php +++ b/htdocs/core/class/commonobjectline.class.php @@ -2,6 +2,7 @@ /* Copyright (C) 2006-2008 Laurent Destailleur * Copyright (C) 2012 Cedric Salvador * Copyright (C) 2024 MDW + * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -78,8 +79,15 @@ abstract class CommonObjectLine extends CommonObject public $multilangs; - public $product_type; // type in line - public $fk_product; // product id in line (when line is linked to a product) + /** + * @var int type in line + */ + public $product_type; + + /** + * @var int product id in line (when line is linked to a product or service) + */ + public $fk_product; /** * Description of the line @@ -95,17 +103,48 @@ abstract class CommonObjectLine extends CommonObject */ public $description; - public $product; // To store full product object after a fetch_product() on a line - public $product_ref; // ref in product table - public $product_label; // label in product table - public $product_barcode; // barcode in product table - public $product_desc; // desc in product table - public $fk_product_type; // type in product table + /** + * @var Product Object product to store full product object after a fetch_product() on a line + */ + public $product; + + /** + * @var string reference in product table + */ + public $product_ref; + + /** + * @var string label in product table + */ + public $product_label; + + /** + * @var string barcode in product table + */ + public $product_barcode; + + /** + * @var string description in product table + */ + public $product_desc; + + /** + * @var int type in product table + */ + public $fk_product_type; public $qty; public $duree; public $remise_percent; + + /** + * @var int info_bits + */ public $info_bits; + + /** + * @var int special code + */ public $special_code; public $subprice; public $tva_tx; diff --git a/htdocs/core/class/commonorder.class.php b/htdocs/core/class/commonorder.class.php index dc5de2b9863..39ce201cb6f 100644 --- a/htdocs/core/class/commonorder.class.php +++ b/htdocs/core/class/commonorder.class.php @@ -1,5 +1,6 @@ + * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -218,6 +219,9 @@ abstract class CommonOrderLine extends CommonObjectLine */ public $info_bits = 0; + /** + * @var int special code + */ public $special_code = 0; public $fk_multicurrency; diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index 84ae48794fc..5ade23faf61 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -81,19 +81,32 @@ class Conf extends stdClass //! Used to store current currency (ISO code like 'USD', 'EUR', ...). To get the currency symbol: $langs->getCurrencySymbol($this->currency) public $currency; - //! Used to store current css (from theme) + /** + * @var string + */ public $theme; // Contains current theme ("eldy", "auguria", ...) + //! Used to store current css (from theme) + /** + * @var string + */ public $css; // Contains full path of css page ("/theme/eldy/style.css.php", ...) public $email_from; //! Used to store current menu handler public $standard_menu; - // List of activated modules + /** + * @var array List of activated modules + */ public $modules; + /** + * @var array> List of activated modules + */ public $modules_parts; - // An array to store cache results ->cache['nameofcache']=... + /** + * @var array An array to store cache results ->cache['nameofcache']=... + */ public $cache; /** @@ -107,13 +120,17 @@ class Conf extends stdClass public $logbuffer = array(); /** - * @var LogHandlerInterface[] + * @var LogHandler[] */ public $loghandlers = array(); - //! Used to store running instance for multi-company (default 1) + /** + * @var int Used to store running instance for multi-company (default 1) + */ public $entity = 1; - //! Used to store list of entities to use for each element + /** + * @var int[] Used to store list of entities to use for each element + */ public $entities = array(); public $dol_hide_topmenu; // Set if we force param dol_hide_topmenu into login url diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php index d51210bff34..29e663f4e27 100644 --- a/htdocs/core/class/discount.class.php +++ b/htdocs/core/class/discount.class.php @@ -303,7 +303,7 @@ class DiscountAbsolute extends CommonObject * Delete object in database. If fk_facture_source is defined, we delete all family with same fk_facture_source. If not, only with id is removed * * @param User $user Object of user asking to delete - * @return int<-1,1> Return integer <0 if KO, >0 if OK + * @return int<-2,1> Return integer <0 if KO, >0 if OK */ public function delete($user) { @@ -427,7 +427,7 @@ class DiscountAbsolute extends CommonObject * * @param int $rowidline Invoice line id (To use discount into invoice lines) * @param int $rowidinvoice Invoice id (To use discount as a credit note to reduce payment of invoice) - * @return int<-1,1> Return integer <0 if KO, >0 if OK + * @return int<-3,1> Return integer <0 if KO, >0 if OK */ public function link_to_invoice($rowidline, $rowidinvoice) { @@ -483,7 +483,7 @@ class DiscountAbsolute extends CommonObject * Link the discount to a particular invoice line or a particular invoice. * Do not call this if discount is linked to a reconcialiated invoice * - * @return int<-1,1> Return integer <0 if KO, >0 if OK + * @return int<-3,1> Return integer <0 if KO, >0 if OK */ public function unlink_invoice() { diff --git a/htdocs/core/class/doldeprecationhandler.class.php b/htdocs/core/class/doldeprecationhandler.class.php index 98f5d663ca6..2033794887f 100644 --- a/htdocs/core/class/doldeprecationhandler.class.php +++ b/htdocs/core/class/doldeprecationhandler.class.php @@ -32,6 +32,11 @@ trait DolDeprecationHandler // // protected $enableDynamicProperties = true; + // Define the following in the class using the trait + // to disallow Dolibarr deprecation warnings. + // + // protected $enableDeprecatedReporting = false; + /** * Get deprecated property * @@ -43,7 +48,7 @@ trait DolDeprecationHandler $deprecatedProperties = $this->deprecatedProperties(); if (isset($deprecatedProperties[$name])) { $newProperty = $deprecatedProperties[$name]; - $msg = "Accessing deprecated property '$name'. Use '$newProperty' instead.".self::getCallerInfoString(); + $msg = "DolDeprecationHandler: Accessing deprecated property '".$name."' on class ".get_class($this).". Use '".$newProperty."' instead.".self::getCallerInfoString(); dol_syslog($msg); if ($this->isDeprecatedReportingEnabled()) { trigger_error($msg, E_USER_DEPRECATED); @@ -53,7 +58,7 @@ trait DolDeprecationHandler if ($this->isDynamicPropertiesEnabled()) { return null; // If the property is set, then __get is not called. } - $msg = "Undefined property '$name'".self::getCallerInfoString(); + $msg = "DolDeprecationHandler: Undefined property '".$name."'".self::getCallerInfoString(); dol_syslog($msg); trigger_error($msg, E_USER_NOTICE); return $this->$name; // Returning value anyway (graceful degradation) @@ -71,18 +76,21 @@ trait DolDeprecationHandler $deprecatedProperties = $this->deprecatedProperties(); if (isset($deprecatedProperties[$name])) { $newProperty = $deprecatedProperties[$name]; - $msg = "Setting value to deprecated property '$name'. Use '$newProperty' instead.".self::getCallerInfoString(); + // Setting is for compatibility, should not be a problem and should be reported only in paranoid mode + /* + $msg = "DolDeprecationHandler: Setting value to the deprecated property '".$name."'. Use '".$newProperty."' instead.".self::getCallerInfoString(); dol_syslog($msg); if ($this->isDeprecatedReportingEnabled()) { trigger_error($msg, E_USER_DEPRECATED); } + */ $this->$newProperty = $value; return; } if (!$this->isDynamicPropertiesEnabled()) { - $msg = "Undefined property '$name'".self::getCallerInfoString(); - trigger_error("Undefined property '$name'".self::getCallerInfoString(), E_USER_NOTICE); + $msg = "DolDeprecationHandler: Undefined property '".$name."'".self::getCallerInfoString(); + trigger_error($msg, E_USER_NOTICE); $this->$name = $value; // Setting anyway for graceful degradation } else { $this->$name = $value; @@ -100,16 +108,19 @@ trait DolDeprecationHandler $deprecatedProperties = $this->deprecatedProperties(); if (isset($deprecatedProperties[$name])) { $newProperty = $deprecatedProperties[$name]; - $msg = "Unsetting deprecated property '$name'. Use '$newProperty' instead.".self::getCallerInfoString(); + // Unsetting is for compatibility, should not be a problem and should be reported only in paranoid mode + /* + $msg = "DolDeprecationHandler: Unsetting deprecated property '".$name."'. Use '".$newProperty."' instead.".self::getCallerInfoString(); dol_syslog($msg); if ($this->isDeprecatedReportingEnabled()) { trigger_error($msg, E_USER_DEPRECATED); } + */ unset($this->$newProperty); return; } if (!$this->isDynamicPropertiesEnabled()) { - $msg = "Undefined property '$name'".self::getCallerInfoString(); + $msg = "DolDeprecationHandler: Undefined property '".$name."'.".self::getCallerInfoString(); dol_syslog($msg); trigger_error($msg, E_USER_NOTICE); } @@ -126,7 +137,7 @@ trait DolDeprecationHandler $deprecatedProperties = $this->deprecatedProperties(); if (isset($deprecatedProperties[$name])) { $newProperty = $deprecatedProperties[$name]; - $msg = "Accessing deprecated property '$name'. Use '$newProperty' instead.".self::getCallerInfoString(); + $msg = "DolDeprecationHandler: Accessing deprecated property '".$name."' on class ".get_class($this).". Use '".$newProperty."' instead.".self::getCallerInfoString(); dol_syslog($msg); if ($this->isDeprecatedReportingEnabled()) { trigger_error($msg, E_USER_DEPRECATED); @@ -135,7 +146,7 @@ trait DolDeprecationHandler } elseif ($this->isDynamicPropertiesEnabled()) { return isset($this->$name); } - $msg = "Undefined property '$name'.".self::getCallerInfoString(); + $msg = "DolDeprecationHandler: Undefined property '".$name."'.".self::getCallerInfoString(); dol_syslog($msg); // trigger_error("Undefined property '$name'.".self::getCallerInfoString(), E_USER_NOTICE); return isset($this->$name); @@ -154,25 +165,32 @@ trait DolDeprecationHandler if (isset($deprecatedMethods[$name])) { $newMethod = $deprecatedMethods[$name]; if ($this->isDeprecatedReportingEnabled()) { - trigger_error("Calling deprecated method '$name'. Use '$newMethod' instead.".self::getCallerInfoString(), E_USER_DEPRECATED); + trigger_error("Calling deprecated method '".$name."' on class ".get_class($this).". Use '".$newMethod."' instead.".self::getCallerInfoString(), E_USER_DEPRECATED); } if (method_exists($this, $newMethod)) { return call_user_func_array([$this, $newMethod], $arguments); } else { - trigger_error("Replacement method '$newMethod' not implemented.", E_USER_NOTICE); + trigger_error("Replacement method '".$newMethod."' not implemented.", E_USER_NOTICE); } } - trigger_error("Call to undefined method '$name'".self::getCallerInfoString(), E_USER_ERROR); + trigger_error("Call to undefined method '".$name."'.".self::getCallerInfoString(), E_USER_ERROR); } /** - * Indicate if deprecations should be reported + * Indicate if deprecations should be reported. Depends on ->enableDeprecatedReporting. If not set, depends on PHP setup. * * @return bool */ private function isDeprecatedReportingEnabled() { + // By default, if enableDeprecatedReporting is set, use that value. + + if (property_exists($this, 'enableDeprecatedReporting')) { + // If the property exists, then we use it. + return (bool) $this->enableDeprecatedReporting; + } + return (error_reporting() & E_DEPRECATED) === E_DEPRECATED; } diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 56fad852290..7cfc5187d49 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -1102,7 +1102,7 @@ class ExtraFields if (!preg_match('/search_/', $keyprefix)) { // If keyprefix is search_ or search_options_, we must just use a simple text field require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; $doleditor = new DolEditor($keyprefix.$key.$keysuffix, $value, '', 200, 'dolibarr_notes', 'In', false, false, false, ROWS_5, '90%'); - $out = $doleditor->Create(1); + $out = (string) $doleditor->Create(1); } else { $out = ''; } @@ -1110,7 +1110,7 @@ class ExtraFields if (!preg_match('/search_/', $keyprefix)) { // If keyprefix is search_ or search_options_, we must just use a simple text field require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; $doleditor = new DolEditor($keyprefix.$key.$keysuffix, $value, '', 200, 'dolibarr_notes', 'In', false, false, isModEnabled('fckeditor') && $conf->global->FCKEDITOR_ENABLE_SOCIETE, ROWS_5, '90%'); - $out = $doleditor->Create(1); + $out = (string) $doleditor->Create(1); } else { $out = ''; } @@ -2129,7 +2129,7 @@ class ExtraFields */ public function setOptionalsFromPost($extralabels, &$object, $onlykey = '', $todefaultifmissing = 0) { - global $conf, $_POST, $langs; + global $langs; $nofillrequired = 0; // For error when required field left blank $error_field_required = array(); diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index e7c86ed271a..ce2a310f6cf 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -70,7 +70,9 @@ class Form public $errors = array(); // Some properties used to return data by some methods + /** @var array */ public $result; + /** @var int */ public $num; // Cache arrays @@ -213,7 +215,7 @@ class Form * @param string $formatfunc Call a specific method of $object->$formatfunc to output field in view mode (For example: 'dol_print_email') * @param string $paramid Key of parameter for id ('id', 'socid') * @param string $gm 'auto' or 'tzuser' or 'tzuserrel' or 'tzserver' (when $typeofdata is a date) - * @param array $moreoptions Array with more options. For example array('addnowlink'=>1), array('valuealreadyhtmlescaped'=>1) + * @param array $moreoptions Array with more options. For example array('addnowlink'=>1), array('valuealreadyhtmlescaped'=>1) * @param string $editaction [=''] use GETPOST default action or set action to edit mode * @return string HTML edit field */ @@ -408,7 +410,7 @@ class Form * Output edit in place form * * @param string $fieldname Name of the field - * @param object $object Object + * @param CommonObject $object Object * @param boolean $perm Permission to allow button to edit parameter. Set it to 0 to have a not edited field. * @param string $typeofdata Type of data ('string' by default, 'email', 'amount:99', 'numeric:99', 'text' or 'textarea:rows:cols', 'datepicker' ('day' do not work, don't know why), 'ckeditor:dolibarr_zzz:width:height:savemethod:1:rows:cols', 'select;xxx[:class]'...) * @param string $check Same coe than $check parameter of GETPOST() @@ -814,7 +816,7 @@ class Form * Generate select HTML to choose massaction * * @param string $selected Value auto selected when at least one record is selected. Not a preselected value. Use '0' by default. - * @param array $arrayofaction array('code'=>'label', ...). The code is the key stored into the GETPOST('massaction') when submitting action. + * @param array $arrayofaction array('code'=>'label', ...). The code is the key stored into the GETPOST('massaction') when submitting action. * @param int $alwaysvisible 1=select button always visible * @param string $name Name for massaction * @param string $cssclass CSS class used to check for select @@ -926,11 +928,11 @@ class Form * @param integer $maxlength Max length for labels (0=no limit) * @param string $morecss More css class * @param string $usecodeaskey ''=Use id as key (default), 'code3'=Use code on 3 alpha as key, 'code2"=Use code on 2 alpha as key - * @param int|string $showempty Show empty choice - * @param int $disablefavorites 1=Disable favorites, - * @param int $addspecialentries 1=Add dedicated entries for group of countries (like 'European Economic Community', ...) - * @param array $exclude_country_code Array of country code (iso2) to exclude - * @param int $hideflags Hide flags + * @param int<0,1>|string $showempty Show empty choice + * @param int<0,1> $disablefavorites 1=Disable favorites, + * @param int<0,1> $addspecialentries 1=Add dedicated entries for group of countries (like 'European Economic Community', ...) + * @param string[] $exclude_country_code Array of country code (iso2) to exclude + * @param int<0,1> $hideflags Hide flags * @return string HTML string with select */ public function select_country($selected = '', $htmlname = 'country_id', $htmloption = '', $maxlength = 0, $morecss = 'minwidth300', $usecodeaskey = '', $showempty = 1, $disablefavorites = 0, $addspecialentries = 0, $exclude_country_code = array(), $hideflags = 0) @@ -1061,9 +1063,9 @@ class Form * @param string $page Defined the form action * @param string $htmlname Name of html select object * @param string $htmloption Options html on select object - * @param int $forcecombo Force to load all values and output a standard combobox (with no beautification) - * @param array $events Event options to run on change. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) - * @param int $disableautocomplete Disable autocomplete + * @param int<0,1> $forcecombo Force to load all values and output a standard combobox (with no beautification) + * @param array}> $events Event options to run on change. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) + * @param int<0,1> $disableautocomplete Disable autocomplete * @return string HTML string with select and input */ public function select_incoterms($selected = '', $location_incoterms = '', $page = '', $htmlname = 'incoterm_id', $htmloption = '', $forcecombo = 1, $events = array(), $disableautocomplete = 0) @@ -1148,7 +1150,7 @@ class Form * * @param string $selected Preselected type * @param string $htmlname Name of field in html form - * @param int $showempty Add an empty field + * @param int<0,1> $showempty Add an empty field * @param int $hidetext Do not show label 'Type' before combo box (used only if there is at least 2 choices to select) * @param integer $forceall 1=Force to show products and services in combo list, whatever are activated modules, 0=No force, 2=Force to show only Products, 3=Force to show only services, -1=Force none (and set hidden field to 'service') * @return void @@ -1303,19 +1305,19 @@ class Form * @param string $selected Preselected type * @param string $htmlname Name of field in form * @param string $filter Optional filters criteras. WARNING: To avoid SQL injection, only few chars [.a-z0-9 =<>()] are allowed here. Example: ((s.client:IN:1,3) AND (s.status:=:1)). Do not use a filter coming from input of users. - * @param string $showempty Add an empty field (Can be '1' or text key to use on empty line like 'SelectThirdParty') + * @param string|int<1,1> $showempty Add an empty field (Can be '1' or text key to use on empty line like 'SelectThirdParty') * @param int $showtype Show third party type in combolist (customer, prospect or supplier) * @param int $forcecombo Force to load all values and output a standard combobox (with no beautification) - * @param array $events Ajax event options to run on change. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) + * @param array}> $events Ajax event options to run on change. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) * @param int $limit Maximum number of elements * @param string $morecss Add more css styles to the SELECT component * @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container * @param string $selected_input_value Value of preselected input text (for use with ajax) - * @param int $hidelabel Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after) - * @param array $ajaxoptions Options for ajax_autocompleter + * @param int<0,3> $hidelabel Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after) + * @param array $ajaxoptions Options for ajax_autocompleter * @param bool $multiple add [] in the name of element and add 'multiple' attribute (not working with ajax_autocompleter) - * @param array $excludeids Exclude IDs from the select combo - * @param int $showcode Show code + * @param string[] $excludeids Exclude IDs from the select combo + * @param int<0,1> $showcode Show code * @return string HTML string with select box for thirdparty. */ public function select_company($selected = '', $htmlname = 'socid', $filter = '', $showempty = '', $showtype = 0, $forcecombo = 0, $events = array(), $limit = 0, $morecss = 'minwidth100', $moreparam = '', $selected_input_value = '', $hidelabel = 1, $ajaxoptions = array(), $multiple = false, $excludeids = array(), $showcode = 0) @@ -1381,19 +1383,19 @@ class Form * @param string $filter Optional filters criteras. WARNING: To avoid SQL injection, only few chars [.a-z0-9 =<>] are allowed here, example: 's.rowid <> x' * If you need parenthesis, use the Universal Filter Syntax, example: '(s.client:in:1,3)' * Do not use a filter coming from input of users. - * @param string $showempty Add an empty field (Can be '1' or text to use on empty line like 'SelectThirdParty') - * @param int $showtype Show third party type in combolist (customer, prospect or supplier) + * @param string|int<0,1> $showempty Add an empty field (Can be '1' or text to use on empty line like 'SelectThirdParty') + * @param int<0,1> $showtype Show third party type in combolist (customer, prospect or supplier) * @param int $forcecombo Force to use standard HTML select component without beautification - * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) + * @param array}> $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) * @param string $filterkey Filter on key value - * @param int $outputmode 0=HTML select string, 1=Array + * @param int<0,1> $outputmode 0=HTML select string, 1=Array * @param int $limit Limit number of answers * @param string $morecss Add more css styles to the SELECT component * @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container * @param bool $multiple add [] in the name of element and add 'multiple' attribute - * @param array $excludeids Exclude IDs from the select combo - * @param int $showcode Show code in list - * @return array|string HTML string with + * @param string[] $excludeids Exclude IDs from the select combo + * @param int<0,1> $showcode Show code in list + * @return array|string HTML string with */ public function select_thirdparty_list($selected = '', $htmlname = 'socid', $filter = '', $showempty = '', $showtype = 0, $forcecombo = 0, $events = array(), $filterkey = '', $outputmode = 0, $limit = 0, $morecss = 'minwidth100', $moreparam = '', $multiple = false, $excludeids = array(), $showcode = 0) { @@ -1720,14 +1722,14 @@ class Form * @param int $socid Id of third party or 0 for all * @param string $selected Id of preselected contact * @param string $htmlname Name of HTML field ('none' for a not editable field) - * @param int $showempty 0=no empty value, 1=add an empty value, 2=add line 'Internal' (used by user edit), 3=add an empty value only if more than one record into list + * @param int<0,3> $showempty 0=no empty value, 1=add an empty value, 2=add line 'Internal' (used by user edit), 3=add an empty value only if more than one record into list * @param string $exclude List of contacts id to exclude * @param string $limitto Disable answers that are not id in this array list * @param integer $showfunction Add function into label * @param string $morecss Add more class to class style * @param integer $showsoc Add company into label * @param int $forcecombo Force to use combo box - * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) + * @param array}> $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) * @param bool $options_only Return options only (for ajax treatment) * @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container * @param string $htmlid Html id to use instead of htmlname @@ -1750,7 +1752,7 @@ class Form * @param int $socid Id of third party or 0 for all or -1 for empty list * @param array|int $selected Array of ID of preselected contact id * @param string $htmlname Name of HTML field ('none' for a not editable field) - * @param int|string $showempty 0=no empty value, 1=add an empty value, 2=add line 'Internal' (used by user edit), 3=add an empty value only if more than one record into list + * @param int<0,3>|string $showempty 0=no empty value, 1=add an empty value, 2=add line 'Internal' (used by user edit), 3=add an empty value only if more than one record into list * @param string $exclude List of contacts id to exclude * @param string $limitto Disable answers that are not id in this array list * @param integer $showfunction Add function into label @@ -1758,7 +1760,7 @@ class Form * @param bool $options_only Return options only (for ajax treatment) * @param integer $showsoc Add company into label * @param int $forcecombo Force to use combo box (so no ajax beautify effect) - * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) + * @param array}> $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) * @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container * @param string $htmlid Html id to use instead of htmlname * @param bool $multiple add [] in the name of element and add 'multiple' attribute @@ -1970,11 +1972,11 @@ class Form * * @param string $selected Id user preselected * @param string $htmlname Field name in form - * @param int $show_empty 0=liste sans valeur nulle, 1=ajoute valeur inconnue - * @param array $exclude Array list of users id to exclude - * @param int $disabled If select list must be disabled - * @param array|string $include Array list of users id to include. User '' for all users or 'hierarchy' to have only supervised users or 'hierarchyme' to have supervised + me - * @param array|int $enableonly Array list of users id to be enabled. All other must be disabled + * @param int<0,1> $show_empty 0=liste sans valeur nulle, 1=ajoute valeur inconnue + * @param int[] $exclude Array list of users id to exclude + * @param int<0,1> $disabled If select list must be disabled + * @param int[]|string $include Array list of users id to include. User '' for all users or 'hierarchy' to have only supervised users or 'hierarchyme' to have supervised + me + * @param int[]|int $enableonly Array list of users id to be enabled. All other must be disabled * @param string $force_entity '0' or Ids of environment to force * @return void * @deprecated Use select_dolusers instead @@ -1991,25 +1993,25 @@ class Form /** * Return select list of users * - * @param string|int $selected User id or user object of user preselected. If 0 or < -2, we use id of current user. If -1 or '', keep unselected (if empty is allowed) + * @param string|int|User $selected User id or user object of user preselected. If 0 or < -2, we use id of current user. If -1 or '', keep unselected (if empty is allowed) * @param string $htmlname Field name in form - * @param int|string $show_empty 0=list with no empty value, 1=add also an empty value into list - * @param array|null $exclude Array list of users id to exclude + * @param int<0,1>|string $show_empty 0=list with no empty value, 1=add also an empty value into list + * @param int[]|null $exclude Array list of users id to exclude * @param int $disabled If select list must be disabled - * @param array|string $include Array list of users id to include. User '' for all users or 'hierarchy' to have only supervised users or 'hierarchyme' to have supervised + me + * @param int[]|string $include Array list of users id to include. User '' for all users or 'hierarchy' to have only supervised users or 'hierarchyme' to have supervised + me * @param array|string $enableonly Array list of users id to be enabled. If defined, it means that others will be disabled * @param string $force_entity '0' or list of Ids of environment to force separated by a coma * @param int $maxlength Maximum length of string into list (0=no limit) - * @param int $showstatus 0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status + * @param int<-1,1> $showstatus 0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status * @param string $morefilter Add more filters into sql request (Example: 'employee = 1'). This value must not come from user input. * @param integer $show_every 0=default list, 1=add also a value "Everybody" at beginning of list * @param string $enableonlytext If option $enableonlytext is set, we use this text to explain into label why record is disabled. Not used if enableonly is empty. * @param string $morecss More css - * @param int $notdisabled Show only active users (this will also happened whatever is this option if USER_HIDE_INACTIVE_IN_COMBOBOX is on). - * @param int $outputmode 0=HTML select string, 1=Array + * @param int<0,1> $notdisabled Show only active users (this will also happened whatever is this option if USER_HIDE_INACTIVE_IN_COMBOBOX is on). + * @param int<0,2> $outputmode 0=HTML select string, 1=Array * @param bool $multiple add [] in the name of element and add 'multiple' attribute - * @param int $forcecombo Force the component to be a simple combo box without ajax - * @return array|string HTML select string + * @param int<0,1> $forcecombo Force the component to be a simple combo box without ajax + * @return string|array HTML select string * @see select_dolgroups() */ public function select_dolusers($selected = '', $htmlname = 'userid', $show_empty = 0, $exclude = null, $disabled = 0, $include = '', $enableonly = '', $force_entity = '', $maxlength = 0, $showstatus = 0, $morefilter = '', $show_every = 0, $enableonlytext = '', $morecss = '', $notdisabled = 0, $outputmode = 0, $multiple = false, $forcecombo = 0) @@ -2137,7 +2139,7 @@ class Form $userstatic->lastname = $obj->lastname; $userstatic->firstname = $obj->firstname; $userstatic->photo = $obj->photo; - $userstatic->statut = $obj->status; + $userstatic->status = $obj->status; $userstatic->entity = $obj->entity; $userstatic->admin = $obj->admin; @@ -2205,7 +2207,7 @@ class Form if (!empty($disableline)) { $out .= ' disabled'; } - if ((is_object($selected) && $selected->id == $obj->rowid) || (!is_object($selected) && in_array($obj->rowid, $selected))) { + if ((!empty($selected[0]) && is_object($selected[0])) ? $selected[0]->id == $obj->rowid : in_array($obj->rowid, $selected)) { $out .= ' selected'; } $out .= ' data-html="'; @@ -2265,19 +2267,19 @@ class Form * * @param string $action Value for $action * @param string $htmlname Field name in form - * @param int $show_empty 0=list without the empty value, 1=add empty value - * @param array $exclude Array list of users id to exclude - * @param int $disabled If select list must be disabled - * @param array $include Array list of users id to include or 'hierarchy' to have only supervised users - * @param array|int $enableonly Array list of users id to be enabled. All other must be disabled + * @param int<0,1> $show_empty 0=list without the empty value, 1=add empty value + * @param int[] $exclude Array list of users id to exclude + * @param int<0,1> $disabled If select list must be disabled + * @param int[]|string $include Array list of users id to include or 'hierarchy' to have only supervised users + * @param int[]|int $enableonly Array list of users id to be enabled. All other must be disabled * @param string $force_entity '0' or Ids of environment to force * @param int $maxlength Maximum length of string into list (0=no limit) - * @param int $showstatus 0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status + * @param int<0,1> $showstatus 0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status * @param string $morefilter Add more filters into sql request * @param int $showproperties Show properties of each attendees - * @param array $listofuserid Array with properties of each user - * @param array $listofcontactid Array with properties of each contact - * @param array $listofotherid Array with properties of each other contact + * @param int[] $listofuserid Array with properties of each user + * @param int[] $listofcontactid Array with properties of each contact + * @param int[] $listofotherid Array with properties of each other contact * @return string HTML select string * @see select_dolgroups() */ @@ -2289,9 +2291,13 @@ class Form $userstatic = new User($this->db); $out = ''; - $assignedtouser = array(); if (!empty($_SESSION['assignedtouser'])) { $assignedtouser = json_decode($_SESSION['assignedtouser'], true); + if (!is_array($assignedtouser)) { + $assignedtouser = array(); + } + } else { + $assignedtouser = array(); } $nbassignetouser = count($assignedtouser); @@ -2360,16 +2366,16 @@ class Form * @param string $action Value for $action * @param string $htmlname Field name in form * @param int $show_empty 0=list without the empty value, 1=add empty value - * @param array $exclude Array list of users id to exclude - * @param int $disabled If select list must be disabled - * @param array $include Array list of users id to include or 'hierarchy' to have only supervised users - * @param array $enableonly Array list of users id to be enabled. All other must be disabled + * @param int[] $exclude Array list of users id to exclude + * @param int<0,1> $disabled If select list must be disabled + * @param int[]|string $include Array list of users id to include or 'hierarchy' to have only supervised users + * @param int[] $enableonly Array list of users id to be enabled. All other must be disabled * @param string $force_entity '0' or Ids of environment to force * @param int $maxlength Maximum length of string into list (0=no limit) - * @param int $showstatus 0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status + * @param int<-1,1> $showstatus 0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status * @param string $morefilter Add more filters into sql request * @param int $showproperties Show properties of each attendees - * @param array $listofresourceid Array with properties of each resource + * @param array}> $listofresourceid Array with properties of each resource * @return string HTML select string */ public function select_dolresources_forevent($action = '', $htmlname = 'userid', $show_empty = 0, $exclude = null, $disabled = 0, $include = array(), $enableonly = array(), $force_entity = '0', $maxlength = 0, $showstatus = 0, $morefilter = '', $showproperties = 0, $listofresourceid = array()) @@ -2383,9 +2389,13 @@ class Form $resourcestatic = new Dolresource($this->db); $out = ''; - $assignedtoresource = array(); if (!empty($_SESSION['assignedtoresource'])) { $assignedtoresource = json_decode($_SESSION['assignedtoresource'], true); + if (!is_array($assignedtoresource)) { + $assignedtoresource = array(); + } + } else { + $assignedtoresource = array(); } $nbassignetoresource = count($assignedtoresource); @@ -2433,7 +2443,7 @@ class Form $events = array(); $out .= img_picto('', 'resource', 'class="pictofixedwidth"'); - $out .= $formresources->select_resource_list(0, $htmlname, [], 1, 1, 0, $events, '', 2, 0); + $out .= $formresources->select_resource_list(0, $htmlname, [], 1, 1, 0, $events, array(), 2, 0); //$out .= $this->select_dolusers('', $htmlname, $show_empty, $exclude, $disabled, $include, $enableonly, $force_entity, $maxlength, $showstatus, $morefilter); $out .= ' '; $out .= '
      '; @@ -2456,19 +2466,19 @@ class Form * @param int $finished 2=all, 1=finished, 0=raw material * @param string $selected_input_value Value of preselected input text (for use with ajax) * @param int $hidelabel Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after) - * @param array $ajaxoptions Options for ajax_autocompleter + * @param array $ajaxoptions Options for ajax_autocompleter * @param int $socid Thirdparty Id (to get also price dedicated to this customer) - * @param string $showempty '' to not show empty line. Translation key to show an empty line. '1' show empty line with no text. + * @param string|int<0,1> $showempty '' to not show empty line. Translation key to show an empty line. '1' show empty line with no text. * @param int $forcecombo Force to use combo box * @param string $morecss Add more css on select - * @param int $hidepriceinlabel 1=Hide prices in label + * @param int<0,1> $hidepriceinlabel 1=Hide prices in label * @param string $warehouseStatus Warehouse status filter to count the quantity in stock. Following comma separated filter options can be used * 'warehouseopen' = count products from open warehouses, * 'warehouseclosed' = count products from closed warehouses, * 'warehouseinternal' = count products from warehouses for internal correct/transfer only - * @param array $selected_combinations Selected combinations. Format: array([attrid] => attrval, [...]) - * @param int $nooutput No print if 1, return the output into a string - * @param int $status_purchase Purchase status: -1=No filter on purchase status, 0=Products not on purchase, 1=Products on purchase + * @param ?mixed[] $selected_combinations Selected combinations. Format: array([attrid] => attrval, [...]) + * @param int<0,1> $nooutput No print if 1, return the output into a string + * @param int<-1,1> $status_purchase Purchase status: -1=No filter on purchase status, 0=Products not on purchase, 1=Products on purchase * @return void|string */ public function select_produits($selected = 0, $htmlname = 'productid', $filtertype = '', $limit = 0, $price_level = 0, $status = 1, $finished = 2, $selected_input_value = '', $hidelabel = 0, $ajaxoptions = array(), $socid = 0, $showempty = '1', $forcecombo = 0, $morecss = '', $hidepriceinlabel = 0, $warehouseStatus = '', $selected_combinations = null, $nooutput = 0, $status_purchase = -1) @@ -2618,17 +2628,17 @@ class Form /** * Return list of BOM for customer in Ajax if Ajax activated or go to select_produits_list * - * @param string $selected Preselected BOM id - * @param string $htmlname Name of HTML select field (must be unique in page). - * @param int $limit Limit on number of returned lines - * @param int $status Sell status -1=Return all bom, 0=Draft BOM, 1=Validated BOM - * @param int $type type of the BOM (-1=Return all BOM, 0=Return disassemble BOM, 1=Return manufacturing BOM) - * @param string $showempty '' to not show empty line. Translation key to show an empty line. '1' show empty line with no text. - * @param string $morecss Add more css on select - * @param string $nooutput No print, return the output into a string - * @param int $forcecombo Force to use combo box - * @param array $TProducts Add filter on a defined product - * @return void|string + * @param string $selected Preselected BOM id + * @param string $htmlname Name of HTML select field (must be unique in page). + * @param int $limit Limit on number of returned lines + * @param int $status Sell status -1=Return all bom, 0=Draft BOM, 1=Validated BOM + * @param int $type type of the BOM (-1=Return all BOM, 0=Return disassemble BOM, 1=Return manufacturing BOM) + * @param string|int<0,1> $showempty '' to not show empty line. Translation key to show an empty line. '1' show empty line with no text. + * @param string $morecss Add more css on select + * @param string $nooutput No print, return the output into a string + * @param int $forcecombo Force to use combo box + * @param string[] $TProducts Add filter on a defined product + * @return void|string */ public function select_bom($selected = '', $htmlname = 'bom_id', $limit = 0, $status = 1, $type = 0, $showempty = '1', $morecss = '', $nooutput = '', $forcecombo = 0, $TProducts = []) { @@ -2709,7 +2719,7 @@ class Form * @param int $finished Filter on finished field: 2=No filter * @param int $outputmode 0=HTML select string, 1=Array * @param int $socid Thirdparty Id (to get also price dedicated to this customer) - * @param string $showempty '' to not show empty line. Translation key to show an empty line. '1' show empty line with no text. + * @param string|int<0,1> $showempty '' to not show empty line. Translation key to show an empty line. '1' show empty line with no text. * @param int $forcecombo Force to use combo box * @param string $morecss Add more css on select * @param int $hidepriceinlabel 1=Hide prices in label @@ -2952,7 +2962,7 @@ class Form $num = $this->db->num_rows($result); - $events = null; + $events = array(); if (!$forcecombo) { include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; @@ -3036,7 +3046,7 @@ class Form $objp->price = $price_result; $objp->unitprice = $price_result; //Calculate the VAT - $objp->price_ttc = price2num($objp->price) * (1 + ($objp->tva_tx / 100)); + $objp->price_ttc = (float) price2num($objp->price) * (1 + ($objp->tva_tx / 100)); $objp->price_ttc = price2num($objp->price_ttc, 'MU'); } } @@ -3073,14 +3083,14 @@ class Form * This define value for &$opt and &$optJson. * This function is called by select_produits_list(). * - * @param object $objp Resultset of fetch + * @param stdClass $objp Resultset of fetch * @param string $opt Option (var used for returned value in string option format) - * @param array $optJson Option (var used for returned value in json format) + * @param array{key:string,value:string,label:string,label2:string,desc:string,type:string,price_ht:string,price_ttc:string,price_ht_locale:string,price_ttc_locale:string,pricebasetype:string,tva_tx:string,default_vat_code:string,qty:string,discount:string,duration_value:string,duration_unit:string,pbq:string,labeltrans:string,desctrans:string,ref_customer:string} $optJson Option (var used for returned value in json format) * @param int $price_level Price level * @param int $selected Preselected value - * @param int $hidepriceinlabel Hide price in label + * @param int<0,1> $hidepriceinlabel Hide price in label * @param string $filterkey Filter key to highlight - * @param int $novirtualstock Do not load virtual stock, even if slow option STOCK_SHOW_VIRTUAL_STOCK_IN_PRODUCTS_COMBO is on. + * @param int<0,1> $novirtualstock Do not load virtual stock, even if slow option STOCK_SHOW_VIRTUAL_STOCK_IN_PRODUCTS_COMBO is on. * @return void */ protected function constructProductListOption(&$objp, &$opt, &$optJson, $price_level, $selected, $hidepriceinlabel = 0, $filterkey = '', $novirtualstock = 0) @@ -3416,9 +3426,9 @@ class Form * @param string $htmlname Name of HTML Select * @param string $filtertype Filter on product type (''=nofilter, 0=product, 1=service) * @param string $filtre For a SQL filter - * @param array $ajaxoptions Options for ajax_autocompleter - * @param int $hidelabel Hide label (0=no, 1=yes) - * @param int $alsoproductwithnosupplierprice 1=Add also product without supplier prices + * @param array $ajaxoptions Options for ajax_autocompleter + * @param int<0,1> $hidelabel Hide label (0=no, 1=yes) + * @param int<0,1> $alsoproductwithnosupplierprice 1=Add also product without supplier prices * @param string $morecss More CSS * @param string $placeholder Placeholder * @return void @@ -3833,7 +3843,7 @@ class Form 'type' => $outtype, 'duration_value' => $outdurationvalue, 'duration_unit' => $outdurationunit, - 'disabled' => (empty($objp->idprodfournprice) ? true : false), + 'disabled' => empty($objp->idprodfournprice), 'description' => $objp->description ); if (isModEnabled('multicurrency')) { @@ -3872,7 +3882,7 @@ class Form 'type' => $outtype, 'duration_value' => $outdurationvalue, 'duration_unit' => $outdurationunit, - 'disabled' => (empty($objp->idprodfournprice) ? true : false), + 'disabled' => empty($objp->idprodfournprice), 'description' => $objp->description ); if (isModEnabled('multicurrency')) { @@ -4838,13 +4848,13 @@ class Form } /** - * Creates HTML units selector (code => label) + * Creates HTML units selector (code => label) * - * @param string $selected Preselected Unit ID - * @param string $htmlname Select name - * @param int $showempty Add a nempty line - * @param string $unit_type Restrict to one given unit type - * @return string HTML select + * @param string $selected Preselected Unit ID + * @param string $htmlname Select name + * @param int<0,1> $showempty Add an empty line + * @param string $unit_type Restrict to one given unit type + * @return string HTML select */ public function selectUnits($selected = '', $htmlname = 'units', $showempty = 0, $unit_type = '') { @@ -5094,10 +5104,10 @@ class Form * - int (id of category) * - string (categories ids separated by comma) * - array (list of categories ids) - * @param int $outputmode 0=HTML select string, 1=Array with full label only, 2=Array extended, 3=Array with full picto + label - * @param int $include [=0] Removed or 1=Keep only + * @param int<0,3> $outputmode 0=HTML select string, 1=Array with full label only, 2=Array extended, 3=Array with full picto + label + * @param int<0,1> $include [=0] Removed or 1=Keep only * @param string $morecss More CSS - * @return string|array String list or Array of categories + * @return string|array|array|array String list or Array of categories * @see select_categories() */ public function select_all_categories($type, $selected = '', $htmlname = "parent", $maxlength = 64, $markafterid = 0, $outputmode = 0, $include = 0, $morecss = '') @@ -5175,6 +5185,7 @@ class Form $output .= "\n"; if ($outputmode == 2) { + // TODO: handle error when $cate_arbo is not an array return $cate_arbo; } elseif ($outputmode == 1) { return $outarray; @@ -5193,7 +5204,7 @@ class Form * @param string $title Title * @param string $question Question * @param string $action Action - * @param array $formquestion An array with forms complementary inputs + * @param array $formquestion An array with complementary inputs to add into forms: array(array('label'=> ,'type'=> , 'size'=>, 'morecss'=>, 'moreattr'=>'autofocus' or 'style=...')) * @param string $selectedchoice "" or "no" or "yes" * @param int|string $useajax 0=No, 1=Yes use Ajax to show the popup, 2=Yes and also submit page with &confirm=no if choice is No, 'xxx'=Yes and preoutput confirm box with div id=dialog-confirm-xxx * @param int $height Force height of box @@ -5224,9 +5235,9 @@ class Form * @param string $title Title * @param string $question Question * @param string $action Action - * @param array|string $formquestion An array with complementary inputs to add into forms: array(array('label'=> ,'type'=> , 'size'=>, 'morecss'=>, 'moreattr'=>'autofocus' or 'style=...')) - * 'type' can be 'text', 'password', 'checkbox', 'radio', 'date', 'datetime', 'select', 'multiselect', 'morecss', - * 'other', 'onecolumn' or 'hidden'... + * @param array}>|string|null $formquestion An array with complementary inputs to add into forms: array(array('label'=> ,'type'=> , 'size'=>, 'morecss'=>, 'moreattr'=>'autofocus' or 'style=...')) + * 'type' can be 'text', 'password', 'checkbox', 'radio', 'date', 'datetime', 'select', 'multiselect', 'morecss', + * 'other', 'onecolumn' or 'hidden'... * @param int|string $selectedchoice '' or 'no', or 'yes' or '1', 1, '0' or 0 * @param int|string $useajax 0=No, 1=Yes use Ajax to show the popup, 2=Yes and also submit page with &confirm=no if choice is No, 'xxx'=Yes and preoutput confirm box with div id=dialog-confirm-xxx * @param int|string $height Force height of box (0 = auto) @@ -5434,7 +5445,7 @@ class Form } } // Add name of fields to propagate with the GET when submitting the form with button KO. - if (isset($input['inputko']) && $input['inputko'] == 1) { + if (isset($input['inputko']) && $input['inputko'] == 1 && isset($input['name'])) { array_push($inputko, $input['name']); } } @@ -5448,7 +5459,7 @@ class Form if (!empty($more)) { $formconfirm .= '
      ' . $more . '
      ' . "\n"; } - $formconfirm .= ($question ? '
      ' . img_help('', '') . ' ' . $question . '
      ' : ''); + $formconfirm .= ($question ? '
      ' . img_help(0, '') . ' ' . $question . '
      ' : ''); $formconfirm .= '
      ' . "\n"; $formconfirm .= "\n\n"; @@ -5877,8 +5888,8 @@ class Form * @param string $page Page * @param string $selected Id of user preselected * @param string $htmlname Name of input html field. If 'none', we just output the user link. - * @param array $exclude List of users id to exclude - * @param array $include List of users id to include + * @param int[] $exclude List of users id to exclude + * @param int[] $include List of users id to include * @return void */ public function form_users($page, $selected = '', $htmlname = 'userid', $exclude = array(), $include = array()) @@ -6205,12 +6216,12 @@ class Form * @param string $selected Id preselected * @param string $htmlname Name of HTML select * @param string $filter Optional filters criteras. WARNING: To avoid SQL injection, only few chars [.a-z0-9 =<>()] are allowed here (example: 's.rowid <> x', 's.client IN (1,3)'). Do not use a filter coming from input of users. - * @param int $showempty Add an empty field - * @param int $showtype Show third party type in combolist (customer, prospect or supplier) - * @param int $forcecombo Force to use combo box - * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) + * @param string|int<0,1> $showempty Add an empty field (Can be '1' or text key to use on empty line like 'SelectThirdParty') + * @param int<0,1> $showtype Show third party type in combolist (customer, prospect or supplier) + * @param int<0,1> $forcecombo Force to use combo box + * @param array}> $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) * @param int $nooutput No print output. Return it only. - * @param array $excludeids Exclude IDs from the select combo + * @param int[] $excludeids Exclude IDs from the select combo * @param string $textifnothirdparty Text to show if no thirdparty * @return string HTML output or '' */ @@ -6773,9 +6784,9 @@ class Form * @param int $m 1=Show also minutes, -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 show minutes always empty * @param int $empty 0=Fields required, 1=Empty inputs are allowed, 2=Empty inputs are allowed for hours only * @param string $form_name Not used - * @param int $d 1=Show days, month, years - * @param int $addnowlink Add a link "Now", 1 with server time, 2 with local computer time - * @param int $disabled Disable input fields + * @param int<0,1> $d 1=Show days, month, years + * @param int<0,2> $addnowlink Add a link "Now", 1 with server time, 2 with local computer time + * @param int<0,1> $disabled Disable input fields * @param int|string $fullday When a checkbox with id #fullday is checked, hours are set with 00:00 (if value if 'fulldaystart') or 23:59 (if value is 'fulldayend') * @param string $addplusone Add a link "+1 hour". Value must be name of another selectDate field. * @param int|string|array $adddateof Add a link "Date of ..." using the following date. Must be array(array('adddateof'=>..., 'labeladddateof'=>...)) @@ -7223,7 +7234,7 @@ class Form * * @param string $prefix Prefix * @param string $selected Selected duration type - * @param array $excludetypes Array of duration types to exclude. Example array('y', 'm') + * @param string[] $excludetypes Array of duration types to exclude. Example array('y', 'm') * @return string HTML select string */ public function selectTypeDuration($prefix, $selected = 'i', $excludetypes = array()) @@ -7325,7 +7336,7 @@ class Form if ($typehour == 'select' || $typehour == 'textselect') { $retstring .= ''; + $stringtoprint .= ''; - $stringtoprint .=''; + $stringtoprint .= '})'; + $stringtoprint .= ''; } - $stringtoprint .=''; + $stringtoprint .= ''; $stringtoprint .= ajax_combobox($htmlname); return $stringtoprint; @@ -1163,7 +1164,7 @@ class FormTicket */ public function selectSeveritiesTickets($selected = '', $htmlname = 'ticketseverity', $filtertype = '', $format = 0, $empty = 0, $noadmininfo = 0, $maxlength = 0, $morecss = '') { - global $langs, $user; + global $conf, $langs, $user; $ticketstat = new Ticket($this->db); @@ -1182,8 +1183,8 @@ class FormTicket print ''; } - if (is_array($ticketstat->cache_severity_tickets) && count($ticketstat->cache_severity_tickets)) { - foreach ($ticketstat->cache_severity_tickets as $id => $arrayseverities) { + if (is_array($conf->cache['severity_tickets']) && count($conf->cache['severity_tickets'])) { + foreach ($conf->cache['severity_tickets'] as $id => $arrayseverities) { // On passe si on a demande de filtrer sur des modes de paiments particuliers if (count($filterarray) && !in_array($arrayseverities['type'], $filterarray)) { continue; diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php index f2a19b8269e..c4b0a371726 100644 --- a/htdocs/core/class/notify.class.php +++ b/htdocs/core/class/notify.class.php @@ -7,6 +7,7 @@ * Copyright (C) 2022 Anthony Berton * Copyright (C) 2023 William Mead * Copyright (C) 2024 Jon Bendtsen + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -213,7 +214,7 @@ class Notify $texte = img_object($langs->trans("Notifications"), 'email', 'class="pictofixedwidth"').$langs->trans("NoNotificationsWillBeSent"); } elseif ($nb == 1) { $texte = img_object($langs->trans("Notifications"), 'email', 'class="pictofixedwidth"').$langs->trans("ANotificationsWillBeSent"); - } elseif ($nb >= 2) { + } else { // Always >= 2 if ($nb >= 2) { $texte = img_object($langs->trans("Notifications"), 'email', 'class="pictofixedwidth"').$langs->trans("SomeNotificationsWillBeSent", $nb); } @@ -485,7 +486,7 @@ class Notify $newval2 = trim($obj->email); $isvalid = isValidEmail($newval2); if (empty($resarray[$newval2])) { - $resarray[$newval2] = array('type'=> 'tocontact', 'code'=>trim($obj->code), 'emaildesc'=>'Contact id '.$obj->rowid, 'email'=>$newval2, 'contactid'=>$obj->rowid, 'isemailvalid'=>$isvalid); + $resarray[$newval2] = array('type' => 'tocontact', 'code' => trim($obj->code), 'emaildesc' => 'Contact id '.$obj->rowid, 'email' => $newval2, 'contactid' => $obj->rowid, 'isemailvalid' => $isvalid); } } $i++; @@ -524,7 +525,7 @@ class Notify $newval2 = trim($obj->email); $isvalid = isValidEmail($newval2); if (empty($resarray[$newval2])) { - $resarray[$newval2] = array('type'=> 'touser', 'code'=>trim($obj->code), 'emaildesc'=>'User id '.$obj->rowid, 'email'=>$newval2, 'userid'=>$obj->rowid, 'isemailvalid'=>$isvalid); + $resarray[$newval2] = array('type' => 'touser', 'code' => trim($obj->code), 'emaildesc' => 'User id '.$obj->rowid, 'email' => $newval2, 'userid' => $obj->rowid, 'isemailvalid' => $isvalid); } } $i++; @@ -575,7 +576,7 @@ class Notify if ($newval2) { $isvalid = isValidEmail($newval2, 0); if (empty($resarray[$newval2])) { - $resarray[$newval2] = array('type'=> 'tofixedemail', 'code'=>trim($key), 'emaildesc'=>trim($val2), 'email'=>$newval2, 'isemailvalid'=>$isvalid); + $resarray[$newval2] = array('type' => 'tofixedemail', 'code' => trim($key), 'emaildesc' => trim($val2), 'email' => $newval2, 'isemailvalid' => $isvalid); } } } @@ -645,7 +646,7 @@ class Notify if (getDolGlobalString('MAIN_APPLICATION_TITLE')) { $application = getDolGlobalString('MAIN_APPLICATION_TITLE'); } - $replyto = $conf->notification->email_from; + $from = getDolGlobalString('NOTIFICATION_EMAIL_FROM'); $object_type = ''; $link = ''; $num = 0; @@ -889,7 +890,7 @@ class Notify $dir_output = $conf->$object_type->multidir_output[$object->entity ? $object->entity : $conf->entity]."/".get_exdir(0, 0, 0, 1, $object, $object_type); $template = $notifcode.'_TEMPLATE'; $mesg = $outputlangs->transnoentitiesnoconv('Notify_'.$notifcode).' '.$newref.' '.$dir_output; - break; + break; } include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; @@ -915,7 +916,7 @@ class Notify $ref = dol_sanitizeFileName($newref); $pdf_path = $dir_output."/".$ref.".pdf"; - if (!dol_is_file($pdf_path)||(is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0 && !$arraydefaultmessage->joinfiles)) { + if (!dol_is_file($pdf_path) || (is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0 && !$arraydefaultmessage->joinfiles)) { // We can't add PDF as it is not generated yet. $filepdf = ''; } else { @@ -944,7 +945,7 @@ class Notify $sendto = preg_replace('/[\s,]+$/', '', $sendto); // Clean end of string } - $parameters = array('notifcode'=>$notifcode, 'sendto'=>$sendto, 'replyto'=>$replyto, 'file'=>$filename_list, 'mimefile'=>$mimetype_list, 'filename'=>$mimefilename_list, 'outputlangs'=>$outputlangs, 'labeltouse'=>$labeltouse); + $parameters = array('notifcode' => $notifcode, 'sendto' => $sendto, 'from' => $from, 'file' => $filename_list, 'mimefile' => $mimetype_list, 'filename' => $mimefilename_list, 'outputlangs' => $outputlangs, 'labeltouse' => $labeltouse); if (!isset($action)) { $action = ''; } @@ -967,7 +968,7 @@ class Notify $mailfile = new CMailFile( $subject, $sendto, - $replyto, + $from, $message, $filename_list, $mimetype_list, @@ -1210,7 +1211,7 @@ class Notify } if ($sendto) { - $parameters = array('notifcode'=>$notifcode, 'sendto'=>$sendto, 'replyto'=>$replyto, 'file'=>$filename_list, 'mimefile'=>$mimetype_list, 'filename'=>$mimefilename_list, 'subject'=>&$subject, 'message'=>&$message); + $parameters = array('notifcode' => $notifcode, 'sendto' => $sendto, 'from' => $from, 'file' => $filename_list, 'mimefile' => $mimetype_list, 'filename' => $mimefilename_list, 'subject' => &$subject, 'message' => &$message); $reshook = $hookmanager->executeHooks('formatNotificationMessage', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if (empty($reshook)) { if (!empty($hookmanager->resArray['files'])) { @@ -1228,7 +1229,7 @@ class Notify $mailfile = new CMailFile( $subject, $sendto, - $replyto, + $from, $message, $filename_list, $mimetype_list, diff --git a/htdocs/core/class/openid.class.php b/htdocs/core/class/openid.class.php index 142fb711ecb..b1b4b3c97a7 100644 --- a/htdocs/core/class/openid.class.php +++ b/htdocs/core/class/openid.class.php @@ -432,26 +432,24 @@ class SimpleOpenID } } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * ValidateWithServer + * validateWithServer * * @return boolean */ - public function ValidateWithServer() + public function validateWithServer() { - // phpcs:enable $params = array( - 'openid.assoc_handle' => urlencode($_GET['openid_assoc_handle']), - 'openid.signed' => urlencode($_GET['openid_signed']), - 'openid.sig' => urlencode($_GET['openid_sig']) + 'openid.assoc_handle' => urlencode(GETPOST('openid_assoc_handle')), + 'openid.signed' => urlencode(GETPOST('openid_signed')), + 'openid.sig' => urlencode(GETPOST('openid_sig')) ); // Send only required parameters to confirm validity - $arr_signed = explode(",", str_replace('sreg.', 'sreg_', $_GET['openid_signed'])); + $arr_signed = explode(",", str_replace('sreg.', 'sreg_', GETPOST('openid_signed'))); $num = count($arr_signed); for ($i = 0; $i < $num; $i++) { $s = str_replace('sreg_', 'sreg.', $arr_signed[$i]); - $c = $_GET['openid_'.$arr_signed[$i]]; + $c = GETPOST('openid_'.$arr_signed[$i]); // if ($c != ""){ $params['openid.'.$s] = urlencode($c); // } diff --git a/htdocs/core/class/smtps.class.php b/htdocs/core/class/smtps.class.php index bca65ed5d84..6b9a2a272f4 100644 --- a/htdocs/core/class/smtps.class.php +++ b/htdocs/core/class/smtps.class.php @@ -4,7 +4,7 @@ * Copyright (C) 2005-2015 Laurent Destailleur * Copyright (C) 2006-2011 Regis Houssin * Copyright (C) 2016 Jonathan TISSEAU - * Copyright (C) 2024 MDW + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -88,6 +88,16 @@ class SMTPs */ private $_msgReplyTo = null; + /** + * List of In-Reply-To + */ + private $_msgInReplyTo = null; + + /** + * List of Msg-Id + */ + private $_msgReferences = null; + /** * Who will the Message be sent to; TO, CC, BCC * Multi-diminsional array containing addresses the message will @@ -1139,6 +1149,56 @@ class SMTPs return $_retValue; } + /** + * Set References in the list of Msg-Id + * + * @param string $_strInReplyTo List of Msg-Id + * @return void + */ + public function setInReplyTo($_strInReplyTo) + { + if ($_strInReplyTo) { + $this->_msgInReplyTo = $_strInReplyTo; + } + } + + /** + * Retrieves the InReplyTo from which mail we reply to + * + * @return string Msg-Id of email we reply to + */ + public function getInReplyTo() + { + $_retValue = $this->_msgInReplyTo; + + return $_retValue; + } + + /** + * Set References in the list of Msg-Id + * + * @param string $_strReferences List of Msg-Id + * @return void + */ + public function setReferences($_strReferences) + { + if ($_strReferences) { + $this->_msgReferences = $_strReferences; + } + } + + /** + * Retrieves the References from which mail will be the reply-to + * + * @return string List of Msg-Id + */ + public function getReferences() + { + $_retValue = $this->_msgReferences; + + return $_retValue; + } + /** * Inserts given addresses into structured format. * This method takes a list of given addresses, via an array or a COMMA delimited string, and inserts them into a highly @@ -1453,8 +1513,6 @@ class SMTPs if ($trackid) { $_header .= 'Message-ID: <'.time().'.SMTPs-dolibarr-'.$trackid.'@'.$host.">\r\n"; $_header .= 'X-Dolibarr-TRACKID: '.$trackid.'@'.$host."\r\n"; - // References and In-Reply-To: will be set by caller - //$_header .= 'References: <'.time().'.SMTPs-dolibarr-'.$trackid.'@'.$host.">\r\n"; } else { $_header .= 'Message-ID: <'.time().'.SMTPs@'.$host.">\r\n"; } @@ -1489,7 +1547,13 @@ class SMTPs $_header .= 'X-Dolibarr-Option: '.($conf->global->MAIN_MAIL_USE_MULTI_PART ? 'MAIN_MAIL_USE_MULTI_PART' : 'No MAIN_MAIL_USE_MULTI_PART')."\r\n"; $_header .= 'Mime-Version: 1.0'."\r\n"; - // TODO Add also $this->references and In-Reply-To + // Add also $this->references and In-Reply-To + if ($this->getInReplyTo()) { + $_header .= "In-Reply-To: ".$this->getInReplyTo()."\r\n"; + } + if ($this->getReferences()) { + $_header .= "References: ".$this->getReferences()."\r\n"; + } return $_header; } diff --git a/htdocs/core/datepicker.php b/htdocs/core/datepicker.php index 4c7c9a0ccc6..61352fa2b2c 100644 --- a/htdocs/core/datepicker.php +++ b/htdocs/core/datepicker.php @@ -3,6 +3,7 @@ * Copyright (C) 2005-2010 Laurent Destailleur * Copyright (C) 2005-2007 Regis Houssin * Copyright (C) 2014 Juanjo Menent + * Copyright (C) 2024 MDW * * This file is a modified version of datepicker.php from phpBSM to fix some * bugs, to add new features and to dramatically increase speed. @@ -107,10 +108,10 @@ print ''."\n"; $qualified = true; +// TODO Replace with GETPOST if (!isset($_GET["sd"])) { $_GET["sd"] = "00000000"; } - if (!isset($_GET["m"]) || !isset($_GET["y"])) { $qualified = false; } @@ -125,7 +126,6 @@ if (isset($_GET["m"]) && isset($_GET["y"])) { // If parameters provided, we show calendar if ($qualified) { - //print $_GET["cm"].",".$_GET["sd"].",".$_GET["m"].",".$_GET["y"];exit; displayBox(GETPOSTINT("sd"), GETPOSTINT("m"), GETPOSTINT("y")); } else { dol_print_error(null, 'ErrorBadParameters'); @@ -267,7 +267,7 @@ function displayBox($selectedDate, $month, $year) echo "trans("FormatDateShortJavaInput")."')\""; - echo ">".sprintf("%02s", $mydate["mday"]).""; + echo ">".sprintf("%02d", $mydate["mday"]).""; $cols++; if (($mydate["wday"] + 1) % 7 == $startday) { @@ -298,7 +298,7 @@ function displayBox($selectedDate, $month, $year) if ($selDate) { $tempDate = dol_getdate($selDate); print $langs->trans("Month".$selectMonth)." "; - print sprintf("%02s", $tempDate["mday"]); + print sprintf("%02d", $tempDate["mday"]); print ", ".$selectYear; } else { print "Click a Date"; diff --git a/htdocs/core/db/Database.interface.php b/htdocs/core/db/Database.interface.php index 1c9c7a5a05f..216865b39a3 100644 --- a/htdocs/core/db/Database.interface.php +++ b/htdocs/core/db/Database.interface.php @@ -36,6 +36,14 @@ interface Database */ public function ifsql($test, $resok, $resko); + /** + * Return SQL string to aggregate using the Standard Deviation of population + * + * @param string $nameoffield Name of field + * @return string SQL string + */ + public function stddevPop($nameoffield); + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Return datas as an array @@ -459,7 +467,7 @@ interface Database * * @param string $string Date in a string (YYYYMMDDHHMMSS, YYYYMMDD, YYYY-MM-DD HH:MM:SS) * @param bool $gm 1=Input information are GMT values, otherwise local to server TZ - * @return int|string Date TMS or '' + * @return int|'' Date TMS or '' */ public function jdate($string, $gm = false); diff --git a/htdocs/core/db/DoliDB.class.php b/htdocs/core/db/DoliDB.class.php index 19bb694558b..3265485cc4d 100644 --- a/htdocs/core/db/DoliDB.class.php +++ b/htdocs/core/db/DoliDB.class.php @@ -105,6 +105,17 @@ abstract class DoliDB implements Database return '(CASE WHEN '.$test.' THEN '.$resok.' ELSE '.$resko.' END)'; } + /** + * Return SQL string to aggregate using the Standard Deviation of population + * + * @param string $nameoffield Name of field + * @return string SQL string + */ + public function stddevPop($nameoffield) + { + return 'STDDEV_POP('.$nameoffield.')'; + } + /** * Return SQL string to force an index * @@ -345,7 +356,7 @@ abstract class DoliDB implements Database * * @param string $string Date in a string (YYYYMMDDHHMMSS, YYYYMMDD, YYYY-MM-DD HH:MM:SS) * @param mixed $gm 'gmt'=Input information are GMT values, 'tzserver'=Local to server TZ - * @return int|string Date TMS or '' + * @return int|'' Date TMS or '' */ public function jdate($string, $gm = 'tzserver') { diff --git a/htdocs/core/db/mysqli.class.php b/htdocs/core/db/mysqli.class.php index 485477d052d..c98732c2d06 100644 --- a/htdocs/core/db/mysqli.class.php +++ b/htdocs/core/db/mysqli.class.php @@ -518,6 +518,7 @@ class DoliDBMysqli extends DoliDB */ public function escapeforlike($stringtoencode) { + // We must first replace the \ char into \\, then we can replace _ and % into \_ and \% return str_replace(array('\\', '_', '%'), array('\\\\', '\_', '\%'), (string) $stringtoencode); } diff --git a/htdocs/core/filemanagerdol/connectors/php/connector.lib.php b/htdocs/core/filemanagerdol/connectors/php/connector.lib.php index afdfa2b6ffd..e95af16f784 100644 --- a/htdocs/core/filemanagerdol/connectors/php/connector.lib.php +++ b/htdocs/core/filemanagerdol/connectors/php/connector.lib.php @@ -243,14 +243,11 @@ function GetFoldersAndFiles($resourceType, $currentFolder) */ function CreateFolder($resourceType, $currentFolder) { - if (!isset($_GET)) { - global $_GET; - } $sErrorNumber = '0'; $sErrorMsg = ''; if (isset($_GET['NewFolderName'])) { - $sNewFolderName = $_GET['NewFolderName']; + $sNewFolderName = GETPOST('NewFolderName'); $sNewFolderName = SanitizeFolderName($sNewFolderName); if (strpos($sNewFolderName, '..') !== false) { @@ -741,9 +738,6 @@ function IsAllowedCommand($sCommand) */ function GetCurrentFolder() { - if (!isset($_GET)) { - global $_GET; - } $sCurrentFolder = isset($_GET['CurrentFolder']) ? GETPOST('CurrentFolder', '', 1) : '/'; // Check the current folder syntax (must begin and start with a slash). diff --git a/htdocs/core/filemanagerdol/connectors/php/connector.php b/htdocs/core/filemanagerdol/connectors/php/connector.php index 080e331b048..49b55f30b09 100644 --- a/htdocs/core/filemanagerdol/connectors/php/connector.php +++ b/htdocs/core/filemanagerdol/connectors/php/connector.php @@ -40,16 +40,13 @@ DoResponse(); */ function DoResponse() { - if (!isset($_GET)) { - global $_GET; - } if (!isset($_GET['Command']) || !isset($_GET['Type']) || !isset($_GET['CurrentFolder'])) { return; } // Get the main request information. - $sCommand = $_GET['Command']; - $sResourceType = $_GET['Type']; + $sCommand = GETPOST('Command'); + $sResourceType = GETPOST('Type'); $sCurrentFolder = GetCurrentFolder(); // Check if it is an allowed command diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index febd2a938ea..f0f7e9cbf75 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -396,7 +396,7 @@ function run_sql($sqlfile, $silent = 1, $entity = 0, $usesavepoint = 1, $handler $sql = preg_replace('/__DATABASE__/i', $db->escape($database), $sql); } - $newsql = preg_replace('/__ENTITY__/i', (!empty($entity) ? $entity : $conf->entity), $sql); + $newsql = preg_replace('/__ENTITY__/i', (!empty($entity) ? $entity : (string) $conf->entity), $sql); // Add log of request if (!$silent) { diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php index 81fe78a073c..42a0139bdf5 100644 --- a/htdocs/core/lib/ajax.lib.php +++ b/htdocs/core/lib/ajax.lib.php @@ -2,6 +2,7 @@ /* Copyright (C) 2007-2010 Laurent Destailleur * Copyright (C) 2007-2015 Regis Houssin * Copyright (C) 2012 Christophe Battarel + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,12 +36,12 @@ * @param string $urloption More parameters on URL request * @param int $minLength Minimum number of chars to trigger that Ajax search * @param int $autoselect Automatic selection if just one value (trigger("change") on field is done if search return only 1 result) - * @param array $ajaxoptions Multiple options array - * - Ex: array('update'=>array('field1','field2'...)) will reset field1 and field2 once select done - * - Ex: array('disabled'=> ) - * - Ex: array('show'=> ) - * - Ex: array('update_textarea'=> ) - * - Ex: array('option_disabled'=> id to disable and warning to show if we select a disabled value (this is possible when using autocomplete ajax) + * @param array $ajaxoptions Multiple options array + * - Ex: array('update'=>array('field1','field2'...)) will reset field1 and field2 once select done + * - Ex: array('disabled'=> ) + * - Ex: array('show'=> ) + * - Ex: array('update_textarea'=> ) + * - Ex: array('option_disabled'=> id to disable and warning to show if we select a disabled value (this is possible when using autocomplete ajax) * @param string $moreparams More params provided to ajax call * @return string Script */ @@ -168,7 +169,7 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLen multicurrency_unitprice: item.multicurrency_unitprice, '; } - $script .= ' + $script .= ' description : item.description, ref_customer: item.ref_customer, tva_tx: item.tva_tx, @@ -690,9 +691,9 @@ function ajax_constantonoff($code, $input = array(), $entity = null, $revertonof confirmConstantAction("del", url, code, input, input.alert.del, entity, yesButton, noButton, strict, userid, token); } else {'; if (empty($setzeroinsteadofdel)) { - $out .=' delConstant(url, code, input, entity, 0, '.((int) $forcereload).', userid, token);'; + $out .= ' delConstant(url, code, input, entity, 0, '.((int) $forcereload).', userid, token);'; } else { - $out .=' setConstant(url, code, input, entity, 0, '.((int) $forcereload).', userid, token, 0);'; + $out .= ' setConstant(url, code, input, entity, 0, '.((int) $forcereload).', userid, token, 0);'; } $out .= ' } }); diff --git a/htdocs/core/lib/barcode.lib.php b/htdocs/core/lib/barcode.lib.php index ca18ed00cb1..f56000ae532 100644 --- a/htdocs/core/lib/barcode.lib.php +++ b/htdocs/core/lib/barcode.lib.php @@ -75,9 +75,9 @@ if (defined('PHP-BARCODE_PATH_COMMAND')) { * * @param string $code Code * @param string $encoding Encoding ('EAN13', 'ISBN', 'C128', 'UPC', 'CBR', 'QRCODE', 'DATAMATRIX', 'ANY'...) - * @param integer $scale Scale + * @param int<1,max> $scale Scale * @param string $mode 'png' or 'jpg' ... - * @return array|string $bars array('encoding': the encoding which has been used, 'bars': the bars, 'text': text-positioning info) or string with error message + * @return array{encoding:string,bars:string,text:string}|string $bars array('encoding': the encoding which has been used, 'bars': the bars, 'text': text-positioning info) or string with error message */ function barcode_print($code, $encoding = "ANY", $scale = 2, $mode = "png") { @@ -124,7 +124,7 @@ function barcode_print($code, $encoding = "ANY", $scale = 2, $mode = "png") * * @param string $code Code * @param string $encoding Encoding - * @return array|false array('encoding': the encoding which has been used, 'bars': the bars, 'text': text-positioning info) + * @return array{encoding:string,bars:string,text:string}|false array('encoding': the encoding which has been used, 'bars': the bars, 'text': text-positioning info) */ function barcode_encode($code, $encoding) { @@ -172,7 +172,7 @@ function barcode_encode($code, $encoding) * Calculate EAN sum * * @param string $ean EAN to encode - * @return integer Sum + * @return int<0,9> EAN Sum */ function barcode_gen_ean_sum($ean) { @@ -206,8 +206,8 @@ function barcode_gen_ean_bars($ean) $line = $guards[0]; for ($i = 1; $i < 13; $i++) { - $str = $digits[$ean[$i]]; - if ($i < 7 && $mirror[$ean[0]][$i - 1] == 1) { + $str = $digits[(int) $ean[$i]]; + if ($i < 7 && $mirror[(int) $ean[0]][$i - 1] == 1) { $line .= strrev($str); } else { $line .= $str; @@ -226,7 +226,7 @@ function barcode_gen_ean_bars($ean) * * @param string $ean Code * @param string $encoding Encoding - * @return array array('encoding': the encoding which has been used, 'bars': the bars, 'text': text-positioning info, 'error': error message if error) + * @return array{encoding:string,bars:string,text:string,error:string}|array{text:string,error:string} array('encoding': the encoding which has been used, 'bars': the bars, 'text': text-positioning info, 'error': error message if error) */ function barcode_encode_ean($ean, $encoding = "EAN-13") { @@ -282,7 +282,7 @@ function barcode_encode_ean($ean, $encoding = "EAN-13") * * @param string $upc Code * @param string $encoding Encoding - * @return array array('encoding': the encoding which has been used, 'bars': the bars, 'text': text-positioning info, 'error': error message if error) + * @return array{encoding:string,bars:string,text:string,error:string}|array{text:string,error:string} array('encoding': the encoding which has been used, 'bars': the bars, 'text': text-positioning info, 'error': error message if error) */ function barcode_encode_upc($upc, $encoding = "UPC") { @@ -332,7 +332,7 @@ function barcode_encode_upc($upc, $encoding = "UPC") * * @param string $code Code * @param string $encoding Encoding - * @return array|false array('encoding': the encoding which has been used, 'bars': the bars, 'text': text-positioning info) + * @return array{encoding:string,bars:string,text:string}|false array('encoding': the encoding which has been used, 'bars': the bars, 'text': text-positioning info) */ function barcode_encode_genbarcode($code, $encoding) { @@ -403,10 +403,10 @@ function barcode_encode_genbarcode($code, $encoding) * * @param string $text the text-line (:: ...) * @param string $bars where to place the bars (...) - * @param int $scale scale factor ( 1 < scale < unlimited (scale 50 will produce 5400x300 pixels when using EAN-13!!!)) + * @param int<1,max> $scale scale factor ( 1 < scale < unlimited (scale 50 will produce 5400x300 pixels when using EAN-13!!!)) * @param string $mode png,gif,jpg (default='png') * @param int $total_y the total height of the image ( default: scale * 60 ) - * @param array $space default: $space[top] = 2 * $scale; $space[bottom]= 2 * $scale; $space[left] = 2 * $scale; $space[right] = 2 * $scale; + * @param array{}|array{top:int,bottom:int,left:int,right:int} $space default: $space[top] = 2 * $scale; $space[bottom]= 2 * $scale; $space[left] = 2 * $scale; $space[right] = 2 * $scale; * @return string|void */ function barcode_outimage($text, $bars, $scale = 1, $mode = "png", $total_y = 0, $space = []) @@ -424,7 +424,7 @@ function barcode_outimage($text, $bars, $scale = 1, $mode = "png", $total_y = 0, if ($total_y < 1) { $total_y = (int) $scale * 60; } - if (!$space) { + if (!is_array($space) || empty($space)) { $space = array('top' => 2 * $scale, 'bottom' => 2 * $scale, 'left' => 2 * $scale, 'right' => 2 * $scale); } @@ -435,7 +435,7 @@ function barcode_outimage($text, $bars, $scale = 1, $mode = "png", $total_y = 0, for ($i = 0; $i < $ln; $i++) { $val = strtolower($bars[$i]); if ($width) { - $xpos += $val * $scale; + $xpos += (int) $val * $scale; $width = false; continue; } diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php index 8b7ea390b71..b3d71145ab2 100644 --- a/htdocs/core/lib/date.lib.php +++ b/htdocs/core/lib/date.lib.php @@ -688,8 +688,8 @@ function dol_get_first_day_week($day, $month, $year, $gm = false) //print 'start_week='.$start_week.' tmparray[wday]='.$tmparray['wday'].' day offset='.$days.' seconds offset='.$seconds.'
      '; //Get first day of week - $tmpdaytms = (int) date($tmparray[0]) - $seconds; // $tmparray[0] is day of parameters - $tmpday = (int) date("d", $tmpdaytms); + $tmpdaytms = (int) date((string) $tmparray['0']) - $seconds; // $tmparray[0] is day of parameters + $tmpday = idate("d", $tmpdaytms); //Check first day of week is in same month than current day or not if ($tmpday > $day) { diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 3ff1c19a100..d697c7595f3 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -54,6 +54,7 @@ if (!function_exists('utf8_encode')) { * * @param mixed $elements PHP Object to json encode * @return string Json encoded string + * @phan-suppress PhanRedefineFunctionInternal */ function utf8_encode($elements) { @@ -67,6 +68,7 @@ if (!function_exists('utf8_decode')) { * * @param mixed $elements PHP Object to json encode * @return string Json encoded string + * @phan-suppress PhanRedefineFunctionInternal */ function utf8_decode($elements) { @@ -80,6 +82,7 @@ if (!function_exists('str_starts_with')) { * @param string $haystack haystack * @param string $needle needle * @return boolean + * @phan-suppress PhanRedefineFunctionInternal */ function str_starts_with($haystack, $needle) { @@ -93,6 +96,7 @@ if (!function_exists('str_ends_with')) { * @param string $haystack haystack * @param string $needle needle * @return boolean + * @phan-suppress PhanRedefineFunctionInternal */ function str_ends_with($haystack, $needle) { @@ -106,6 +110,7 @@ if (!function_exists('str_contains')) { * @param string $haystack haystack * @param string $needle needle * @return boolean + * @phan-suppress PhanRedefineFunctionInternal */ function str_contains($haystack, $needle) { @@ -336,10 +341,10 @@ function getDoliDBInstance($type, $host, $user, $pass, $name, $port) * 'contract', 'tax', 'expensereport', 'holiday', 'multicurrency', 'project', * 'email_template', 'event', 'donation' * 'c_paiement', 'c_payment_term', ... - * @param int $shared 0=Return id of current entity only, + * @param int<0,1> $shared 0=Return id of current entity only, * 1=Return id of current entity + shared entities (default) - * @param object $currentobject Current object if needed - * @return mixed Entity id(s) to use ( eg. entity IN ('.getEntity(elementname).')' ) + * @param ?CommonObject $currentobject Current object if needed + * @return string Entity id(s) to use ( eg. entity IN ('.getEntity(elementname).')' ) */ function getEntity($element, $shared = 1, $currentobject = null) { @@ -401,8 +406,8 @@ function getEntity($element, $shared = 1, $currentobject = null) /** * Set entity id to use when to create an object * - * @param object $currentobject Current object - * @return mixed Entity id to use ( eg. entity = '.setEntity($object) ) + * @param CommonObject $currentobject Current object + * @return int Entity id to use ( eg. entity = '.setEntity($object) ) */ function setEntity($currentobject) { @@ -456,7 +461,7 @@ function num2Alpha($n) * ) * * @param string $user_agent Content of $_SERVER["HTTP_USER_AGENT"] variable - * @return array Check function documentation + * @return array{browsername:string,browserversion:string,browseros:string,browserua:string,layout:string,phone:string,tablet:bool} Check function documentation */ function getBrowserInfo($user_agent) { @@ -637,8 +642,8 @@ function GETPOSTISSET($paramname) * Return true if the parameter $paramname is submit from a POST OR GET as an array. * Can be used before GETPOST to know if the $check param of GETPOST need to check an array or a string * - * @param string $paramname Name or parameter to test - * @param int $method Type of method (0 = get then post, 1 = only get, 2 = only post, 3 = post then get) + * @param string $paramname Name or parameter to test + * @param int<0,3> $method Type of method (0 = get then post, 1 = only get, 2 = only post, 3 = post then get) * @return bool True if we have just submit a POST or GET request with the parameter provided (even if param is empty) */ function GETPOSTISARRAY($paramname, $method = 0) @@ -683,8 +688,8 @@ function GETPOSTISARRAY($paramname, $method = 0) * 'restricthtml'=check html content is restricted to some tags only * 'custom'= custom filter specify $filter and $options) * @param int $method Type of method (0 = get then post, 1 = only get, 2 = only post, 3 = post then get) - * @param int $filter Filter to apply when $check is set to 'custom'. (See http://php.net/manual/en/filter.filters.php for détails) - * @param mixed $options Options to pass to filter_var when $check is set to 'custom' + * @param ?int $filter Filter to apply when $check is set to 'custom'. (See http://php.net/manual/en/filter.filters.php for détails) + * @param mixed $options Options to pass to filter_var when $check is set to 'custom' * @param int $noreplace Force disable of replacement of __xxx__ strings. * @return string|array Value found (string or array), or '' if check fails */ @@ -713,6 +718,8 @@ function GETPOST($paramname, $check = 'alphanohtml', $method = 0, $filter = null return 'BadThirdParameterForGETPOST'; } + $relativepathstring = ''; // For static analysis - looks possibly undefined if not set. + if (empty($method) || $method == 3 || $method == 4) { $relativepathstring = (empty($_SERVER["PHP_SELF"]) ? '' : $_SERVER["PHP_SELF"]); // Clean $relativepathstring @@ -754,6 +761,7 @@ function GETPOST($paramname, $check = 'alphanohtml', $method = 0, $filter = null if (!empty($_GET['action']) && $_GET['action'] == 'create' && !isset($_GET[$paramname]) && !isset($_POST[$paramname])) { // Search default value from $object->field global $object; + '@phan-var-force CommonObject $object'; // Suppose it's a CommonObject for analysis, but other objects have the $fields field as well if (is_object($object) && isset($object->fields[$paramname]['default'])) { $out = $object->fields[$paramname]['default']; } @@ -1003,9 +1011,9 @@ function GETPOST($paramname, $check = 'alphanohtml', $method = 0, $filter = null * Use the property $user->default_values[path]['creatform'] and/or $user->default_values[path]['filters'] and/or $user->default_values[path]['sortorder'] * Note: The property $user->default_values is loaded by main.php when loading the user. * - * @param string $paramname Name of the $_GET or $_POST parameter - * @param int $method Type of method (0 = $_GET then $_POST, 1 = only $_GET, 2 = only $_POST, 3 = $_POST then $_GET) - * @return int Value converted into integer + * @param string $paramname Name of the $_GET or $_POST parameter + * @param int<0,3> $method Type of method (0 = $_GET then $_POST, 1 = only $_GET, 2 = only $_POST, 3 = $_POST then $_GET) + * @return int Value converted into integer */ function GETPOSTINT($paramname, $method = 0) { @@ -1065,6 +1073,9 @@ function sanitizeVal($out = '', $check = 'alphanohtml', $filter = null, $options } break; case 'intcomma': + if (is_array($out)) { + $out = implode(',', $out); + } if (preg_match('/[^0-9,-]+/i', $out)) { $out = ''; } @@ -1186,6 +1197,7 @@ if (!function_exists('dol_getprefix')) { * * @param string $mode '' (prefix for session name) or 'email' (prefix for email id) * @return string A calculated prefix + * @phan-suppress PhanRedefineFunction - Also defined in webportal.main.inc.php */ function dol_getprefix($mode = '') { @@ -1355,15 +1367,52 @@ function dol_buildpath($path, $type = 0, $returnemptyifnotfound = 0) return $res; } +/** + * Get properties for an object - including magic properties when requested + * + * Only returns properties that exist + * + * @param object $obj Object to get properties from + * @param string[] $properties Optional list of properties to get. + * When empty, only gets public properties. + * @return array Hash for retrieved values (key=name) + */ +function dol_get_object_properties($obj, $properties = []) +{ + // Get real properties using get_object_vars() if $properties is empty + if (empty($properties)) { + return get_object_vars($obj); + } + + $existingProperties = []; + $realProperties = get_object_vars($obj); + + // Get the real or magic property values + foreach ($properties as $property) { + if (array_key_exists($property, $realProperties)) { + // Real property, add the value + $existingProperties[$property] = $obj->{$property}; + } elseif (property_exists($obj, $property)) { + // Magic property + $existingProperties[$property] = $obj->{$property}; + } + } + + return $existingProperties; +} + + /** * Create a clone of instance of object (new instance with same value for each properties) * With native = 0: Property that are reference are different memory area in the new object (full isolation clone). This means $this->db of new object may not be valid. * With native = 1: Use PHP clone. Property that are reference are same pointer. This means $this->db of new object is still valid but point to same this->db than original object. * With native = 2: Property that are reference are different memory area in the new object (full isolation clone). Only scalar and array values are cloned. This means method are not availables and $this->db of new object is not valid. * - * @param object $object Object to clone + * @template T of object + * + * @param T $object Object to clone * @param int $native 0=Full isolation method, 1=Native PHP method, 2=Full isolation method keeping only scalar and array properties (recommended) - * @return object Clone object + * @return T Clone object * @see https://php.net/manual/language.oop5.cloning.php */ function dol_clone($object, $native = 0) @@ -1654,10 +1703,10 @@ function dol_string_nounprintableascii($str, $removetabcrlf = 1) /** * Returns text escaped for inclusion into javascript code * - * @param string $stringtoescape String to escape - * @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 \ - * @param int $noescapebackslashn 0=Escape also \n. 1=Do not escape \n. - * @return string Escaped string. Both ' and " are escaped into ' if they are escaped. + * @param string $stringtoescape String to escape + * @param int<0,3> $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 \ + * @param int $noescapebackslashn 0=Escape also \n. 1=Do not escape \n. + * @return string Escaped string. Both ' and " are escaped into ' if they are escaped. */ function dol_escape_js($stringtoescape, $mode = 0, $noescapebackslashn = 0) { @@ -1962,13 +2011,14 @@ function dol_ucwords($string, $encoding = "UTF-8") * * @param string $message Line to log. ''=Show nothing * @param int $level Log level - * 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 + * On Windows LOG_ERR=4, LOG_WARNING=5, LOG_NOTICE=LOG_INFO=6, LOG_DEBUG=6 if define_syslog_variables ou PHP 5.3+, 7 if dolibarr * On Linux LOG_ERR=3, LOG_WARNING=4, LOG_NOTICE=5, LOG_INFO=6, LOG_DEBUG=7 * @param int $ident 1=Increase ident of 1 (after log), -1=Decrease ident of 1 (before log) * @param string $suffixinfilename When output is a file, append this suffix into default log filename. Example '_stripe', '_mail' * @param string $restricttologhandler Force output of log only to this log handler * @param array|null $logcontext If defined, an array with extra information (can be used by some log handlers) * @return void + * @phan-suppress PhanPluginUnknownArrayFunctionParamType $logcontext is not defined in detail */ function dol_syslog($message, $level = LOG_INFO, $ident = 0, $suffixinfilename = '', $restricttologhandler = '', $logcontext = null) { @@ -2026,7 +2076,7 @@ function dol_syslog($message, $level = LOG_INFO, $ident = 0, $suffixinfilename = //TODO: Remove this. MAIN_ENABLE_LOG_INLINE_HTML should be deprecated and use a log handler dedicated to HTML output // If html log tag enabled and url parameter log defined, we show output log on HTML comments - if (getDolGlobalString('MAIN_ENABLE_LOG_INLINE_HTML') && !empty($_GET["log"])) { + if (getDolGlobalString('MAIN_ENABLE_LOG_INLINE_HTML') && GETPOSTINT("log")) { print "\n\n\n"; @@ -2189,7 +2239,7 @@ function dolButtonToOpenUrlInDialogPopup($name, $label, $buttonstring, $url, $di /** * Show tab header of a card * - * @param array $links Array of tabs (0=>url, 1=>label, 2=>code, 3=>not used, 4=>text after link, 5=>morecssonlink). Currently initialized by calling a function xxx_admin_prepare_head. Note that label into $links[$i][1] must be already HTML escaped. + * @param array,string>> $links Array of tabs (0=>url, 1=>label, 2=>code, 3=>not used, 4=>text after link, 5=>morecssonlink). Currently initialized by calling a function xxx_admin_prepare_head. Note that label into $links[$i][1] must be already HTML escaped. * @param string $active Active tab name (document', 'info', 'ldap', ....) * @param string $title Title * @param int $notab -1 or 0=Add tab header, 1=no tab header (if you set this to 1, using print dol_get_fiche_end() to close tab is not required), -2=Add tab header with no sepaaration under tab (to start a tab just after), -3=Add tab header but no footer separation @@ -2210,7 +2260,7 @@ function dol_fiche_head($links = array(), $active = '0', $title = '', $notab = 0 /** * Show tabs of a record * - * @param array $links Array of tabs (0=>url, 1=>label, 2=>code, 3=>not used, 4=>text after link, 5=>morecssonlink). Currently initialized by calling a function xxx_admin_prepare_head. Note that label into $links[$i][1] must be already HTML escaped. + * @param array,string>> $links Array of tabs (0=>url, 1=>label, 2=>code, 3=>not used, 4=>text after link, 5=>morecssonlink). Currently initialized by calling a function xxx_admin_prepare_head. Note that label into $links[$i][1] must be already HTML escaped. * @param string $active Active tab name * @param string $title Title * @param int $notab -1 or 0=Add tab header, 1=no tab header (if you set this to 1, using print dol_get_fiche_end() to close tab is not required), -2=Add tab header with no separation under tab (to start a tab just after), -3=-2+'noborderbottom' @@ -2410,7 +2460,7 @@ function dol_get_fiche_head($links = array(), $active = '', $title = '', $notab /** * Show tab footer of a card * - * @param int $notab -1 or 0=Add tab footer, 1=no tab footer + * @param int<-1,1> $notab -1 or 0=Add tab footer, 1=no tab footer * @return void * @deprecated Use print dol_get_fiche_end() instead */ @@ -2422,7 +2472,7 @@ function dol_fiche_end($notab = 0) /** * Return tab footer of a card * - * @param int $notab -1 or 0=Add tab footer, 1=no tab footer + * @param int<-1,1> $notab -1 or 0=Add tab footer, 1=no tab footer * @return string */ function dol_get_fiche_end($notab = 0) @@ -2462,6 +2512,7 @@ function dol_banner_tab($object, $paramid, $morehtml = '', $shownav = 1, $fieldi $maxvisiblephotos = 1; $showimage = 1; $entity = (empty($object->entity) ? $conf->entity : $object->entity); + // @phan-suppress-next-line PhanUndeclaredMethod $showbarcode = empty($conf->barcode->enabled) ? 0 : (empty($object->barcode) ? 0 : 1); if (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !$user->hasRight('barcode', 'lire_advance')) { $showbarcode = 0; @@ -2492,6 +2543,7 @@ function dol_banner_tab($object, $paramid, $morehtml = '', $shownav = 1, $fieldi if ($object->element == 'product') { /** @var Product $object */ + '@phan-var-force Product $object'; $width = 80; $cssclass = 'photowithmargin photoref'; $showimage = $object->is_photo_available($conf->product->multidir_output[$entity]); @@ -2500,7 +2552,7 @@ function dol_banner_tab($object, $paramid, $morehtml = '', $shownav = 1, $fieldi $maxvisiblephotos = 1; } if ($showimage) { - $morehtmlleft .= '
      '.$object->show_photos('product', $conf->product->multidir_output[$entity], 'small', $maxvisiblephotos, 0, 0, 0, 0, $width, 0, '').'
      '; + $morehtmlleft .= '
      '.$object->show_photos('product', $conf->product->multidir_output[$entity], 1, $maxvisiblephotos, 0, 0, 0, 0, $width, 0, '').'
      '; } else { if (getDolGlobalString('PRODUCT_NODISPLAYIFNOPHOTO')) { $nophoto = ''; @@ -2512,6 +2564,7 @@ function dol_banner_tab($object, $paramid, $morehtml = '', $shownav = 1, $fieldi } } elseif ($object->element == 'category') { /** @var Categorie $object */ + '@phan-var-force Categorie $object'; $width = 80; $cssclass = 'photowithmargin photoref'; $showimage = $object->isAnyPhotoAvailable($conf->categorie->multidir_output[$entity]); @@ -2532,6 +2585,7 @@ function dol_banner_tab($object, $paramid, $morehtml = '', $shownav = 1, $fieldi } } elseif ($object->element == 'bom') { /** @var Bom $object */ + '@phan-var-force Bom $object'; $width = 80; $cssclass = 'photowithmargin photoref'; $showimage = $object->is_photo_available($conf->bom->multidir_output[$entity]); @@ -2554,6 +2608,7 @@ function dol_banner_tab($object, $paramid, $morehtml = '', $shownav = 1, $fieldi $width = 80; $cssclass = 'photoref'; /** @var Ticket $object */ + '@phan-var-force Ticket $object'; $showimage = $object->is_photo_available($conf->ticket->multidir_output[$entity].'/'.$object->ref); $maxvisiblephotos = getDolGlobalInt('TICKET_MAX_VISIBLE_PHOTO', 2); if ($conf->browser->layout == 'phone') { @@ -3213,7 +3268,7 @@ function dol_print_date($time, $format = '', $tzoutput = 'auto', $outputlangs = * @param int $timestamp Timestamp * @param boolean $fast Fast mode. deprecated. * @param string $forcetimezone '' to use the PHP server timezone. Or use a form like 'gmt', 'Europe/Paris' or '+0200' to force timezone. - * @return array Array of information + * @return array{}|array{seconds:int<0,59>,minutes:int<0,59>,hours:int<0,23>,mday:int<1,31>,wday:int<0,6>,mon:int<1,12>,year:int<0,9999>,yday:int<0,366>,0:int} Array of information * 'seconds' => $secs, * 'minutes' => $min, * 'hours' => $hour, @@ -5691,11 +5746,11 @@ function dol_print_error($db = null, $error = '', $errors = null) /** * Show a public email and error code to contact if technical error * - * @param string $prefixcode Prefix of public error code - * @param string $errormessage Complete error message - * @param array $errormessages Array of error messages - * @param string $morecss More css - * @param string $email Email + * @param string $prefixcode Prefix of public error code + * @param string $errormessage Complete error message + * @param string[] $errormessages Array of error messages + * @param string $morecss More css + * @param string $email Email * @return void */ function dol_print_error_email($prefixcode, $errormessage = '', $errormessages = array(), $morecss = 'error', $email = '') @@ -6265,7 +6320,7 @@ function vatrate($rate, $addpercent = false, $info_bits = 0, $usestarfornpr = 0, * * @param string|float $amount Amount value to format * @param int<0,1> $form Type of formatting: 1=HTML, 0=no formatting (no by default) - * @param Translate|string $outlangs Object langs for output. '' use default lang. 'none' use international separators. + * @param Translate|string|null $outlangs Object langs for output. '' use default lang. 'none' use international separators. * @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 accuracy) before being inserted into database or after a computation, so this parameter should be useless. * @param int $rounding MINIMUM number of decimal to show: 0=no change, -1=we use min($conf->global->MAIN_MAX_DECIMALS_UNIT,$conf->global->MAIN_MAX_DECIMALS_TOT) * @param int|string $forcerounding MAXIMUM number of decimal to forcerounding decimal: -1=no change, 'MU' or 'MT' or a numeric to round to MU or MT or to a given number of decimal @@ -6298,7 +6353,7 @@ function price($amount, $form = 0, $outlangs = '', $trunc = 1, $rounding = -1, $ $thousand = ' '; // If $outlangs not forced, we use use language - if (!is_object($outlangs)) { + if (!($outlangs instanceof Translate)) { $outlangs = $langs; } @@ -6538,17 +6593,17 @@ function showDimensionInBestUnit($dimension, $unit, $type, $outputlangs, $round require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; if (($forceunitoutput == 'no' && $dimension < 1 / 10000 && $unit < 90) || (is_numeric($forceunitoutput) && $forceunitoutput == -6)) { - $dimension = $dimension * 1000000; + $dimension *= 1000000; $unit = $unit - 6; } elseif (($forceunitoutput == 'no' && $dimension < 1 / 10 && $unit < 90) || (is_numeric($forceunitoutput) && $forceunitoutput == -3)) { - $dimension = $dimension * 1000; - $unit = $unit - 3; + $dimension *= 1000; + $unit -= 3; } elseif (($forceunitoutput == 'no' && $dimension > 100000000 && $unit < 90) || (is_numeric($forceunitoutput) && $forceunitoutput == 6)) { - $dimension = $dimension / 1000000; - $unit = $unit + 6; + $dimension /= 1000000; + $unit += 6; } elseif (($forceunitoutput == 'no' && $dimension > 100000 && $unit < 90) || (is_numeric($forceunitoutput) && $forceunitoutput == 3)) { - $dimension = $dimension / 1000; - $unit = $unit + 3; + $dimension /= 1000; + $unit += 3; } // Special case when we want output unit into pound or ounce /* TODO @@ -7340,7 +7395,7 @@ function yn($yesno, $case = 1, $color = 0) * @param int $level Level of subdirs to return (1, 2 or 3 levels). (deprecated, global option will be used in future) * @param int $alpha 0=Keep number only to forge path, 1=Use alpha part after the - (By default, use 0). (deprecated, global option will be used in future) * @param int $withoutslash 0=With slash at end (except if '/', we return ''), 1=without slash at end - * @param Object $object Object to use to get ref to forge the path. + * @param ?CommonObject $object Object to use to get ref to forge the path. * @param string $modulepart Type of object ('invoice_supplier, 'donation', 'invoice', ...'). Use '' for autodetect from $object. * @return string Dir to use ending. Example '' or '1/' or '1/2/' * @see getMultiDirOuput() @@ -8975,8 +9030,8 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, * $mesg = make_substitutions($mesg, $substitutionarray, $langs); * * @param string $text Source string in which we must do substitution - * @param array $substitutionarray Array with key->val to substitute. Example: array('__MYKEY__' => 'MyVal', ...) - * @param Translate $outputlangs Output language + * @param array $substitutionarray Array with key->val to substitute. Example: array('__MYKEY__' => 'MyVal', ...) + * @param ?Translate $outputlangs Output language * @param int $converttextinhtmlifnecessary 0=Convert only value into HTML if text is already in HTML * 1=Will also convert initial $text into HTML if we try to insert one value that is HTML * @return string Output string after substitutions @@ -9587,9 +9642,8 @@ function dol_htmloutput_errors($mesgstring = '', $mesgarray = array(), $keepembe } /** - * Advanced sort array by second index function, which produces ascending (default) - * or descending output and uses optionally natural case insensitive sorting (which - * can be optionally case sensitive as well). + * Advanced sort array by the value of a given key, which produces ascending (default) or descending + * output and uses optionally natural case insensitive sorting (which can be optionally case sensitive as well). * * @param array $array Array to sort (array of array('key1'=>val1,'key2'=>val2,'key3'...) or array of objects) * @param string $index Key in array to use for sorting criteria @@ -9598,7 +9652,7 @@ function dol_htmloutput_errors($mesgstring = '', $mesgarray = array(), $keepembe * If values are numeric (I said value not type): 0=Use numeric order (even if type is string) so use a "natural" sort, 1=use "natural" sort too (same than 0), -1=Force alphabetical order * @param int $case_sensitive 1=sort is case sensitive, 0=not case sensitive * @param int $keepindex If 0 and index key of array to sort is a numeric, then index will be rewritten. If 1 or index key is not numeric, key for index is kept after sorting. - * @return array Sorted array + * @return array Return the sorted array (the source array is not modified !) */ function dol_sort_array(&$array, $index, $order = 'asc', $natsort = 0, $case_sensitive = 0, $keepindex = 0) { @@ -9871,7 +9925,7 @@ function verifCond($strToEvaluate, $onlysimplestring = '1') * @param string $onlysimplestring '0' (deprecated, do not use it anymore)=Accept all chars, * '1' (most common use)=Accept only simple string with char 'a-z0-9\s^$_+-.*>&|=!?():"\',/@';', * '2' (used for example for the compute property of extrafields)=Accept also '[]' - * @return mixed Nothing or return result of eval + * @return void|string Nothing or return result of eval (even if type can be int, it is safer to assume string and find all potential typing issues as abs(dol_eval(...)). * @see verifCond() * @phan-suppress PhanPluginUnsafeEval */ @@ -12117,7 +12171,7 @@ function dolGetButtonTitle($label, $helpText = '', $iconClass = 'fa fa-file', $u * 'action', 'facture', 'project', 'project_task' or * 'myobject@mymodule' or * 'myobject_mysubobject' (where mymodule = myobject, like 'project_task') - * @return array array('module'=>, 'classpath'=>, 'element'=>, 'subelement'=>, 'classfile'=>, 'classname'=>, 'dir_output'=>) + * @return array{module:string,element:string,table_element:string,subelement:string,classpath:string,classfile:string,classname:string,dir_output:string} array('module'=>, 'classpath'=>, 'element'=>, 'subelement'=>, 'classfile'=>, 'classname'=>, 'dir_output'=>) * @see fetchObjectByElement(), getMultiDirOutput() */ function getElementProperties($elementType) @@ -12149,6 +12203,17 @@ function getElementProperties($elementType) $subelement = $regs[2]; } + // Object lines will use parent classpath and module ref + if (substr($elementType, -3) == 'det') { + $module = preg_replace('/det$/', '', $element); + $subelement = preg_replace('/det$/', '', $subelement); + $classpath = $module.'/class'; + $classfile = $module; + $classname = preg_replace('/det$/', 'Line', $element); + if (in_array($module, array('expedition', 'propale', 'facture', 'contrat', 'fichinter', 'commandefournisseur'))) { + $classname = preg_replace('/det$/', 'Ligne', $element); + } + } // For compatibility and to work with non standard path if ($elementType == "action") { $classpath = 'comm/action/class'; @@ -12479,6 +12544,7 @@ function fetchObjectByElement($element_id, $element_type, $element_ref = '', $us if (class_exists($element_prop['classname'])) { $className = $element_prop['classname']; $objecttmp = new $className($db); + '@phan-var-force CommonObject $objecttmp'; if ($element_id > 0 || !empty($element_ref)) { $ret = $objecttmp->fetch($element_id, $element_ref); @@ -12572,16 +12638,17 @@ function getNonce() /** * Start a table with headers and a optional clickable number (don't forget to use "finishSimpleTable()" after the last table row) * - * @param string $header The first left header of the table (automatic translated) - * @param string $link (optional) The link to a internal dolibarr page, when click on the number (without the first "/") - * @param string $arguments (optional) Additional arguments for the link (e.g. "search_status=0") - * @param integer $emptyRows (optional) The count of empty rows after the first header - * @param integer $number (optional) The number that is shown right after the first header, when not set the link is shown on the right side of the header as "FullList" + * @param string $header The first left header of the table (automatic translated) + * @param string $link (optional) The link to a internal dolibarr page, when click on the number (without the first "/") + * @param string $arguments (optional) Additional arguments for the link (e.g. "search_status=0") + * @param integer $emptyRows (optional) The count of empty columns after the first column + * @param integer $number (optional) The number that is shown right after the first header, when not set the link is shown on the right side of the header as "FullList" + * @param string $pictofulllist (optional) The picto to use for the full list link * @return void * * @see finishSimpleTable() */ -function startSimpleTable($header, $link = "", $arguments = "", $emptyRows = 0, $number = -1) +function startSimpleTable($header, $link = "", $arguments = "", $emptyRows = 0, $number = -1, $pictofulllist = '') { global $langs; @@ -12625,7 +12692,12 @@ function startSimpleTable($header, $link = "", $arguments = "", $emptyRows = 0, print ''; } - print $langs->trans("FullList"); + if ($pictofulllist) { + print img_picto($langs->trans("FullList"), $pictofulllist); + } else { + print $langs->trans("FullList"); + } + print ''; print ''; } @@ -12869,7 +12941,7 @@ function forgeSQLFromUniversalSearchCriteria($filter, &$errorstr = '', $noand = * This is used to output the search criteria in an UFS (Universal Filter Syntax) input component. * * @param string $sqlfilters Universal SQL filter string. Must have been trimmed before. - * @return array Array of AND + * @return string[] Array of AND */ function dolForgeExplodeAnd($sqlfilters) { @@ -12995,7 +13067,7 @@ function dolCheckFilters($sqlfilters, &$error = '', &$parenthesislevel = 0) * Function to forge a SQL criteria from a Dolibarr filter syntax string. * This method is called by forgeSQLFromUniversalSearchCriteria() * - * @param array $matches Array of found string by regex search. Example: "t.ref:like:'SO-%'" or "t.date_creation:<:'20160101'" or "t.nature:is:NULL" + * @param string[] $matches Array of found string by regex search. Example: "t.ref:like:'SO-%'" or "t.date_creation:<:'20160101'" or "t.nature:is:NULL" * @return string Forged criteria. Example: "" or "()" */ function dolForgeDummyCriteriaCallback($matches) @@ -13016,7 +13088,7 @@ function dolForgeDummyCriteriaCallback($matches) * Function to forge a SQL criteria from a Dolibarr filter syntax string. * This method is called by forgeSQLFromUniversalSearchCriteria() * - * @param array $matches Array of found string by regex search. + * @param string[] $matches Array of found string by regex search. * Example: "t.ref:like:'SO-%'" or "t.date_creation:<:'20160101'" or "t.date_creation:<:'2016-01-01 12:30:00'" or "t.nature:is:NULL" * @return string Forged criteria. Example: "t.field LIKE 'abc%'" */ @@ -13097,7 +13169,7 @@ function dolForgeCriteriaCallback($matches) * Get timeline icon * * @param ActionComm $actionstatic actioncomm - * @param array $histo histo + * @param array $histo histo * @param int $key key * @return string String with timeline icon * @deprecated Use actioncomm->getPictoType() instead @@ -13164,7 +13236,7 @@ function getTimelineIcon($actionstatic, &$histo, $key) * getActionCommEcmList * * @param ActionComm $object Object ActionComm - * @return array Array of documents in index table + * @return array Array of documents in index table */ function getActionCommEcmList($object) { @@ -13191,23 +13263,22 @@ function getActionCommEcmList($object) } - /** - * Show html area with actions in messaging format. - * Note: Global parameter $param must be defined. + * Show html area with actions in messaging format. + * Note: Global parameter $param must be defined. * - * @param Conf $conf Object conf - * @param Translate $langs Object langs - * @param DoliDB $db Object db - * @param mixed $filterobj Filter on object Adherent|Societe|Project|Product|CommandeFournisseur|Dolresource|Ticket|... to list events linked to an object - * @param Contact|null $objcon Filter on object contact to filter events on a contact - * @param int $noprint Return string but does not output it - * @param string $actioncode Filter on actioncode - * @param string $donetodo Filter on event 'done' or 'todo' or ''=nofilter (all). - * @param array $filters Filter on other fields - * @param string $sortfield Sort field - * @param string $sortorder Sort order - * @return string|void Return html part or void if noprint is 1 + * @param Conf $conf Object conf + * @param Translate $langs Object langs + * @param DoliDB $db Object db + * @param ?CommonObject $filterobj Filter on object Adherent|Societe|Project|Product|CommandeFournisseur|Dolresource|Ticket|... to list events linked to an object + * @param ?Contact $objcon Filter on object contact to filter events on a contact + * @param int $noprint Return string but does not output it + * @param string $actioncode Filter on actioncode + * @param string $donetodo Filter on event 'done' or 'todo' or ''=nofilter (all). + * @param array $filters Filter on other fields + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @return string|void Return html part or void if noprint is 1 */ function show_actions_messaging($conf, $langs, $db, $filterobj, $objcon = null, $noprint = 0, $actioncode = '', $donetodo = 'done', $filters = array(), $sortfield = 'a.datep,a.id', $sortorder = 'DESC') { @@ -13237,6 +13308,9 @@ function show_actions_messaging($conf, $langs, $db, $filterobj, $objcon = null, } $sortfield_new = implode(',', $sortfield_new_list); + $sql = null; + $sql2 = null; + if (isModEnabled('agenda')) { // Search histo on actioncomm if (is_object($objcon) && $objcon->id > 0) { @@ -13272,11 +13346,8 @@ function show_actions_messaging($conf, $langs, $db, $filterobj, $objcon = null, $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on u.rowid = a.fk_user_action"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_actioncomm as c ON a.fk_action = c.id"; - if (get_class($filterobj) !== 'User') { - $force_filter_contact = false; - } else { - $force_filter_contact = true; - } + $force_filter_contact = $filterobj instanceof User; + if (is_object($objcon) && $objcon->id > 0) { $force_filter_contact = true; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."actioncomm_resources as r ON a.id = r.fk_actioncomm"; @@ -13433,7 +13504,6 @@ function show_actions_messaging($conf, $langs, $db, $filterobj, $objcon = null, while ($i < $imaxinloop) { $obj = $db->fetch_object($resql); - '@phan-var-force array{apicto:string,contact_id:string,dp:string,dp2:string,firstname:string,label:string,message:string,msg_from:string,ref:string,type:string,user_lastname:string} $obj'; if ($obj->type == 'action') { $contactaction = new ActionComm($db); $contactaction->id = $obj->id; @@ -13599,20 +13669,20 @@ function show_actions_messaging($conf, $langs, $db, $filterobj, $objcon = null, if ($donetodo) { $tmp = ''; - if (get_class($filterobj) == 'Societe') { + if ($filterobj instanceof Societe) { $tmp .= ''; } - if (get_class($filterobj) == 'User') { + if ($filterobj instanceof User) { $tmp .= ''; } $tmp .= ($donetodo != 'done' ? $langs->trans("ActionsToDoShort") : ''); $tmp .= ($donetodo != 'done' && $donetodo != 'todo' ? ' / ' : ''); $tmp .= ($donetodo != 'todo' ? $langs->trans("ActionsDoneShort") : ''); //$out.=$langs->trans("ActionsToDoShort").' / '.$langs->trans("ActionsDoneShort"); - if (get_class($filterobj) == 'Societe') { + if ($filterobj instanceof Societe) { $tmp .= ''; } - if (get_class($filterobj) == 'User') { + if ($filterobj instanceof User) { $tmp .= ''; } $out .= getTitleFieldOfList($tmp); @@ -13839,6 +13909,7 @@ function show_actions_messaging($conf, $langs, $db, $filterobj, $objcon = null, $conf->cache['contact'][$histo[$key]['contact_id']] = $contact; } else { $contact = $conf->cache['contact'][$histo[$key]['contact_id']]; + $result = ($contact instanceof Contact) ? $contact->id : 0; } if ($result > 0) { diff --git a/htdocs/core/lib/images.lib.php b/htdocs/core/lib/images.lib.php index 258317756d0..19c0c75b9c5 100644 --- a/htdocs/core/lib/images.lib.php +++ b/htdocs/core/lib/images.lib.php @@ -661,7 +661,7 @@ function vignette($file, $maxWidth = 160, $maxHeight = 120, $extName = '_small', if ($exifAngle) { $rotated = false; - if ($infoImg[2] === 'IMAGETYPE_PNG') { // In fact there is no exif on PNG but just in case + if ($infoImg[2] === IMAGETYPE_PNG) { // In fact there is no exif on PNG but just in case imagealphablending($img, false); imagesavealpha($img, true); $rotated = imagerotate($img, $exifAngle, imagecolorallocatealpha($img, 0, 0, 0, 127)); diff --git a/htdocs/core/lib/invoice.lib.php b/htdocs/core/lib/invoice.lib.php index 1efc998a384..95ed5249031 100644 --- a/htdocs/core/lib/invoice.lib.php +++ b/htdocs/core/lib/invoice.lib.php @@ -710,7 +710,9 @@ function getDraftSupplierTable($maxCount = 500, $socid = 0) $facturesupplierstatic->ref_supplier = $obj->ref_supplier; $facturesupplierstatic->type = $obj->type; $facturesupplierstatic->statut = $obj->status; + $facturesupplierstatic->statusi = $obj->status; $facturesupplierstatic->paye = $obj->paye; + $facturesupplierstatic->paid = $obj->paye; $companystatic->id = $obj->socid; $companystatic->name = $obj->name; @@ -931,7 +933,9 @@ function getPurchaseInvoiceLatestEditTable($maxCount = 5, $socid = 0) $objectstatic->id = $obj->rowid; $objectstatic->ref = $obj->ref; $objectstatic->paye = $obj->paye; + $objectstatic->paid = $obj->paye; $objectstatic->statut = $obj->status; + $objectstatic->status = $obj->status; $objectstatic->total_ht = $obj->total_ht; $objectstatic->total_tva = $obj->total_tva; $objectstatic->total_ttc = $obj->total_ttc; @@ -1260,6 +1264,8 @@ function getPurchaseInvoiceUnpaidOpenTable($maxCount = 500, $socid = 0) $facstatic->total_tva = $obj->total_tva; $facstatic->total_ttc = $obj->total_ttc; $facstatic->statut = $obj->status; + $facstatic->status = $obj->status; + $facstatic->paid = $obj->paye; $facstatic->paye = $obj->paye; $societestatic->id = $obj->socid; diff --git a/htdocs/core/lib/mailmanspip.lib.php b/htdocs/core/lib/mailmanspip.lib.php index 7ddc9b68615..5449da31228 100644 --- a/htdocs/core/lib/mailmanspip.lib.php +++ b/htdocs/core/lib/mailmanspip.lib.php @@ -33,12 +33,12 @@ function mailmanspip_admin_prepare_head() return array( array( DOL_URL_ROOT.'/admin/mailman.php', - $langs->trans('Mailman'), + 'Mailman', 'mailman' ), array( DOL_URL_ROOT.'/admin/spip.php', - $langs->trans('SPIP'), + 'SPIP', 'spip' ) ); diff --git a/htdocs/core/lib/member.lib.php b/htdocs/core/lib/member.lib.php index 8283de2dc75..ce5294d3ff9 100644 --- a/htdocs/core/lib/member.lib.php +++ b/htdocs/core/lib/member.lib.php @@ -3,6 +3,7 @@ * Copyright (C) 2015-2016 Alexandre Spangaro * Copyright (C) 2015 Raphaël Doursenaud * Copyright (C) 2017 Regis Houssin + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,8 +28,8 @@ /** * Return array head with list of tabs to view object information * - * @param Adherent $object Member - * @return array head + * @param Adherent $object Member + * @return array> head links */ function member_prepare_head(Adherent $object) { @@ -128,7 +129,7 @@ function member_prepare_head(Adherent $object) // Show agenda tab $head[$h][0] = DOL_URL_ROOT.'/adherents/agenda.php?id='.$object->id; $head[$h][1] = $langs->trans("Events"); - if (isModEnabled('agenda')&& ($user->hasRight('agenda', 'myactions', 'read') || $user->hasRight('agenda', 'allactions', 'read'))) { + if (isModEnabled('agenda') && ($user->hasRight('agenda', 'myactions', 'read') || $user->hasRight('agenda', 'allactions', 'read'))) { $nbEvent = 0; // Enable caching of thirdparty count actioncomm require_once DOL_DOCUMENT_ROOT.'/core/lib/memory.lib.php'; @@ -170,7 +171,7 @@ function member_prepare_head(Adherent $object) * Return array head with list of tabs to view object information * * @param AdherentType $object Member - * @return array head + * @return array> head links */ function member_type_prepare_head(AdherentType $object) { @@ -216,7 +217,7 @@ function member_type_prepare_head(AdherentType $object) /** * Return array head with list of tabs to view object information * - * @return array head + * @return array> head links */ function member_admin_prepare_head() { @@ -278,7 +279,7 @@ function member_admin_prepare_head() * Return array head with list of tabs to view object stats information * * @param Adherent $object Member or null - * @return array head + * @return array> head links */ function member_stats_prepare_head($object) { @@ -332,7 +333,7 @@ function member_stats_prepare_head($object) * Return array head with list of tabs to view object information * * @param Subscription $object Subscription - * @return array head + * @return array> head links */ function subscription_prepare_head(Subscription $object) { diff --git a/htdocs/core/lib/modulebuilder.lib.php b/htdocs/core/lib/modulebuilder.lib.php index 0250110d229..4e5b480eb73 100644 --- a/htdocs/core/lib/modulebuilder.lib.php +++ b/htdocs/core/lib/modulebuilder.lib.php @@ -31,9 +31,9 @@ * @param string $objectname Name of object * @param string $newmask New mask * @param string $readdir Directory source (use $destdir when not defined) - * @param array $addfieldentry Array of 1 field entry to add array('key'=>,'type'=>,''label'=>,'visible'=>,'enabled'=>,'position'=>,'notnull'=>','index'=>,'searchall'=>,'comment'=>,'help'=>,'isameasure') + * @param array{}|array{name:string,key:string,type:string,label:string,picot?:string,enabled:int<0,1>,notnull:int<0,1>,position:int,visible:int,noteditable?:int<0,1>,alwayseditable?:int<0,1>,default?:string,index?:int,foreignkey?:string,searchall?:int,isameasure?:int<0,1>,css?:string,cssview?:string,csslist?:string,help?:string,showoncombobox?:int<0,1>,disabled?:int<0,1>,autofocusoncreate?:int<0,1>,arrayofkeyval?:array,validate?:int<0,1>,comment?:string} $addfieldentry Array of 1 field entry to add * @param string $delfieldentry Id of field to remove - * @return int|object Return integer <=0 if KO, Object if OK + * @return int<-7,-1>|CommonObject Return integer <=0 if KO, Object if OK * @see rebuildObjectSql() */ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir = '', $addfieldentry = array(), $delfieldentry = '') @@ -89,6 +89,7 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir = } else { return -4; } + '@phan-var-force CommonObject $object'; // Backup old file dol_copy($pathoffiletoedittarget, $pathoffiletoedittarget.'.back', $newmask, 1); @@ -138,7 +139,7 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir = if (!empty($val['alwayseditable'])) { $texttoinsert .= ' "alwayseditable"=>"'.dol_escape_php($val['alwayseditable']).'",'; } - if (!empty($val['default']) || (isset($val['default']) && $val['default'] === '0')) { + if (array_key_exists('default', $val) && (!empty($val['default']) || $val['default'] === '0')) { $texttoinsert .= ' "default"=>"'.dol_escape_php($val['default']).'",'; } if (!empty($val['index'])) { @@ -549,11 +550,11 @@ function compareFirstValue($a, $b) * @param string $file filename or path * @param array $permissions permissions existing in file * @param int|null $key key for permission needed - * @param array|null $right $right to update or add + * @param array{0:string,1:string}|null $right $right to update or add * @param string|null $objectname name of object * @param string|null $module name of module * @param int<-2,2> $action 0 for delete, 1 for add, 2 for update, -1 when delete object completely, -2 for generate rights after add - * @return int 1 if OK,-1 if KO + * @return int<-1,1> 1 if OK,-1 if KO */ function reWriteAllPermissions($file, $permissions, $key, $right, $objectname, $module, $action) { @@ -672,7 +673,7 @@ function reWriteAllPermissions($file, $permissions, $key, $right, $objectname, $ * Converts a formatted properties string into an associative array. * * @param string $string The formatted properties string. - * @return array The resulting associative array. + * @return array The resulting associative array. */ function parsePropertyString($string) { @@ -874,7 +875,7 @@ function getFromFile($file, $start, $end) * Write all permissions of each object in AsciiDoc format * @param string $file path of the class * @param string $destfile file where write table of permissions - * @return int 1 if OK, -1 if KO + * @return int<-1,1> 1 if OK, -1 if KO */ function writePermsInAsciiDoc($file, $destfile) { @@ -959,9 +960,9 @@ function writePermsInAsciiDoc($file, $destfile) * * @param string $srcfile Source file to use as example * @param string $file Path of modified file - * @param array $objects Array of objects in the module + * @param string[] $objects Array of objects in the module * @param string $modulename Name of module - * @return int Return 1 if OK, -1 if KO + * @return int<-1,1> Return 1 if OK, -1 if KO */ function addObjectsToApiFile($srcfile, $file, $objects, $modulename) { @@ -1044,9 +1045,9 @@ function addObjectsToApiFile($srcfile, $file, $objects, $modulename) * Remove Object variables and methods from API_Module File * * @param string $file File api module - * @param array $objects Array of objects in the module + * @param string[] $objects Array of objects in the module * @param string $objectname Name of object want to remove - * @return int 1 if OK, -1 if KO + * @return int<-1,1> 1 if OK, -1 if KO */ function removeObjectFromApiFile($file, $objects, $objectname) { @@ -1091,12 +1092,12 @@ function removeObjectFromApiFile($file, $objects, $objectname) /** - * @param string $file path of filename - * @param mixed $menus all menus for module - * @param mixed|null $menuWantTo menu get for do actions - * @param int|null $key key for the concerned menu - * @param int $action for specify what action (0 = delete, 1 = add, 2 = update, -1 = when delete object) - * @return int 1 if OK, -1 if KO + * @param string $file path of filename + * @param array $menus all menus for module + * @param mixed|null $menuWantTo menu get for do actions + * @param int|null $key key for the concerned menu + * @param int<-1,2> $action for specify what action (0 = delete, 1 = add, 2 = update, -1 = when delete object) + * @return int<-1,1> 1 if OK, -1 if KO */ function reWriteAllMenus($file, $menus, $menuWantTo, $key, $action) { @@ -1194,7 +1195,7 @@ function reWriteAllMenus($file, $menus, $menuWantTo, $key, $action) * * @param string $module The name of the module. * @param string $file The path to the module descriptor file. - * @param array $dicts The dictionary data to be updated. + * @param array> $dicts The dictionary data to be updated. * @return int Returns the number of replacements made in the file. */ function updateDictionaryInFile($module, $file, $dicts) @@ -1267,8 +1268,8 @@ function updateDictionaryInFile($module, $file, $dicts) * @param string $modulename The lowercase name of the module for which the dictionary table is being created. * @param string $file The file path to the Dolibarr module builder file where the dictionaries are defined. * @param string $namedic The name of the dictionary, which will also be used as the base for the table name. - * @param array|null $dictionnaires An optional array containing pre-existing dictionary data, including 'tabname', 'tablib', 'tabsql', etc. - * @return int|void Return int < 0 if error, return nothing on success + * @param array> $dictionnaires An optional array containing pre-existing dictionary data, including 'tabname', 'tablib', 'tabsql', etc. + * @return int<-1,-1>|void Return int < 0 if error, return nothing on success */ function createNewDictionnary($modulename, $file, $namedic, $dictionnaires = null) { @@ -1288,11 +1289,11 @@ function createNewDictionnary($modulename, $file, $namedic, $dictionnaires = nul } $columns = array( - 'rowid' => array('type' => 'integer', 'value' => 11, 'extra' => 'AUTO_INCREMENT PRIMARY KEY'), - 'code' => array('type' => 'varchar', 'value' => 255, 'null'=>'NOT NULL'), - 'label' => array('type' => 'varchar', 'value' => 255, 'null'=>'NOT NULL'), - 'position' => array('type' => 'integer', 'value' => 11, 'null'=>'NULL'), - 'use_default' => array('type' => 'varchar', 'value' => 11, 'default'=>'1'), + 'rowid' => array('type' => 'integer', 'value' => 11, 'extra' => 'AUTO_INCREMENT'), + 'code' => array('type' => 'varchar', 'value' => 255, 'null' => 'NOT NULL'), + 'label' => array('type' => 'varchar', 'value' => 255, 'null' => 'NOT NULL'), + 'position' => array('type' => 'integer', 'value' => 11, 'null' => 'NULL'), + 'use_default' => array('type' => 'varchar', 'value' => 11, 'default' => '1'), 'active' => array('type' => 'integer', 'value' => 3) ); @@ -1310,9 +1311,7 @@ function createNewDictionnary($modulename, $file, $namedic, $dictionnaires = nul } // check if tablename exist in Database and create it if not - // @FIXME We must use $db->DDLDescTable($table) to know if a table exists. - $query = "SHOW TABLES LIKE '" . $db->escape(MAIN_DB_PREFIX.strtolower($namedic)) . "'"; - $checkTable = $db->query($query); + $checkTable = $db->DDLDescTable(MAIN_DB_PREFIX.strtolower($namedic)); if ($checkTable && $db->num_rows($checkTable) > 0) { setEventMessages($langs->trans("ErrorTableExist", $namedic), null, 'errors'); return; @@ -1350,7 +1349,7 @@ function createNewDictionnary($modulename, $file, $namedic, $dictionnaires = nul * * @param string $file_api filename or path of api * @param string $file_doc filename or path of documentation - * @return int -1 if KO, 1 if OK, 0 if nothing change + * @return int<-1,1> -1 if KO, 1 if OK, 0 if nothing change */ function writeApiUrlsInDoc($file_api, $file_doc) { diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index 0594beb7ee3..6c591eab176 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -925,7 +925,7 @@ function pdf_bank(&$pdf, $outputlangs, $curx, $cury, $account, $onlynumber = 0, $curx = $savcurx; $cury += 8; } - } else { + } elseif (!empty($account->number)) { $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent); $pdf->SetXY($curx, $cury); $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Bank").': '.$outputlangs->convToOutputCharset($account->bank), 0, 'L', 0); diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php index 9691b94642a..36af665f373 100644 --- a/htdocs/core/lib/website2.lib.php +++ b/htdocs/core/lib/website2.lib.php @@ -61,7 +61,7 @@ function dolSaveMasterFile($filemaster) function dolSavePageAlias($filealias, $object, $objectpage) { // Now create the .tpl file - dol_syslog("dolSavePageAlias We regenerate the alias page filealias=".$filealias); + dol_syslog("dolSavePageAlias We regenerate the alias page filealias=".$filealias." and a wrapper into all language subdirectories"); $aliascontent = 'lang.'/'.$filename; + dol_mkdir($dirname.'/'.$objectpage->lang, DOL_DATA_ROOT); + $aliascontent = 'SetIdentity(GETPOST('openid_identity')); - $openid_validation_result = $openid->ValidateWithServer(); + $openid_validation_result = $openid->validateWithServer(); if ($openid_validation_result === true) { // OK HERE KEY IS VALID @@ -93,7 +93,7 @@ function check_user_password_openid($usertotest, $passwordtotest, $entitytotest) //echo "INVALID AUTHORIZATION"; return false; } - } elseif ($_GET['openid_mode'] == 'cancel') { + } elseif (GETPOST('openid_mode') == 'cancel') { // User Canceled your Request //echo "USER CANCELED REQUEST"; return false; diff --git a/htdocs/core/menus/init_menu_auguria.sql b/htdocs/core/menus/init_menu_auguria.sql index d177030b841..a36047df657 100644 --- a/htdocs/core/menus/init_menu_auguria.sql +++ b/htdocs/core/menus/init_menu_auguria.sql @@ -19,7 +19,7 @@ insert into llx_menu (rowid, module, enabled, menu_handler, type, mainmenu, left insert into llx_menu (rowid, module, enabled, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity, prefix) values ( 7__+MAX_llx_menu__, 'projet', 'isModEnabled("project")', __HANDLER__, 'top', 'project', '', 0, '/projet/index.php?mainmenu=project&leftmenu=', 'Projects', -1, 'projects', '$user->hasRight("projet","lire")', '', 2, 32, __ENTITY__, ''); insert into llx_menu (rowid, module, enabled, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity, prefix) values ( 5__+MAX_llx_menu__, 'propal|commande|fournisseur|supplier_order|supplier_invoice|contrat|ficheinter', 'isModEnabled("propal") || isModEnabled("commande") || isModEnabled("supplier_order") || isModEnabled("contrat") || isModEnabled("ficheinter")', __HANDLER__, 'top', 'commercial', '', 0, '/comm/index.php?mainmenu=commercial&leftmenu=', 'Commercial', -1, 'commercial', '$user->hasRight("societe","lire") || $user->hasRight("societe","contact","lire")', '', 2, 40, __ENTITY__, ''); insert into llx_menu (rowid, module, enabled, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity, prefix) values ( 6__+MAX_llx_menu__, 'facture|don|tax|salaries|loan|banque', 'isModEnabled("comptabilite") || isModEnabled("accounting") || isModEnabled("invoice") || isModEnabled("don") || isModEnabled("tax") || isModEnabled("salaries") || isModEnabled("supplier_invoice") || isModEnabled("loan") || isModEnabled("banque")', __HANDLER__, 'top', 'billing', '', 0, '/compta/index.php?mainmenu=billing&leftmenu=', 'MenuFinancial', -1, 'compta', '$user->hasRight("facture","lire") || $user->hasRight("don","lire") || $user->hasRight("tax","charges","lire") || $user->hasRight("salaries","read") || $user->hasRight("loan","read") || $user->hasRight("banque","lire") || $user->hasRight("fournisseur","facture","lire") || $user->hasRight("supplier_invoice","read")', '', 2, 50, __ENTITY__, ''); -insert into llx_menu (rowid, module, enabled, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity, prefix) values ( 14__+MAX_llx_menu__, 'banque|prelevement', 'isModEnabled("banque") || isModEnabled("prelevement")', __HANDLER__, 'top', 'bank', '', 0, '/compta/bank/list.php?mainmenu=bank&leftmenu=bank', 'MenuBankCash', -1, 'banks', '$user->hasRight("banque","lire") || $user->hasRight("prelevement","bons","lire")', '', 0, 52, __ENTITY__, ''); +insert into llx_menu (rowid, module, enabled, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity, prefix) values ( 14__+MAX_llx_menu__, 'banque|prelevement', 'isModEnabled("banque") || isModEnabled("prelevement")', __HANDLER__, 'top', 'bank', '', 0, '/compta/bank/list.php?search_status=opened&mainmenu=bank&leftmenu=bank', 'MenuBankCash', -1, 'banks', '$user->hasRight("banque","lire") || $user->hasRight("prelevement","bons","lire")', '', 0, 52, __ENTITY__, ''); insert into llx_menu (rowid, module, enabled, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity, prefix) values ( 9__+MAX_llx_menu__, 'comptabilite|accounting|asset', 'isModEnabled("comptabilite") || isModEnabled("accounting") || isModEnabled("asset")', __HANDLER__, 'top', 'accountancy', '', 0, '/compta/index.php?mainmenu=accountancy&leftmenu=accountancy', 'MenuAccountancy', -1, 'main', '$user->hasRight("compta","resultat","lire") || $user->hasRight("accounting","mouvements","lire") || $user->hasRight("asset","read")', '', 2, 54, __ENTITY__, ''); insert into llx_menu (rowid, module, enabled, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity, prefix) values ( 8__+MAX_llx_menu__, '', '', __HANDLER__, 'top', 'tools', '', 0, '/core/tools.php?mainmenu=tools&leftmenu=', 'Tools', -1, 'other', '', '', 2, 90, __ENTITY__, ''); insert into llx_menu (rowid, module, enabled, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity, prefix) values ( 13__+MAX_llx_menu__, 'adherent', 'isModEnabled("adherent")', __HANDLER__, 'top', 'members', '', 0, '/adherents/index.php?mainmenu=members&leftmenu=', 'Members', -1, 'members', '$user->hasRight("adherent","lire")', '', 2, 19, __ENTITY__, ''); @@ -119,7 +119,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("societe") && isModEnabled("categorie")', __HANDLER__, 'left', 671__+MAX_llx_menu__, 'companies', '', 670__+MAX_llx_menu__, '/categories/card.php?mainmenu=companies&action=create&type=4', 'NewCategory', 1, 'categories', '$user->hasRight("categorie","creer")', '', 2, 0, __ENTITY__); -- Product - Product -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("product")', __HANDLER__, 'left', 2800__+MAX_llx_menu__, 'products', 'product', 3__+MAX_llx_menu__, '/product/index.php?mainmenu=products&leftmenu=product&type=0', 'Products', 0, 'products', '$user->rights->produit->lire', '', 2, 0, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("product")', __HANDLER__, 'left', 2800__+MAX_llx_menu__, 'products', 'product', 3__+MAX_llx_menu__, '/product/index.php?mainmenu=products&leftmenu=product', 'Products', 0, 'products', '$user->rights->produit->lire', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("product")', __HANDLER__, 'left', 2801__+MAX_llx_menu__, 'products', '', 2800__+MAX_llx_menu__, '/product/card.php?mainmenu=products&leftmenu=product&action=create&type=0', 'NewProduct', 1, 'products', '$user->rights->produit->creer', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("product")', __HANDLER__, 'left', 2802__+MAX_llx_menu__, 'products', '', 2800__+MAX_llx_menu__, '/product/list.php?mainmenu=products&leftmenu=product&type=0', 'List', 1, 'products', '$user->rights->produit->lire', '', 2, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("product")', __HANDLER__, 'left', 2803__+MAX_llx_menu__, 'products', '', 2800__+MAX_llx_menu__, '/product/reassort.php?mainmenu=products&type=0', 'MenuStocks', 1, 'products', '$user->rights->produit->lire && $user->rights->stock->lire', '', 2, 4, __ENTITY__); @@ -131,13 +131,13 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("propal")', __HANDLER__, 'left', 2804__+MAX_llx_menu__, 'products', '', 2800__+MAX_llx_menu__, '/product/stats/card.php?mainmenu=products&id=all&leftmenu=stats&type=0', 'Statistics', 1, 'main', '$user->rights->produit->lire', '', 2, 8, __ENTITY__); -- Product - Services -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("service")', __HANDLER__, 'left', 2900__+MAX_llx_menu__, 'products', 'service', 3__+MAX_llx_menu__, '/product/index.php?mainmenu=products&leftmenu=service&type=1', 'Services', 0, 'products', '$user->hasRight("service","lire")', '', 2, 1, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("service")', __HANDLER__, 'left', 2900__+MAX_llx_menu__, 'products', 'service', 3__+MAX_llx_menu__, '/product/index.php?mainmenu=products&leftmenu=service', 'Services', 0, 'products', '$user->hasRight("service","lire")', '', 2, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("service")', __HANDLER__, 'left', 2901__+MAX_llx_menu__, 'products', '', 2900__+MAX_llx_menu__, '/product/card.php?mainmenu=products&leftmenu=service&action=create&type=1', 'NewService', 1, 'products', '$user->rights->service->creer', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("service")', __HANDLER__, 'left', 2902__+MAX_llx_menu__, 'products', '', 2900__+MAX_llx_menu__, '/product/list.php?mainmenu=products&leftmenu=service&type=1', 'List', 1, 'products', '$user->hasRight("service","lire")', '', 2, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("propal")', __HANDLER__, 'left', 2903__+MAX_llx_menu__, 'products', '', 2900__+MAX_llx_menu__, '/product/stats/card.php?mainmenu=products&id=all&leftmenu=stats&type=1', 'Statistics', 1, 'main', '$user->hasRight("service","lire")', '', 2, 5, __ENTITY__); -- Product - Stocks -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("stock")', __HANDLER__, 'left', 3100__+MAX_llx_menu__, 'products', 'stock', 3__+MAX_llx_menu__, '/product/stock/index.php?mainmenu=products&leftmenu=stock', 'Stock', 0, 'stocks', '$user->rights->stock->lire', '', 2, 3, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("stock")', __HANDLER__, 'left', 3100__+MAX_llx_menu__, 'products', 'stock', 3__+MAX_llx_menu__, '/product/index.php?mainmenu=products&leftmenu=stock', 'Stock', 0, 'stocks', '$user->rights->stock->lire', '', 2, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("stock")', __HANDLER__, 'left', 3101__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/card.php?mainmenu=products&action=create', 'MenuNewWarehouse', 1, 'stocks', '$user->rights->stock->creer', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("stock")', __HANDLER__, 'left', 3102__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/list.php?mainmenu=products', 'List', 1, 'stocks', '$user->rights->stock->lire', '', 2, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("stock")', __HANDLER__, 'left', 3104__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/movement_list.php?mainmenu=products', 'Movements', 1, 'stocks', '$user->rights->stock->mouvement->lire', '', 2, 3, __ENTITY__); @@ -400,7 +400,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("prelevement") && $leftmenu=="banktransfer"', __HANDLER__, 'left', 2517__+MAX_llx_menu__, 'accountancy', '', 2510__+MAX_llx_menu__, '/compta/prelevement/stats.php?mainmenu=bank&leftmenu=banktransfer&type=bank-transfer', 'Statistics', 1, 'withdrawals', '$user->hasRight("prelevement","bons","lire")', '', 2, 6, __ENTITY__); -- Bank -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("banque")', __HANDLER__, 'left', 2600__+MAX_llx_menu__, 'accountancy', 'bank', 14__+MAX_llx_menu__, '/compta/bank/list.php?mainmenu=bank&leftmenu=bank', 'MenuBankCash', 0, 'banks', '$user->hasRight("banque","lire")', '', 0, 1, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("banque")', __HANDLER__, 'left', 2600__+MAX_llx_menu__, 'accountancy', 'bank', 14__+MAX_llx_menu__, '/compta/bank/list.php?search_status=opened&mainmenu=bank&leftmenu=bank', 'MenuBankCash', 0, 'banks', '$user->hasRight("banque","lire")', '', 0, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("banque") && ($leftmenu=="bank" || $leftmenu=="checks" || $leftmenu=="withdraw")', __HANDLER__, 'left', 2601__+MAX_llx_menu__, 'accountancy', '', 2600__+MAX_llx_menu__, '/compta/bank/card.php?mainmenu=bank&action=create&leftmenu=bank', 'MenuNewFinancialAccount', 1, 'banks', '$user->hasRight("banque","configurer")', '', 0, 0, __ENTITY__); -- insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("banque") && ($leftmenu=="bank" || $leftmenu=="checks" || $leftmenu=="withdraw")', __HANDLER__, 'left', 2602__+MAX_llx_menu__, 'accountancy', '', 2600__+MAX_llx_menu__, '/compta/bank/categ.php?mainmenu=bank&leftmenu=bank', 'Rubriques', 1, 'categories', '$user->hasRight("banque","configurer")', '', 0, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("banque") && ($leftmenu=="bank" || $leftmenu=="checks" || $leftmenu=="withdraw")', __HANDLER__, 'left', 2603__+MAX_llx_menu__, 'accountancy', '', 2600__+MAX_llx_menu__, '/compta/bank/bankentries_list.php?mainmenu=bank&leftmenu=bank', 'ListTransactions', 1, 'banks', '$user->hasRight("banque","lire")', '', 0, 2, __ENTITY__); diff --git a/htdocs/core/menus/standard/auguria.lib.php b/htdocs/core/menus/standard/auguria.lib.php index c12fbc08c45..0d91d521370 100644 --- a/htdocs/core/menus/standard/auguria.lib.php +++ b/htdocs/core/menus/standard/auguria.lib.php @@ -374,7 +374,7 @@ function print_left_auguria_menu($db, $menu_array_before, $menu_array_after, &$t $i = 0; if ($numr > 0) { - $newmenu->add('/compta/bank/list.php', $langs->trans("BankAccounts"), 0, $user->hasRight('banque', 'lire')); + $newmenu->add('/compta/bank/list.php?search_status=opened', $langs->trans("BankAccounts"), 0, $user->hasRight('banque', 'lire')); } while ($i < $numr) { diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 0349eef17ad..d41472c6528 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -334,7 +334,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = ); $menu_arr[] = array( 'name' => 'Bank', - 'link' => '/compta/bank/list.php?mainmenu=bank&leftmenu=', + 'link' => '/compta/bank/list.php?mainmenu=bank&leftmenu=&search_status=opened', 'title' => "MenuBankCash", 'level' => 0, 'enabled' => $showmode = isVisibleToUserType($type_user, $tmpentry, $listofmodulesforexternal), @@ -1989,10 +1989,10 @@ function get_left_menu_bank($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = // Bank-Cash account if (isModEnabled('bank')) { - $newmenu->add("/compta/bank/list.php?leftmenu=bank&mainmenu=bank", $langs->trans("MenuBankCash"), 0, $user->hasRight('banque', 'lire'), '', $mainmenu, 'bank', 0, '', '', '', img_picto('', 'bank_account', 'class="paddingright pictofixedwidth"')); + $newmenu->add("/compta/bank/list.php?leftmenu=bank&mainmenu=bank&search_status=opened", $langs->trans("MenuBankCash"), 0, $user->hasRight('banque', 'lire'), '', $mainmenu, 'bank', 0, '', '', '', img_picto('', 'bank_account', 'class="paddingright pictofixedwidth"')); $newmenu->add("/compta/bank/card.php?action=create", $langs->trans("MenuNewFinancialAccount"), 1, $user->hasRight('banque', 'configurer')); - $newmenu->add("/compta/bank/list.php?leftmenu=bank&mainmenu=bank", $langs->trans("List"), 1, $user->hasRight('banque', 'lire'), '', $mainmenu, 'bank'); + $newmenu->add("/compta/bank/list.php?leftmenu=bank&mainmenu=bank&search_status=opened", $langs->trans("List"), 1, $user->hasRight('banque', 'lire'), '', $mainmenu, 'bank'); $newmenu->add("/compta/bank/bankentries_list.php", $langs->trans("ListTransactions"), 1, $user->hasRight('banque', 'lire')); $newmenu->add("/compta/bank/budget.php", $langs->trans("ListTransactionsByCategory"), 1, $user->hasRight('banque', 'lire')); @@ -2069,7 +2069,7 @@ function get_left_menu_products($mainmenu, &$newmenu, $usemenuhider = 1, $leftme if ($mainmenu == 'products') { // Products if (isModEnabled('product')) { - $newmenu->add("/product/index.php?leftmenu=product&type=0", $langs->trans("Products"), 0, $user->hasRight('product', 'read'), '', $mainmenu, 'product', 0, '', '', '', img_picto('', 'product', 'class="paddingright pictofixedwidth"')); + $newmenu->add("/product/index.php?leftmenu=product", $langs->trans("Products"), 0, $user->hasRight('product', 'read'), '', $mainmenu, 'product', 0, '', '', '', img_picto('', 'product', 'class="paddingright pictofixedwidth"')); $newmenu->add("/product/card.php?leftmenu=product&action=create&type=0", $langs->trans("NewProduct"), 1, $user->hasRight('product', 'creer')); $newmenu->add("/product/list.php?leftmenu=product&type=0", $langs->trans("List"), 1, $user->hasRight('product', 'read')); if (isModEnabled('stock')) { @@ -2097,7 +2097,7 @@ function get_left_menu_products($mainmenu, &$newmenu, $usemenuhider = 1, $leftme // Services if (isModEnabled('service')) { - $newmenu->add("/product/index.php?leftmenu=service&type=1", $langs->trans("Services"), 0, $user->hasRight('service', 'read'), '', $mainmenu, 'service', 0, '', '', '', img_picto('', 'service', 'class="paddingright pictofixedwidth"')); + $newmenu->add("/product/index.php?leftmenu=service", $langs->trans("Services"), 0, $user->hasRight('service', 'read'), '', $mainmenu, 'service', 0, '', '', '', img_picto('', 'service', 'class="paddingright pictofixedwidth"')); $newmenu->add("/product/card.php?leftmenu=service&action=create&type=1", $langs->trans("NewService"), 1, $user->hasRight('service', 'creer')); $newmenu->add("/product/list.php?leftmenu=service&type=1", $langs->trans("List"), 1, $user->hasRight('service', 'read')); @@ -2121,7 +2121,7 @@ function get_left_menu_products($mainmenu, &$newmenu, $usemenuhider = 1, $leftme // Warehouse if (isModEnabled('stock')) { $langs->load("stocks"); - $newmenu->add("/product/stock/index.php?leftmenu=stock", $langs->trans("Warehouses"), 0, $user->hasRight('stock', 'lire'), '', $mainmenu, 'stock', 0, '', '', '', img_picto('', 'stock', 'class="paddingright pictofixedwidth"')); + $newmenu->add("/product/index.php?leftmenu=stock", $langs->trans("Warehouses"), 0, $user->hasRight('stock', 'lire'), '', $mainmenu, 'stock', 0, '', '', '', img_picto('', 'stock', 'class="paddingright pictofixedwidth"')); $newmenu->add("/product/stock/card.php?action=create", $langs->trans("MenuNewWarehouse"), 1, $user->hasRight('stock', 'creer')); $newmenu->add("/product/stock/list.php", $langs->trans("List"), 1, $user->hasRight('stock', 'lire')); $newmenu->add("/product/stock/movement_list.php", $langs->trans("Movements"), 1, $user->hasRight('stock', 'mouvement', 'lire')); diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php index 6aabd6443ef..a7589be4860 100644 --- a/htdocs/core/modules/DolibarrModules.class.php +++ b/htdocs/core/modules/DolibarrModules.class.php @@ -38,30 +38,33 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it into unActivateModule to be able to disable a module whose files were removed. { /** - * @var DoliDB Database handler + * @var DoliDB Database handler */ public $db; /** - * @var int Module unique ID + * @var int Module unique ID * @see https://wiki.dolibarr.org/index.php/List_of_modules_id */ public $numero; /** - * @var string Publisher name - * @since 4.0.0 + * @var string Publisher name */ public $editor_name; /** - * @var string URL of module at publisher site - * @since 4.0.0 + * @var string URL of module at publisher site */ public $editor_url; /** - * @var string Family + * @var string URL of logo of the publisher. Must be image filename into the module/img directory followed with @modulename. Example: 'myimage.png@mymodule'. + */ + public $editor_squarred_logo; + + /** + * @var string Family * @see $familyinfo * * Native values: 'crm', 'financial', 'hr', 'projects', 'products', 'ecm', 'technic', 'other'. @@ -84,12 +87,12 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it public $familyinfo; /** - * @var string Module position on 2 digits + * @var string Module position on 2 digits */ public $module_position = '50'; /** - * @var string Module name + * @var string Module name * * Only used if Module[ID]Name translation string is not found. * @@ -500,7 +503,7 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it $ignoreerror = $val['ignoreerror']; } // Add current entity id - $sql = str_replace('__ENTITY__', $conf->entity, $sql); + $sql = str_replace('__ENTITY__', (string) $conf->entity, $sql); dol_syslog(get_class($this)."::_init ignoreerror=".$ignoreerror, LOG_DEBUG); $result = $this->db->query($sql, $ignoreerror); diff --git a/htdocs/core/modules/action/doc/pdf_standard_actions.class.php b/htdocs/core/modules/action/doc/pdf_standard_actions.class.php index 6a4a448a43c..bfd1c0b5bc8 100644 --- a/htdocs/core/modules/action/doc/pdf_standard_actions.class.php +++ b/htdocs/core/modules/action/doc/pdf_standard_actions.class.php @@ -2,6 +2,7 @@ /* Copyright (C) 2004 Rodolphe Quiedeville * Copyright (C) 2004-2012 Laurent Destailleur * Copyright (C) 2005-2009 Regis Houssin + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -160,7 +161,7 @@ class pdf_standard_actions global $action; $object = new stdClass(); - $parameters = array('file'=>$file, 'outputlangs'=>$outputlangs); + $parameters = array('file' => $file, 'outputlangs' => $outputlangs); $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks $pdf = pdf_getInstance($this->format); @@ -204,7 +205,7 @@ class pdf_standard_actions $hookmanager = new HookManager($this->db); } $hookmanager->initHooks(array('pdfgeneration')); - $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs); + $parameters = array('file' => $file, 'object' => $object, 'outputlangs' => $outputlangs); global $action; $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) { @@ -214,7 +215,7 @@ class pdf_standard_actions dolChmod($file); - $this->result = array('fullpath'=>$file); + $this->result = array('fullpath' => $file); return 1; } @@ -355,7 +356,7 @@ class pdf_standard_actions * @param TCPDF $pdf Object PDF * @param Translate $outputlangs Object lang for output * @param int $pagenb Page nb - * @return float|int Return topshift value + * @return float Return topshift value */ private function _pagehead(&$pdf, $outputlangs, $pagenb) { diff --git a/htdocs/core/modules/bank/doc/pdf_sepamandate.modules.php b/htdocs/core/modules/bank/doc/pdf_sepamandate.modules.php index 5cc2c4602db..dc836b18651 100644 --- a/htdocs/core/modules/bank/doc/pdf_sepamandate.modules.php +++ b/htdocs/core/modules/bank/doc/pdf_sepamandate.modules.php @@ -1,6 +1,7 @@ * Copyright (C) 2020 Josep Lluís Amador + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -115,7 +116,7 @@ class pdf_sepamandate extends ModeleBankAccountDoc /** * Function to create pdf of company bank account sepa mandate * - * @param CompanyBankAccount $object Object bank account to generate document for + * @param Account $object CompanyBankAccount bank account to generate document for * @param Translate $outputlangs Lang output object * @param string $srctemplatepath Full path of source filename for generator using a template file * @param int $hidedetails Do not show line details (not used for this template) @@ -129,6 +130,11 @@ class pdf_sepamandate extends ModeleBankAccountDoc // phpcs:enable global $conf, $hookmanager, $langs, $user, $mysoc; + if (!$object instanceof CompanyBankAccount) { + dol_syslog(get_class($this)."::write_file object is of type ".get_class($object)." which is not expected", LOG_ERR); + return -1; + } + if (!is_object($outputlangs)) { $outputlangs = $langs; } diff --git a/htdocs/core/modules/bank/modules_bank.php b/htdocs/core/modules/bank/modules_bank.php index 682c9fe4de9..5367ae52e8c 100644 --- a/htdocs/core/modules/bank/modules_bank.php +++ b/htdocs/core/modules/bank/modules_bank.php @@ -1,6 +1,7 @@ * Copyright (C) 2014 Marcos García + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -50,4 +51,15 @@ abstract class ModeleBankAccountDoc extends CommonDocGenerator return $list; } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Write the document to disk + * + * @param Account $object Object Account to generate + * @param Translate $outputlangs Lang output object + * @return int 1 if OK, <=0 if KO + */ + abstract public function write_file($object, $outputlangs); + // phpcs:enable } diff --git a/htdocs/core/modules/barcode/doc/phpbarcode.modules.php b/htdocs/core/modules/barcode/doc/phpbarcode.modules.php index 706b6213a7c..05dfc085a1a 100644 --- a/htdocs/core/modules/barcode/doc/phpbarcode.modules.php +++ b/htdocs/core/modules/barcode/doc/phpbarcode.modules.php @@ -135,7 +135,6 @@ class modPhpbarcode extends ModeleBarCode */ public function buildBarCode($code, $encoding, $readable = 'Y', $scale = 1, $nooutputiferror = 0) { - global $_GET, $_SERVER; global $conf; global $genbarcode_loc, $bar_color, $bg_color, $text_color, $font_loc; @@ -189,12 +188,21 @@ class modPhpbarcode extends ModeleBarCode dol_mkdir($conf->barcode->dir_temp); if (!is_writable($conf->barcode->dir_temp)) { - $this->error = $langs->transnoentities("ErrorFailedToWriteInTempDirectory", $conf->barcode->dir_temp); + if ($langs instanceof Translate) { + $this->error = $langs->transnoentities("ErrorFailedToWriteInTempDirectory", $conf->barcode->dir_temp); + } else { + $this->error = "ErrorFailedToWriteInTempDirectory ".$conf->barcode->dir_temp; + } dol_syslog('Error in write_file: ' . $this->error, LOG_ERR); return -1; } - $file = $conf->barcode->dir_temp . '/barcode_' . $code . '_' . $encoding . '.png'; + $newcode = $code; + if (!preg_match('/^\w+$/', $code) || dol_strlen($code) > 32) { + $newcode = dol_hash($newcode, 'md5'); // No need for security here, we can use md5 + } + + $file = $conf->barcode->dir_temp . '/barcode_' . $newcode . '_' . $encoding . '.png'; $filebarcode = $file; // global var to be used in barcode_outimage called by barcode_print in buildBarCode diff --git a/htdocs/core/modules/barcode/doc/tcpdfbarcode.modules.php b/htdocs/core/modules/barcode/doc/tcpdfbarcode.modules.php index dcb69e6642a..21829deb88f 100644 --- a/htdocs/core/modules/barcode/doc/tcpdfbarcode.modules.php +++ b/htdocs/core/modules/barcode/doc/tcpdfbarcode.modules.php @@ -106,8 +106,6 @@ class modTcpdfbarcode extends ModeleBarCode */ public function buildBarCode($code, $encoding, $readable = 'Y', $scale = 1, $nooutputiferror = 0) { - global $_GET; - $tcpdfEncoding = $this->getTcpdfEncodingType($encoding); if (empty($tcpdfEncoding)) { return -1; @@ -154,16 +152,33 @@ class modTcpdfbarcode extends ModeleBarCode */ public function writeBarCode($code, $encoding, $readable = 'Y', $scale = 1, $nooutputiferror = 0) { - global $conf, $langs, $_GET; + global $conf, $langs; + + // Force value of temp directory because we may call this even if module barcode is disabled + if (empty($conf->barcode)) { + $conf->barcode = new stdClass(); + } + if (empty($conf->barcode->dir_temp)) { + $conf->barcode->dir_temp = DOL_DATA_ROOT.'/barcode/temp'; + } dol_mkdir($conf->barcode->dir_temp); if (!is_writable($conf->barcode->dir_temp)) { - $this->error = $langs->transnoentities("ErrorFailedToWriteInTempDirectory", $conf->barcode->dir_temp); + if ($langs instanceof Translate) { + $this->error = $langs->transnoentities("ErrorFailedToWriteInTempDirectory", $conf->barcode->dir_temp); + } else { + $this->error = "ErrorFailedToWriteInTempDirectory ".$conf->barcode->dir_temp; + } dol_syslog('Error in write_file: ' . $this->error, LOG_ERR); return -1; } - $file = $conf->barcode->dir_temp . '/barcode_' . $code . '_' . $encoding . '.png'; + $newcode = $code; + if (!preg_match('/^\w+$/', $code) || dol_strlen($code) > 32) { + $newcode = dol_hash($newcode, 'md5'); // No need for security here, we can use md5 + } + + $file = $conf->barcode->dir_temp . '/barcode_' . $newcode . '_' . $encoding . '.png'; $tcpdfEncoding = $this->getTcpdfEncodingType($encoding); if (empty($tcpdfEncoding)) { @@ -190,7 +205,8 @@ class modTcpdfbarcode extends ModeleBarCode $barcodeobj = new TCPDFBarcode($code, $tcpdfEncoding); } - dol_syslog("writeBarCode::TCPDF.getBarcodePngData"); + dol_syslog("writeBarCode::TCPDF.getBarcodePngData file=".$file); + if ($imageData = (string) $barcodeobj->getBarcodePngData($width, $height, $color)) { if (function_exists('imagecreate')) { $imageData = imagecreatefromstring($imageData); diff --git a/htdocs/core/modules/mailings/fraise.modules.php b/htdocs/core/modules/mailings/fraise.modules.php index 1547ce1d866..6007b7adb95 100644 --- a/htdocs/core/modules/mailings/fraise.modules.php +++ b/htdocs/core/modules/mailings/fraise.modules.php @@ -233,7 +233,7 @@ class mailing_fraise extends MailingTargets public function add_to_target($mailing_id) { // phpcs:enable - global $conf, $langs, $_POST; + global $conf, $langs; // Load translation files required by the page $langs->loadLangs(array("members", "companies")); diff --git a/htdocs/core/modules/oauth/google_oauthcallback.php b/htdocs/core/modules/oauth/google_oauthcallback.php index 2fc4a4a4b09..4f38e884481 100644 --- a/htdocs/core/modules/oauth/google_oauthcallback.php +++ b/htdocs/core/modules/oauth/google_oauthcallback.php @@ -161,22 +161,8 @@ if (!GETPOST('code')) { $_SESSION['oauthstateanticsrf'] = $state; // Save more data into session - // Not required. All data are saved into $_SESSION['datafromloginform'] when form is posted with a click on Login with - // Google with param actionlogin=login and beforeoauthloginredirect=google, by the functions_googleoauth.php. - /* - if (!empty($_POST["tz"])) { - $_SESSION["tz"] = $_POST["tz"]; - } - if (!empty($_POST["tz_string"])) { - $_SESSION["tz_string"] = $_POST["tz_string"]; - } - if (!empty($_POST["dst_first"])) { - $_SESSION["dst_first"] = $_POST["dst_first"]; - } - if (!empty($_POST["dst_second"])) { - $_SESSION["dst_second"] = $_POST["dst_second"]; - } - */ + // No need to save more data in sessions. We have several info into $_SESSION['datafromloginform'], saved when form is posted with a click + // on "Login with Google" with param actionlogin=login and beforeoauthloginredirect=google, by the functions_googleoauth.php. if ($forlogin) { $apiService->setApprouvalPrompt('force'); diff --git a/htdocs/core/modules/printing/modules_printing.php b/htdocs/core/modules/printing/modules_printing.php index 6eb74a2e93d..95d07d90323 100644 --- a/htdocs/core/modules/printing/modules_printing.php +++ b/htdocs/core/modules/printing/modules_printing.php @@ -1,6 +1,7 @@ + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,6 +32,9 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; */ class PrintingDriver { + /** Force subclass to implement LANGFILE */ + const LANGFILE = self::LANGFILE; + /** * @var DoliDB Database handler. */ @@ -70,8 +74,8 @@ class PrintingDriver * Return list of printing driver * * @param DoliDB $db Database handler - * @param integer $maxfilenamelength Max length of value to show - * @return array List of drivers + * @param int $maxfilenamelength Max length of value to show + * @return array List of drivers */ public static function listDrivers($db, $maxfilenamelength = 0) { diff --git a/htdocs/core/modules/printing/printipp.modules.php b/htdocs/core/modules/printing/printipp.modules.php index e83823777da..46806916537 100644 --- a/htdocs/core/modules/printing/printipp.modules.php +++ b/htdocs/core/modules/printing/printipp.modules.php @@ -1,6 +1,7 @@ + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -51,7 +52,7 @@ class printing_printipp extends PrintingDriver public $active = 'PRINTING_PRINTIPP'; /** - * @var array array of setup value + * @var array> array of setup values */ public $conf = array(); @@ -112,11 +113,11 @@ class printing_printipp extends PrintingDriver $this->port = getDolGlobalString('PRINTIPP_PORT'); $this->user = getDolGlobalString('PRINTIPP_USER'); $this->password = getDolGlobalString('PRINTIPP_PASSWORD'); - $this->conf[] = array('varname'=>'PRINTIPP_HOST', 'required'=>1, 'example'=>'localhost', 'type'=>'text'); - $this->conf[] = array('varname'=>'PRINTIPP_PORT', 'required'=>1, 'example'=>'631', 'type'=>'text'); - $this->conf[] = array('varname'=>'PRINTIPP_USER', 'required'=>0, 'example'=>'', 'type'=>'text', 'moreattributes'=>'autocomplete="off"'); - $this->conf[] = array('varname'=>'PRINTIPP_PASSWORD', 'required'=>0, 'example'=>'', 'type'=>'password', 'moreattributes'=>'autocomplete="off"'); - $this->conf[] = array('enabled'=>1, 'type'=>'submit'); + $this->conf[] = array('varname' => 'PRINTIPP_HOST', 'required' => 1, 'example' => 'localhost', 'type' => 'text'); + $this->conf[] = array('varname' => 'PRINTIPP_PORT', 'required' => 1, 'example' => '631', 'type' => 'text'); + $this->conf[] = array('varname' => 'PRINTIPP_USER', 'required' => 0, 'example' => '', 'type' => 'text', 'moreattributes' => 'autocomplete="off"'); + $this->conf[] = array('varname' => 'PRINTIPP_PASSWORD', 'required' => 0, 'example' => '', 'type' => 'password', 'moreattributes' => 'autocomplete="off"'); + $this->conf[] = array('enabled' => 1, 'type' => 'submit'); } /** @@ -194,6 +195,8 @@ class printing_printipp extends PrintingDriver * Return list of available printers * * @return int 0 if OK, >0 if KO + * + * @phan-suppress PhanTypeExpectedObjectPropAccess */ public function listAvailablePrinters() { @@ -216,6 +219,7 @@ class printing_printipp extends PrintingDriver $list = $this->getlistAvailablePrinters(); foreach ($list as $value) { $printer_det = $this->getPrinterDetail($value); + '@phan-var-force stdClass $printer_det'; $html .= ''; $html .= ''.$value.''; //$html.= '
      '.print_r($printer_det,true).'
      '; @@ -245,7 +249,7 @@ class printing_printipp extends PrintingDriver /** * Return list of available printers * - * @return array list of printers + * @return string[] List of printers (URIs) */ public function getlistAvailablePrinters() { @@ -267,7 +271,7 @@ class printing_printipp extends PrintingDriver * Get printer detail * * @param string $uri URI - * @return array List of attributes + * @return stdClass List of attributes */ private function getPrinterDetail($uri) { diff --git a/htdocs/core/modules/supplier_invoice/doc/pdf_canelle.modules.php b/htdocs/core/modules/supplier_invoice/doc/pdf_canelle.modules.php index 858aef6b33b..526490336d9 100644 --- a/htdocs/core/modules/supplier_invoice/doc/pdf_canelle.modules.php +++ b/htdocs/core/modules/supplier_invoice/doc/pdf_canelle.modules.php @@ -770,7 +770,7 @@ class pdf_canelle extends ModelePDFSuppliersInvoices $depositsamount = $object->getSumDepositsUsed((isModEnabled("multicurrency") && $object->multicurrency_tx != 1) ? 1 : 0); //print "x".$creditnoteamount."-".$depositsamount;exit; $resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT'); - if (!empty($object->paye)) { + if (!empty($object->paid)) { $resteapayer = 0; } diff --git a/htdocs/core/multicompany_page.php b/htdocs/core/multicompany_page.php index 9286e3efaaa..a047ef74968 100644 --- a/htdocs/core/multicompany_page.php +++ b/htdocs/core/multicompany_page.php @@ -1,5 +1,6 @@ + * Copyright (C) 2024 MDW * * This file is a modified version of datepicker.php from phpBSM to fix some * bugs, to add new features and to dramatically increase speed. @@ -91,9 +92,8 @@ print ''."\n"; print '
      '; //print '
      '; -if (!isset($bookmarkList)) { - $bookmarkList = ''; -} + +$bookmarkList = ''; if (!isModEnabled('multicompany')) { $langs->load("admin"); $bookmarkList .= '
      '.$langs->trans("WarningModuleNotActive", $langs->transnoentitiesnoconv("MultiCompany")).''; @@ -109,6 +109,8 @@ if (!isModEnabled('multicompany')) { if (is_object($mc)) { $listofentities = $mc->getEntitiesList($user->login, false, true); + } else { + $listofentities = array(); } $multicompanyList .= '
        '; diff --git a/htdocs/core/photos_resize.php b/htdocs/core/photos_resize.php index 70c8da59d2a..199d54e3e50 100644 --- a/htdocs/core/photos_resize.php +++ b/htdocs/core/photos_resize.php @@ -404,7 +404,6 @@ if ($action == 'confirm_resize' && GETPOSTISSET("file") && GETPOSTISSET("sizex") } } else { setEventMessages($result, null, 'errors'); - $_GET['file'] = $_POST["file"]; $action = ''; } } @@ -467,7 +466,6 @@ if ($action == 'confirm_crop') { } } else { setEventMessages($result, null, 'errors'); - $_GET['file'] = $_POST["file"]; $action = ''; } } diff --git a/htdocs/core/tpl/extrafields_list_print_fields.tpl.php b/htdocs/core/tpl/extrafields_list_print_fields.tpl.php index 886d8fded87..3729c2c1f4a 100644 --- a/htdocs/core/tpl/extrafields_list_print_fields.tpl.php +++ b/htdocs/core/tpl/extrafields_list_print_fields.tpl.php @@ -63,7 +63,7 @@ if (!empty($extrafieldsobjectkey) && !empty($extrafields->attributes[$extrafield $totalarray['nbfield']++; } - if ($extrafields->attributes[$extrafieldsobjectkey]['totalizable'][$key]) { + if (!empty($extrafields->attributes[$extrafieldsobjectkey]['totalizable'][$key])) { if (!$i) { // we keep position for the first line $totalarray['totalizable'][$key]['pos'] = $totalarray['nbfield']; @@ -75,7 +75,7 @@ if (!empty($extrafieldsobjectkey) && !empty($extrafields->attributes[$extrafield $totalarray['totalizable'][$key]['total'] += $obj->$tmpkey; } } - // key 'totalizable' if in extrafields same as 'isameasure' into ->$fields + // The key 'totalizable' on extrafields, is the same as 'isameasure' into ->fields if (!empty($extrafields->attributes[$extrafieldsobjectkey]['totalizable'][$key]) && $extrafields->attributes[$extrafieldsobjectkey]['totalizable'][$key] == 1) { if (!$i) { $totalarray['pos'][$totalarray['nbfield']] = $extrafieldsobjectprefix.$tmpkey; @@ -86,7 +86,12 @@ if (!empty($extrafieldsobjectkey) && !empty($extrafields->attributes[$extrafield if (!isset($totalarray['val'][$extrafieldsobjectprefix.$tmpkey])) { $totalarray['val'][$extrafieldsobjectprefix.$tmpkey] = 0; } - $totalarray['val'][$extrafieldsobjectprefix.$tmpkey] += $obj->$tmpkey; + if (isset($obj->$tmpkey) && is_numeric($obj->$tmpkey)) { + if (!isset($totalarray['val'][$extrafieldsobjectprefix.$tmpkey])) { + $totalarray['val'][$extrafieldsobjectprefix.$tmpkey] = 0; + } + $totalarray['val'][$extrafieldsobjectprefix.$tmpkey] += $obj->$tmpkey; + } } } } diff --git a/htdocs/core/tpl/filemanager.tpl.php b/htdocs/core/tpl/filemanager.tpl.php index 9c09f821638..0e75907dcba 100644 --- a/htdocs/core/tpl/filemanager.tpl.php +++ b/htdocs/core/tpl/filemanager.tpl.php @@ -62,7 +62,7 @@ if (!isset($section)) { // Confirm remove file (for non javascript users) if (($action == 'delete' || $action == 'file_manager_delete') && empty($conf->use_javascript_ajax)) { // TODO Add website, pageid, filemanager if defined - print $form->formconfirm($_SERVER["PHP_SELF"].'?section='.$section.'&urlfile='.urlencode($_GET["urlfile"]), $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile', '', '', 1); + print $form->formconfirm($_SERVER["PHP_SELF"].'?section='.$section.'&urlfile='.urlencode(GETPOST("urlfile")), $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile', '', '', 1); } // Start container of all panels @@ -316,7 +316,7 @@ if (empty($action) || $action == 'editfile' || $action == 'file_manager' || preg $_POST['modulepart'] = $module; $_POST['openeddir'] = GETPOST('openeddir'); - $_POST['dir'] = empty($_POST['dir']) ? '/' : $_POST['dir']; + $_POST['dir'] = empty($_POST['dir']) ? '/' : GETPOST('dir'); // Show filemanager tree (will be filled by direct include of ajaxdirtree.php in mode noajax, this will return all dir - all levels - to show) print '
        '; diff --git a/htdocs/core/tpl/massactions_pre.tpl.php b/htdocs/core/tpl/massactions_pre.tpl.php index cf57e63b9c5..d479a223a12 100644 --- a/htdocs/core/tpl/massactions_pre.tpl.php +++ b/htdocs/core/tpl/massactions_pre.tpl.php @@ -394,6 +394,16 @@ if ($massaction == 'presetcommercial') { 'value' => $form->multiselectarray('commercial', $userlist, null, 0, 0, 'quatrevingtpercent widthcentpercentminusx', 0, 0, '', '', '', 1)); print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmAllocateCommercial"), $langs->trans("ConfirmAllocateCommercialQuestion", count($toselect)), "affectcommercial", $formquestion, 1, 0, 200, 500, 1); } +if ($massaction == 'unsetcommercial') { + $formquestion = array(); + $userlist = $form->select_dolusers('', '', 0, null, 0, '', '', 0, 0, 0, 'AND u.statut = 1', 0, '', '', 0, 1); + $formquestion[] = array('type' => 'other', + 'name' => 'unassigncommercial', + 'label' => $form->editfieldkey('UnallocateCommercial', 'commercial_id', '', $object, 0), + 'value' => $form->multiselectarray('commercial', $userlist, null, 0, 0, 'quatrevingtpercent widthcentpercentminusx', 0, 0, '', '', '', 1)); + print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmUnallocateCommercial"), $langs->trans("ConfirmUnallocateCommercialQuestion", count($toselect)), "unassigncommercial", $formquestion, 1, 0, 200, 500, 1); +} + if ($massaction == 'preapproveleave') { print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassLeaveApproval"), $langs->trans("ConfirmMassLeaveApprovalQuestion", count($toselect)), "approveleave", null, 'yes', 0, 200, 500, 1); } diff --git a/htdocs/core/triggers/interface_50_modMailmanspip_Mailmanspipsynchro.class.php b/htdocs/core/triggers/interface_50_modMailmanspip_Mailmanspipsynchro.class.php index cb98232addc..4626228ef93 100644 --- a/htdocs/core/triggers/interface_50_modMailmanspip_Mailmanspipsynchro.class.php +++ b/htdocs/core/triggers/interface_50_modMailmanspip_Mailmanspipsynchro.class.php @@ -116,10 +116,13 @@ class InterfaceMailmanSpipsynchro extends DolibarrTriggers // Add user into some linked tools (mailman, spip, etc...) if (($object->oldcopy->email != $object->email) || ($object->oldcopy->typeid != $object->typeid)) { if (is_object($object->oldcopy) && (($object->oldcopy->email != $object->email) || ($object->oldcopy->typeid != $object->typeid))) { // If email has changed or if list has changed we delete mailman subscription for old email - if (method_exists($object->oldcopy, 'del_to_abo') && $object->oldcopy->del_to_abo() < 0) { - $this->errors = $object->oldcopy->errors; - if (!empty($object->oldcopy->error)) { - $this->errors[] = $object->oldcopy->error; + // $object->oldcopy may be a stdClass and not original object depending on copy type, so we realod a new object to run the del_to_abo() + $tmpmember = new Adherent($this->db); + $tmpmember->fetch($object->oldcopy->id); + if ($tmpmember->del_to_abo() < 0) { + $this->errors = $tmpmember->errors; + if (!empty($tmpmember->error)) { + $this->errors[] = $tmpmember->error; } $return = -1; } else { diff --git a/htdocs/core/website.inc.php b/htdocs/core/website.inc.php index 4708d12e929..34f6d1a0945 100644 --- a/htdocs/core/website.inc.php +++ b/htdocs/core/website.inc.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2017-2024 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,8 +18,9 @@ /** * \file htdocs/core/website.inc.php - * \brief Common file loaded by all website pages (after master.inc.php). It set the new object $weblangs, using parameter 'l'. - * This file is included in top of all container pages and is run only when a web page is called. + * \brief Common file loaded by all website pages (after master.inc.php). It sets the new object $weblangs. + * This file is included in top of all container pages (in edit mode, in dolibarr web server mode and in external web server mode). + * It is run only when a web page is called. * The global variable $websitekey must be defined. */ @@ -70,7 +71,31 @@ if (!is_object($pagelangs)) { if (!empty($pageid) && $pageid > 0) { $websitepage->fetch($pageid); - $weblangs->setDefaultLang(GETPOSTISSET('lang') ? GETPOST('lang', 'aZ09') : (empty($_COOKIE['weblangs-shortcode']) ? 'auto' : preg_replace('/[^a-zA-Z0-9_\-]/', '', $_COOKIE['weblangs-shortcode']))); + // Rule to define weblang of visitor: + // 1 - Take parameter lang + // 2 - Cookie lang of website (set by a possible js lang selector) + // 3 - XX/... found in url page + // 4 - auto (so web browser lang) + $srclang = GETPOSTISSET('lang') ? GETPOST('lang', 'aZ09') : ''; + if (empty($srclang)) { + $srclang = (empty($_COOKIE['weblangs-shortcode']) ? '' : preg_replace('/[^a-zA-Z0-9_\-]/', '', $_COOKIE['weblangs-shortcode'])); + } + if (empty($srclang)) { + $reg = array(); + // With Dolibarr server, url is in parameter pageref + if (defined('USEDOLIBARRSERVER') && !empty($_GET['pageref']) && preg_match('/^\/?(\w\w)\//', $_GET['pageref'], $reg) && $reg[1] != 'js') { // We reuse $_GET['pageref'] because $pageref may have been cleaned already from the language code. + $srclang = $reg[1]; + } + // With External server, url is in parameter pageref + if (defined('USEEXTERNALSERVER') && !empty($_SERVER['PHP_SELF']) && preg_match('/^\/?(\w\w)\//', $_SERVER['PHP_SELF'], $reg) && $reg[1] != 'js') { + $srclang = $reg[1]; + } + } + if (empty($srclang)) { + $srclang= 'auto'; + } + $weblangs->setDefaultLang($srclang); + $pagelangs->setDefaultLang($websitepage->lang ? $websitepage->lang : $weblangs->shortlang); if (!defined('USEDOLIBARREDITOR') && (in_array($websitepage->type_container, array('menu', 'other')) || empty($websitepage->status) && !defined('USEDOLIBARRSERVER'))) { diff --git a/htdocs/cron/list.php b/htdocs/cron/list.php index 8560f351563..84bf60f6992 100644 --- a/htdocs/cron/list.php +++ b/htdocs/cron/list.php @@ -619,8 +619,8 @@ if ($num > 0) { } elseif ($obj->unitfrequency == "2678400") { $s = ($obj->frequency)." ".($obj->frequency > 1 ? $langs->trans('DurationMonths') : $langs->trans('DurationMonth')); } - print ''; - print $s; + print ''; + print dol_escape_htmltag($s); print ''; /* @@ -720,9 +720,9 @@ if ($num > 0) { } if ($user->hasRight('cron', 'delete')) { print 'trans('CronDelete'))."\">".img_picto($langs->trans('CronDelete'), 'delete', '', false, 0, 0, '', 'marginleftonly')."   "; + print '" title="'.dol_escape_htmltag($langs->trans('CronDelete')).'">'.img_picto($langs->trans('CronDelete'), 'delete', '', false, 0, 0, '', 'marginleftonly').'   '; } else { - print "trans('NotEnoughPermissions'))."\">".img_picto($langs->trans('NotEnoughPermissions'), 'delete', '', false, 0, 0, '', 'marginleftonly')."   "; + print ''.img_picto($langs->trans('NotEnoughPermissions'), 'delete', '', false, 0, 0, '', 'marginleftonly').'   '; } if ($user->hasRight('cron', 'execute')) { if (!empty($obj->status)) { diff --git a/htdocs/debugbar/class/TraceableDB.php b/htdocs/debugbar/class/TraceableDB.php index 013a31b66ac..6e3312e547b 100644 --- a/htdocs/debugbar/class/TraceableDB.php +++ b/htdocs/debugbar/class/TraceableDB.php @@ -293,7 +293,7 @@ class TraceableDB extends DoliDB */ public function escapeforlike($stringtoencode) { - return str_replace(array('_', '\\', '%'), array('\_', '\\\\', '\%'), (string) $stringtoencode); + return $this->db->escapeforlike($stringtoencode); } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -632,7 +632,7 @@ class TraceableDB extends DoliDB * * @param string $string Date in a string (YYYYMMDDHHMMSS, YYYYMMDD, YYYY-MM-DD HH:MM:SS) * @param bool $gm 1=Input information are GMT values, otherwise local to server TZ - * @return int|string Date TMS or '' + * @return int|'' Date TMS or '' */ public function jdate($string, $gm = false) { diff --git a/htdocs/document.php b/htdocs/document.php index 17f0d61676e..2090fe89838 100644 --- a/htdocs/document.php +++ b/htdocs/document.php @@ -61,6 +61,7 @@ if (isset($_GET["hashp"]) && !defined("NOLOGIN")) { } } // Some value of modulepart can be used to get resources that are public so no login are required. +// Keep $_GET here, GETPOST is not available yet if ((isset($_GET["modulepart"]) && $_GET["modulepart"] == 'medias')) { if (!defined("NOLOGIN")) { define("NOLOGIN", 1); @@ -98,7 +99,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; $encoding = ''; $action = GETPOST('action', 'aZ09'); -$original_file = GETPOST('file', 'alphanohtml'); // Do not use urldecode here ($_GET are already decoded by PHP). +$original_file = GETPOST('file', 'alphanohtml'); $hashp = GETPOST('hashp', 'aZ09'); $modulepart = GETPOST('modulepart', 'alpha'); $urlsource = GETPOST('urlsource', 'alpha'); diff --git a/htdocs/don/class/api_donations.class.php b/htdocs/don/class/api_donations.class.php index 1312e385480..6773efc4c03 100644 --- a/htdocs/don/class/api_donations.class.php +++ b/htdocs/don/class/api_donations.class.php @@ -72,7 +72,7 @@ class Donations extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('don', $this->don->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } // Add external contacts ids @@ -185,11 +185,11 @@ class Donations extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->don->context['caller'] = $request_data['caller']; + $this->don->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->don->$field = $value; + $this->don->$field = $this->_checkValForAPI($field, $value, $this->don); } /*if (isset($request_data["lines"])) { $lines = array(); @@ -225,7 +225,7 @@ class Donations extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('donation', $this->don->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach ($request_data as $field => $value) { if ($field == 'id') { @@ -233,11 +233,11 @@ class Donations extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->don->context['caller'] = $request_data['caller']; + $this->don->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->don->$field = $value; + $this->don->$field = $this->_checkValForAPI($field, $value, $this->don); } if ($this->don->update(DolibarrApiAccess::$user) > 0) { @@ -265,7 +265,7 @@ class Donations extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('donation', $this->don->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if (!$this->don->delete(DolibarrApiAccess::$user)) { @@ -314,7 +314,7 @@ class Donations extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('don', $this->don->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } // @phan-suppress-next-line PhanPluginSuspiciousParamPosition @@ -331,7 +331,7 @@ class Donations extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('don', $this->don->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->don->fetchObjectLinked(); diff --git a/htdocs/ecm/dir_card.php b/htdocs/ecm/dir_card.php index 7444815a11e..46fe08c71fb 100644 --- a/htdocs/ecm/dir_card.php +++ b/htdocs/ecm/dir_card.php @@ -139,7 +139,7 @@ if (GETPOST("sendit") && getDolGlobalString('MAIN_UPLOAD_DOC') && $permissiontou // Remove file if ($action == 'confirm_deletefile' && $confirm == 'yes' && $permissiontoupload) { $langs->load("other"); - $file = $upload_dir."/".GETPOST('urlfile'); // Do not use urldecode here ($_GET and $_REQUEST are already decoded by PHP). + $file = $upload_dir."/".GETPOST('urlfile'); // Do not use urldecode here $ret = dol_delete_file($file); if ($ret) { setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs'); diff --git a/htdocs/ecm/index_auto.php b/htdocs/ecm/index_auto.php index 7a0338a0126..a46470e9d7a 100644 --- a/htdocs/ecm/index_auto.php +++ b/htdocs/ecm/index_auto.php @@ -137,7 +137,7 @@ if ($action == 'confirm_deletefile') { $relativepath = ''; } $upload_dir = $conf->ecm->dir_output.($relativepath ? '/'.$relativepath : ''); - $file = $upload_dir."/".GETPOST('urlfile'); // Do not use urldecode here ($_GET and $_POST are already decoded by PHP). + $file = $upload_dir."/".GETPOST('urlfile'); $ret = dol_delete_file($file); if ($ret) { @@ -417,7 +417,7 @@ print dol_get_fiche_head($head, 'index_auto', '', -1, ''); // Confirm remove file (for non javascript users) if ($action == 'deletefile' && empty($conf->use_javascript_ajax)) { - print $form->formconfirm($_SERVER["PHP_SELF"].'?section='.$section.'&urlfile='.urlencode($_GET["urlfile"]), $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile', '', '', 1); + print $form->formconfirm($_SERVER["PHP_SELF"].'?section='.$section.'&urlfile='.urlencode(GETPOST("urlfile")), $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile', '', '', 1); } // Start container of all panels diff --git a/htdocs/eventorganization/core/actions_massactions_mail.inc.php b/htdocs/eventorganization/core/actions_massactions_mail.inc.php index 634264c83cf..67aaa624510 100644 --- a/htdocs/eventorganization/core/actions_massactions_mail.inc.php +++ b/htdocs/eventorganization/core/actions_massactions_mail.inc.php @@ -109,7 +109,7 @@ if (!$error && $massaction == 'confirm_presend_attendees') { $receiver = array($receiver); } } - if (!trim($_POST['sendto']) && count($receiver) == 0 && count($listofselectedid) == 0) { // if only one recipient, receiver is mandatory + if (!trim(GETPOST('sendto', 'alphawithlgt')) && count($receiver) == 0 && count($listofselectedid) == 0) { // if only one recipient, receiver is mandatory $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Recipient")), null, 'warnings'); $massaction = 'presend_attendees'; @@ -142,7 +142,7 @@ if (!$error && $massaction == 'confirm_presend_attendees') { } } $tmparray = array(); - if (trim($_POST['sendtocc'])) { + if (trim(GETPOST('sendtocc', 'alphawithlgt'))) { $tmparray[] = trim(GETPOST('sendtocc', 'alphawithlgt')); } $sendtocc = implode(',', $tmparray); diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 61b6fb26300..16a71da87da 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -444,7 +444,7 @@ if (empty($reshook)) { exit; } else { $db->rollback(); - $_GET["commande_id"] = GETPOSTINT('commande_id'); + //$_GET["commande_id"] = GETPOSTINT('commande_id'); $action = 'create'; } } elseif ($action == 'create_delivery' && getDolGlobalInt('MAIN_SUBMODULE_DELIVERY') && $user->hasRight('expedition', 'delivery', 'creer')) { diff --git a/htdocs/expedition/class/api_shipments.class.php b/htdocs/expedition/class/api_shipments.class.php index 3f3aa064030..b10346c8047 100644 --- a/htdocs/expedition/class/api_shipments.class.php +++ b/htdocs/expedition/class/api_shipments.class.php @@ -74,7 +74,7 @@ class Shipments extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('expedition', $this->shipment->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->shipment->fetchObjectLinked(); @@ -191,11 +191,11 @@ class Shipments extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->shipment->context['caller'] = $request_data['caller']; + $this->shipment->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->shipment->$field = $value; + $this->shipment->$field = $this->_checkValForAPI($field, $value, $this->shipment); } if (isset($request_data["lines"])) { $lines = array(); @@ -234,7 +234,7 @@ class Shipments extends DolibarrApi } if( ! DolibarrApi::_checkAccessToResource('expedition',$this->shipment->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->shipment->getLinesArray(); $result = array(); @@ -268,7 +268,7 @@ class Shipments extends DolibarrApi } if( ! DolibarrApi::_checkAccessToResource('expedition',$this->shipment->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $request_data = (object) $request_data; @@ -336,7 +336,7 @@ class Shipments extends DolibarrApi } if( ! DolibarrApi::_checkAccessToResource('expedition',$this->shipment->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $request_data = (object) $request_data; @@ -403,7 +403,7 @@ class Shipments extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('expedition', $this->shipment->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } // TODO Check the lineid $lineid is a line of object @@ -440,7 +440,7 @@ class Shipments extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('expedition', $this->shipment->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach ($request_data as $field => $value) { if ($field == 'id') { @@ -448,11 +448,11 @@ class Shipments extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->shipment->context['caller'] = $request_data['caller']; + $this->shipment->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->shipment->$field = $value; + $this->shipment->$field = $this->_checkValForAPI($field, $value, $this->shipment); } if ($this->shipment->update(DolibarrApiAccess::$user) > 0) { @@ -480,7 +480,7 @@ class Shipments extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('expedition', $this->shipment->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if (!$this->shipment->delete(DolibarrApiAccess::$user)) { @@ -525,7 +525,7 @@ class Shipments extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('expedition', $this->shipment->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->shipment->valid(DolibarrApiAccess::$user, $notrigger); @@ -648,7 +648,7 @@ class Shipments extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('expedition', $this->shipment->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->shipment->setClosed(); diff --git a/htdocs/expensereport/class/api_expensereports.class.php b/htdocs/expensereport/class/api_expensereports.class.php index 75b116af9e9..852d8d1e0b9 100644 --- a/htdocs/expensereport/class/api_expensereports.class.php +++ b/htdocs/expensereport/class/api_expensereports.class.php @@ -86,7 +86,7 @@ class ExpenseReports extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('expensereport', $this->expensereport->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->expensereport->fetchObjectLinked(); @@ -183,11 +183,11 @@ class ExpenseReports extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->expensereport->context['caller'] = $request_data['caller']; + $this->expensereport->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->expensereport->$field = $value; + $this->expensereport->$field = $this->_checkValForAPI($field, $value, $this->expensereport); } /*if (isset($request_data["lines"])) { $lines = array(); @@ -225,7 +225,7 @@ class ExpenseReports extends DolibarrApi } if( ! DolibarrApi::_checkAccessToResource('expensereport',$this->expensereport->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->expensereport->getLinesArray(); $result = array(); @@ -259,7 +259,7 @@ class ExpenseReports extends DolibarrApi } if( ! DolibarrApi::_checkAccessToResource('expensereport',$this->expensereport->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $request_data = (object) $request_data; @@ -327,7 +327,7 @@ class ExpenseReports extends DolibarrApi } if( ! DolibarrApi::_checkAccessToResource('expensereport',$this->expensereport->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $request_data = (object) $request_data; @@ -391,7 +391,7 @@ class ExpenseReports extends DolibarrApi } if( ! DolibarrApi::_checkAccessToResource('expensereport',$this->expensereport->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } // TODO Check the lineid $lineid is a line of object @@ -427,7 +427,7 @@ class ExpenseReports extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('expensereport', $this->expensereport->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach ($request_data as $field => $value) { if ($field == 'id') { @@ -435,11 +435,11 @@ class ExpenseReports extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->expensereport->context['caller'] = $request_data['caller']; + $this->expensereport->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->expensereport->$field = $value; + $this->expensereport->$field = $this->_checkValForAPI($field, $value, $this->expensereport); } if ($this->expensereport->update(DolibarrApiAccess::$user) > 0) { @@ -511,7 +511,7 @@ class ExpenseReports extends DolibarrApi } if( ! DolibarrApi::_checkAccessToResource('expensereport',$this->expensereport->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if( ! $this->expensereport->valid(DolibarrApiAccess::$user, $idwarehouse)) { diff --git a/htdocs/expensereport/index.php b/htdocs/expensereport/index.php index 016fbfee019..ab95b3a5e0b 100644 --- a/htdocs/expensereport/index.php +++ b/htdocs/expensereport/index.php @@ -5,7 +5,7 @@ * Copyright (C) 2005-2011 Regis Houssin * Copyright (C) 2015 Alexandre Spangaro * Copyright (C) 2019 Nicolas ZABOURI - * Copyright (C) 2019 Frédéric FRANCE + * Copyright (C) 2019-2024 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -66,6 +66,8 @@ if (!$sortfield) { } $limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit; +$max = getDolGlobalInt('MAIN_SIZE_SHORTLIST_LIMIT'); + /* * View @@ -190,8 +192,6 @@ print '
        '; print '
      '; -$max = 10; - $langs->load("boxes"); $sql = "SELECT u.rowid as uid, u.lastname, u.firstname, u.login, u.statut as user_status, u.photo, u.email, u.admin,"; @@ -223,7 +223,11 @@ if ($result) { print ''.$langs->trans("AmountHT").''; print ''.$langs->trans("AmountTTC").''; print ''.$langs->trans("DateModificationShort").''; - print ' '; + print ''; + print ''; + print img_picto($langs->trans("FullList"), 'expensereport'); + print ''; + print ''; print ''; if ($num) { $total_ttc = $totalam = $total = 0; @@ -243,7 +247,7 @@ if ($result) { $userstatic->lastname = $obj->lastname; $userstatic->firstname = $obj->firstname; $userstatic->login = $obj->login; - $userstatic->statut = $obj->user_status; + $userstatic->status = $obj->user_status; $userstatic->photo = $obj->photo; print ''; diff --git a/htdocs/exports/export.php b/htdocs/exports/export.php index 638dbd6b700..dac7cee794c 100644 --- a/htdocs/exports/export.php +++ b/htdocs/exports/export.php @@ -219,11 +219,11 @@ if ($action == 'selectfield') { // Selection of field at step 2 } } if ($action == 'unselectfield') { - if ($_GET["field"] == 'all') { + if (GETPOST("field") == 'all') { $array_selected = array(); $_SESSION["export_selected_fields"] = $array_selected; } else { - unset($array_selected[$_GET["field"]]); + unset($array_selected[GETPOST("field")]); // Renumber fields of array_selected (from 1 to nb_elements) asort($array_selected); $i = 0; @@ -238,7 +238,7 @@ if ($action == 'unselectfield') { } if ($action == 'downfield' || $action == 'upfield') { - $pos = $array_selected[$_GET["field"]]; + $pos = $array_selected[GETPOST("field")]; if ($action == 'downfield') { $newpos = $pos + 1; } @@ -253,9 +253,9 @@ if ($action == 'downfield' || $action == 'upfield') { break; } } - //print("Switch pos=$pos (code=".$_GET["field"].") and newpos=$newpos (code=$newcode)"); + //print("Switch pos=$pos (code=".GETPOST("field").") and newpos=$newpos (code=$newcode)"); if ($newcode) { // Si newcode trouve (protection contre resoumission de page) - $array_selected[$_GET["field"]] = $newpos; + $array_selected[GETPOST("field")] = $newpos; $array_selected[$newcode] = $pos; $_SESSION["export_selected_fields"] = $array_selected; } @@ -290,7 +290,7 @@ if ($action == 'builddoc') { // Delete file if ($step == 5 && $action == 'confirm_deletefile' && $confirm == 'yes') { - $file = $upload_dir."/".GETPOST('file'); // Do not use urldecode here ($_GET and $_REQUEST are already decoded by PHP). + $file = $upload_dir."/".GETPOST('file'); $ret = dol_delete_file($file); if ($ret) { @@ -400,7 +400,6 @@ if ($step == 4 && $action == 'submitFormField') { $filterqualified = 0; } if ($filterqualified) { - //print 'Filter on '.$newcode.' type='.$type.' value='.$_POST[$newcode]."\n"; $objexport->array_export_FilterValue[0][$code] = GETPOST($newcode, $check); } } diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php index a8301b48558..0091dd56dfe 100644 --- a/htdocs/fichinter/card.php +++ b/htdocs/fichinter/card.php @@ -11,6 +11,7 @@ * Copyright (C) 2020-2024 Frédéric France * Copyright (C) 2023 Benjamin Grembi * Copyright (C) 2023-2024 William Mead + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -117,7 +118,7 @@ $usercancreate = $user->hasRight('ficheinter', 'creer'); * Actions */ -$parameters = array('socid'=>$socid); +$parameters = array('socid' => $socid); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) { setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); @@ -292,8 +293,8 @@ if (empty($reshook)) { // Possibility to add external linked objects with hooks $object->linked_objects[$object->origin] = $object->origin_id; - if (is_array($_POST['other_linked_objects']) && !empty($_POST['other_linked_objects'])) { - $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']); + if (GETPOSTISARRAY('other_linked_objects')) { + $object->linked_objects = array_merge($object->linked_objects, GETPOST('other_linked_objects', 'array:int')); } // Extrafields @@ -1185,7 +1186,7 @@ if ($action == 'create') { } if (!$formconfirm) { - $parameters = array('formConfirm' => $formconfirm, 'lineid'=>$lineid); + $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) { $formconfirm .= $hookmanager->resPrint; @@ -1204,8 +1205,8 @@ if ($action == 'create') { $morehtmlref = '
      '; // Ref customer - $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, $user->hasRight('ficheinter', 'creer'), 'string', '', 0, 1); - $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, $user->hasRight('ficheinter', 'creer'), 'string', '', null, null, '', 1); + $morehtmlref .= $form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, $user->hasRight('ficheinter', 'creer'), 'string', '', 0, 1); + $morehtmlref .= $form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, $user->hasRight('ficheinter', 'creer'), 'string', '', null, null, '', 1); // Thirdparty $morehtmlref .= '
      '.$object->thirdparty->getNomUrl(1, 'customer'); // Project diff --git a/htdocs/fichinter/class/api_interventions.class.php b/htdocs/fichinter/class/api_interventions.class.php index b8c5b4f187f..3c1dbf01b70 100644 --- a/htdocs/fichinter/class/api_interventions.class.php +++ b/htdocs/fichinter/class/api_interventions.class.php @@ -88,7 +88,7 @@ class Interventions extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('fichinter', $this->fichinter->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->fichinter->fetchObjectLinked(); @@ -198,11 +198,11 @@ class Interventions extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->fichinter->context['caller'] = $request_data['caller']; + $this->fichinter->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->fichinter->$field = $value; + $this->fichinter->$field = $this->_checkValForAPI($field, $value, $this->fichinter); } if ($this->fichinter->create(DolibarrApiAccess::$user) < 0) { @@ -235,7 +235,7 @@ class Interventions extends DolibarrApi } if( ! DolibarrApi::_checkAccessToResource('fichinter',$this->fichinter->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->fichinter->getLinesArray(); $result = array(); @@ -267,11 +267,11 @@ class Interventions extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->fichinter->context['caller'] = $request_data['caller']; + $this->fichinter->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->fichinter->$field = $value; + $this->fichinter->$field = $this->_checkValForAPI($field, $value, $this->fichinter); } if (!$result) { @@ -279,7 +279,7 @@ class Interventions extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('fichinter', $this->fichinter->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $updateRes = $this->fichinter->addLine( @@ -314,7 +314,7 @@ class Interventions extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('fichinter', $this->fichinter->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if (!$this->fichinter->delete(DolibarrApiAccess::$user)) { @@ -355,7 +355,7 @@ class Interventions extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('fichinter', $this->fichinter->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->fichinter->setValid(DolibarrApiAccess::$user, $notrigger); @@ -391,7 +391,7 @@ class Interventions extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('fichinter', $this->fichinter->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->fichinter->setStatut(3); diff --git a/htdocs/fichinter/class/fichinterrec.class.php b/htdocs/fichinter/class/fichinterrec.class.php index 3f34bdf65fb..cf3751fa06e 100644 --- a/htdocs/fichinter/class/fichinterrec.class.php +++ b/htdocs/fichinter/class/fichinterrec.class.php @@ -110,6 +110,10 @@ class FichinterRec extends Fichinter * int rank */ public $rang; + + /** + * @var int special code + */ public $special_code; public $usenewprice = 0; diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php index 02028392a6f..13626a9e72e 100644 --- a/htdocs/fourn/class/api_supplier_invoices.class.php +++ b/htdocs/fourn/class/api_supplier_invoices.class.php @@ -211,7 +211,7 @@ class SupplierInvoices extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->invoice->context['caller'] = $request_data['caller']; + $this->invoice->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } @@ -258,10 +258,15 @@ class SupplierInvoices extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->invoice->context['caller'] = $request_data['caller']; + $this->invoice->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); + continue; + } + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->invoice->array_options[$index] = $this->_checkValForAPI($field, $val, $this->invoice); + } continue; } - $this->invoice->$field = $this->_checkValForAPI($field, $value, $this->invoice); } diff --git a/htdocs/fourn/class/api_supplier_orders.class.php b/htdocs/fourn/class/api_supplier_orders.class.php index 156b395c377..21a9b3b77b0 100644 --- a/htdocs/fourn/class/api_supplier_orders.class.php +++ b/htdocs/fourn/class/api_supplier_orders.class.php @@ -73,7 +73,7 @@ class SupplierOrders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->order->fetchObjectLinked(); @@ -230,7 +230,7 @@ class SupplierOrders extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->order->context['caller'] = $request_data['caller']; + $this->order->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } @@ -273,7 +273,7 @@ class SupplierOrders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach ($request_data as $field => $value) { @@ -282,7 +282,7 @@ class SupplierOrders extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->order->context['caller'] = $request_data['caller']; + $this->order->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } @@ -322,7 +322,7 @@ class SupplierOrders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $contacts = array(); @@ -365,7 +365,7 @@ class SupplierOrders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->order->add_contact($contactid, $type, $source); @@ -414,7 +414,7 @@ class SupplierOrders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $contacts = $this->order->liste_contact(-1, $source, 0, $type); @@ -462,7 +462,7 @@ class SupplierOrders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if ($this->order->delete(DolibarrApiAccess::$user) < 0) { @@ -507,7 +507,7 @@ class SupplierOrders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->order->valid(DolibarrApiAccess::$user, $idwarehouse, $notrigger); @@ -555,7 +555,7 @@ class SupplierOrders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->order->approve(DolibarrApiAccess::$user, $idwarehouse, $secondlevel); @@ -606,7 +606,7 @@ class SupplierOrders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->order->commande(DolibarrApiAccess::$user, $date, $method, $comment); @@ -669,7 +669,7 @@ class SupplierOrders extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach ($lines as $line) { diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index b018cda619d..d1d6aa84f14 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -3411,7 +3411,7 @@ class CommandeFournisseur extends CommonOrder /** * Returns the rights used for this class - * @return stdClass + * @return int */ public function getRights() { @@ -3774,6 +3774,10 @@ class CommandeFournisseurLigne extends CommonOrderLine public $fk_facture; public $rang = 0; + + /** + * @var int special code + */ public $special_code = 0; /** @@ -4014,7 +4018,7 @@ class CommandeFournisseurLigne extends CommonOrderLine $sql .= "null,"; } $sql .= "'".$this->db->escape($this->product_type)."',"; - $sql .= "'".$this->db->escape($this->special_code)."',"; + $sql .= (int) $this->special_code . ","; $sql .= "'".$this->db->escape($this->rang)."',"; $sql .= "'".$this->db->escape($this->qty)."', "; $sql .= " ".(empty($this->vat_src_code) ? "''" : "'".$this->db->escape($this->vat_src_code)."'").","; diff --git a/htdocs/fourn/class/fournisseur.facture-rec.class.php b/htdocs/fourn/class/fournisseur.facture-rec.class.php index 2fbdc41be62..9c02861a112 100644 --- a/htdocs/fourn/class/fournisseur.facture-rec.class.php +++ b/htdocs/fourn/class/fournisseur.facture-rec.class.php @@ -380,7 +380,7 @@ class FactureFournisseurRec extends CommonInvoice $result_insert = $this->addline( $facfourn_src->lines[$i]->fk_product, $facfourn_src->lines[$i]->ref_supplier, - $facfourn_src->lines[$i]->label, + $facfourn_src->lines[$i]->product_label, $facfourn_src->lines[$i]->desc ? $facfourn_src->lines[$i]->desc : $facfourn_src->lines[$i]->description, $facfourn_src->lines[$i]->pu_ht, $facfourn_src->lines[$i]->pu_ttc, @@ -2027,6 +2027,10 @@ class FactureFournisseurLigneRec extends CommonObjectLine public $date_start; public $date_end; public $info_bits; + + /** + * @var int special code + */ public $special_code; public $rang; diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 2f2f97137f8..2f8dd59bdfd 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -147,17 +147,18 @@ class FactureFournisseur extends CommonInvoice /** * Set to 1 if the invoice is completely paid, otherwise is 0 - * @var int + * @var int<0,1> * @deprecated Use $paid */ public $paye; /** * Set to 1 if the invoice is completely paid, otherwise is 0 - * @var int + * @var int<0,1> */ public $paid; /** + * @var int * @deprecated Use $user_creation_id */ public $author; @@ -195,22 +196,32 @@ class FactureFournisseur extends CommonInvoice // Warning: Do not set default value into property definition. it must stay null. // For example to avoid to have substitution done when object is generic and not yet defined. + /** @var ?string */ public $localtax1; + /** @var ?string */ public $localtax2; + /** @var float|int */ public $total_ht; + /** @var float|int */ public $total_tva; + /** @var float|int */ public $total_localtax1; + /** @var float|int */ public $total_localtax2; + /** @var float|int */ public $total_ttc; /** * @deprecated * @see $note_private, $note_public + * @var string */ public $note; - + /** @var string */ public $note_private; + /** @var string */ public $note_public; + /** @var int */ public $propalid; /** @@ -238,6 +249,7 @@ class FactureFournisseur extends CommonInvoice /** * @deprecated + * @var ?Fournisseur */ public $fournisseur; @@ -247,7 +259,9 @@ class FactureFournisseur extends CommonInvoice */ public $fk_facture_source; + /** @var int */ public $fac_rec; + /** @var int */ public $fk_fac_rec_source; public $fields = array( @@ -419,6 +433,10 @@ class FactureFournisseur extends CommonInvoice $nextdatewhen = dol_time_plus_duree($originaldatewhen, $_facrec->frequency, $_facrec->unit_frequency); $previousdaynextdatewhen = dol_time_plus_duree($nextdatewhen, -1, 'd'); $this->socid = $_facrec->socid; + } else { + $originaldatewhen = 0; + $nextdatewhen = 0; + $previousdaynextdatewhen = 0; } $this->entity = $_facrec->entity; // Invoice created in same entity than template @@ -476,7 +494,7 @@ class FactureFournisseur extends CommonInvoice $_facrec->date_when = $now; } $next_date = $_facrec->getNextDate(); // Calculate next date - $result = $_facrec->setValueFrom('date_last_gen', $now, '', null, 'date', '', $user, ''); + $result = $_facrec->setValueFrom('date_last_gen', $now, '', 0, 'date', '', $user, ''); //$_facrec->setValueFrom('nb_gen_done', $_facrec->nb_gen_done + 1); // Not required, +1 already included into setNextDate when second param is 1. $result = $_facrec->setNextDate($next_date, 1); } @@ -494,9 +512,7 @@ class FactureFournisseur extends CommonInvoice if (!empty($newlang)) { $outputlangs = new Translate("", $conf); $outputlangs->setDefaultLang($newlang); - } - - // Array of possible substitutions (See also file mailing-send.php that should manage same substitutions) + } // Array of possible substitutions (See also file mailing-send.php that should manage same substitutions) $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $this); $substitutionarray['__INVOICE_PREVIOUS_MONTH__'] = dol_print_date(dol_time_plus_duree($this->date, -1, 'm'), '%m'); $substitutionarray['__INVOICE_MONTH__'] = dol_print_date($this->date, '%m'); @@ -506,11 +522,10 @@ class FactureFournisseur extends CommonInvoice $substitutionarray['__INVOICE_NEXT_MONTH_TEXT__'] = dol_print_date(dol_time_plus_duree($this->date, 1, 'm'), '%B'); $substitutionarray['__INVOICE_PREVIOUS_YEAR__'] = dol_print_date(dol_time_plus_duree($this->date, -1, 'y'), '%Y'); $substitutionarray['__INVOICE_YEAR__'] = dol_print_date($this->date, '%Y'); - $substitutionarray['__INVOICE_NEXT_YEAR__'] = dol_print_date(dol_time_plus_duree($this->date, 1, 'y'), '%Y'); - // Only for template invoice - $substitutionarray['__INVOICE_DATE_NEXT_INVOICE_BEFORE_GEN__'] = dol_print_date($originaldatewhen, 'dayhour'); - $substitutionarray['__INVOICE_DATE_NEXT_INVOICE_AFTER_GEN__'] = dol_print_date($nextdatewhen, 'dayhour'); - $substitutionarray['__INVOICE_PREVIOUS_DATE_NEXT_INVOICE_AFTER_GEN__'] = dol_print_date($previousdaynextdatewhen, 'dayhour'); + $substitutionarray['__INVOICE_NEXT_YEAR__'] = dol_print_date(dol_time_plus_duree($this->date, 1, 'y'), '%Y'); // Only for template invoice + $substitutionarray['__INVOICE_DATE_NEXT_INVOICE_BEFORE_GEN__'] = $originaldatewhen ? dol_print_date($originaldatewhen, 'dayhour') : ''; + $substitutionarray['__INVOICE_DATE_NEXT_INVOICE_AFTER_GEN__'] = $nextdatewhen ? dol_print_date($nextdatewhen, 'dayhour') : ''; + $substitutionarray['__INVOICE_PREVIOUS_DATE_NEXT_INVOICE_AFTER_GEN__'] = $previousdaynextdatewhen ? dol_print_date($previousdaynextdatewhen, 'dayhour') : ''; $substitutionarray['__INVOICE_COUNTER_CURRENT__'] = $_facrec->nb_gen_done; $substitutionarray['__INVOICE_COUNTER_MAX__'] = $_facrec->nb_gen_max; @@ -680,7 +695,7 @@ class FactureFournisseur extends CommonInvoice $this->updateline( $idligne, $line->desc ? $line->desc : $line->description, - $line->pu_ht, + $line->subprice, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, @@ -709,7 +724,7 @@ class FactureFournisseur extends CommonInvoice /* * Insert lines of template invoices */ - if (! $error && $this->fac_rec > 0) { + if (! $error && $this->fac_rec > 0 && $_facrec instanceof FactureFournisseurRec) { foreach ($_facrec->lines as $i => $val) { if ($_facrec->lines[$i]->fk_product) { $prod = new Product($this->db); @@ -1156,8 +1171,12 @@ class FactureFournisseur extends CommonInvoice if (isset($this->label)) { $this->label = trim($this->label); } - if (isset($this->paye)) { - $this->paye = (int) $this->paye; + if (isset($this->paid)) { + $this->paid = (int) (bool) $this->paye; + $this->paye = $this->paid; + } elseif (isset($this->paye)) { + $this->paid = (int) (bool) $this->paye; + $this->paye = $this->paid; } if (isset($this->close_code)) { $this->close_code = trim($this->close_code); @@ -1165,31 +1184,24 @@ class FactureFournisseur extends CommonInvoice if (isset($this->close_note)) { $this->close_note = trim($this->close_note); } - if (isset($this->localtax1)) { - $this->localtax1 = trim($this->localtax1); - } - if (isset($this->localtax2)) { - $this->localtax2 = trim($this->localtax2); - } if (empty($this->total_ht)) { $this->total_ht = 0; } if (empty($this->total_tva)) { $this->total_tva = 0; } - // if (isset($this->total_localtax1)) $this->total_localtax1=trim($this->total_localtax1); - // if (isset($this->total_localtax2)) $this->total_localtax2=trim($this->total_localtax2); if (isset($this->total_ttc)) { $this->total_ttc = (float) $this->total_ttc; } - if (isset($this->statut)) { - $this->statut = (int) $this->statut; - } if (isset($this->status)) { $this->status = (int) $this->status; + $this->statut = $this->status; + } elseif (isset($this->statut)) { + $this->status = (int) $this->statut; + $this->statut = $this->status; } - if (isset($this->author)) { - $this->author = trim($this->author); + if (isset($this->author)) { // TODO: user_creation_id? + $this->author = trim((string) $this->author); } if (isset($this->fk_user_valid)) { $this->fk_user_valid = trim($this->fk_user_valid); @@ -1208,7 +1220,8 @@ class FactureFournisseur extends CommonInvoice $this->cond_reglement_id = (int) $this->cond_reglement_id; } if (isset($this->note_private)) { - $this->note = trim($this->note_private); + $this->note_private = trim($this->note_private); + $this->note = $this->note_private; } if (isset($this->note_public)) { $this->note_public = trim($this->note_public); @@ -1239,11 +1252,11 @@ class FactureFournisseur extends CommonInvoice $sql .= " tms=".(dol_strlen($this->tms) != 0 ? "'".$this->db->idate($this->tms)."'" : 'null').","; } $sql .= " libelle=".(isset($this->label) ? "'".$this->db->escape($this->label)."'" : "null").","; - $sql .= " paye=".(isset($this->paye) ? ((int) $this->paye) : "0").","; + $sql .= " paye=".(isset($this->paid) ? ((int) $this->paid) : "0").","; $sql .= " close_code=".(isset($this->close_code) ? "'".$this->db->escape($this->close_code)."'" : "null").","; $sql .= " close_note=".(isset($this->close_note) ? "'".$this->db->escape($this->close_note)."'" : "null").","; - $sql .= " localtax1=".(isset($this->localtax1) ? ((float) $this->localtax1) : "null").","; - $sql .= " localtax2=".(isset($this->localtax2) ? ((float) $this->localtax2) : "null").","; + $sql .= " localtax1=".(isset($this->total_localtax1) ? ((float) $this->total_localtax1) : "null").","; + $sql .= " localtax2=".(isset($this->total_localtax2) ? ((float) $this->total_localtax2) : "null").","; $sql .= " total_ht=".(isset($this->total_ht) ? ((float) $this->total_ht) : "null").","; $sql .= " total_tva=".(isset($this->total_tva) ? ((float) $this->total_tva) : "null").","; $sql .= " total_ttc=".(isset($this->total_ttc) ? ((float) $this->total_ttc) : "null").","; @@ -1449,7 +1462,7 @@ class FactureFournisseur extends CommonInvoice $this->fetch_lines(); $list_rowid_det = array(); foreach ($this->lines as $key => $invoiceline) { - $list_rowid_det[] = $invoiceline->rowid; + $list_rowid_det[] = $invoiceline->id; } // Consumned discounts are freed @@ -1567,13 +1580,13 @@ class FactureFournisseur extends CommonInvoice * @param User $user Object user * @param string $close_code Code indicates whether the class has paid in full while payment is incomplete. Not implemented yet. * @param string $close_note Comment informs if the class has been paid while payment is incomplete. Not implemented yet. - * @return int Return integer <0 si ko, >0 si ok + * @return int<-1,1> Return integer <0 si ko, >0 si ok */ public function setPaid($user, $close_code = '', $close_note = '') { $error = 0; - if ($this->paye != 1) { + if ($this->paid != 1) { $this->db->begin(); $now = dol_now(); @@ -1766,7 +1779,7 @@ class FactureFournisseur extends CommonInvoice $this->fetch_lines(); // Check parameters - if ($this->statut > self::STATUS_DRAFT) { // This is to avoid to validate twice (avoid errors on logs and stock management) + if ($this->status > self::STATUS_DRAFT) { // This is to avoid to validate twice (avoid errors on logs and stock management) dol_syslog(get_class($this)."::validate no draft status", LOG_WARNING); return 0; } @@ -1939,6 +1952,7 @@ class FactureFournisseur extends CommonInvoice if (!$error) { $this->ref = $this->newref; $this->statut = self::STATUS_VALIDATED; + $this->status = self::STATUS_VALIDATED; //$this->date_validation=$now; this is stored into log table } @@ -1971,7 +1985,7 @@ class FactureFournisseur extends CommonInvoice $error = 0; - if ($this->statut == self::STATUS_DRAFT) { + if ($this->status == self::STATUS_DRAFT) { dol_syslog(__METHOD__." already draft status", LOG_WARNING); return 0; } @@ -2062,19 +2076,19 @@ class FactureFournisseur extends CommonInvoice * @param int $origin_id id origin document * @param double $pu_devise Amount in currency * @param string $ref_supplier Supplier ref - * @param string $special_code Special code + * @param int $special_code Special code * @param int $fk_parent_line Parent line id * @param int $fk_remise_except Id discount used * @return int >0 if OK, <0 if KO */ - public function addline($desc, $pu, $txtva, $txlocaltax1, $txlocaltax2, $qty, $fk_product = 0, $remise_percent = 0, $date_start = 0, $date_end = 0, $fk_code_ventilation = 0, $info_bits = 0, $price_base_type = 'HT', $type = 0, $rang = -1, $notrigger = 0, $array_options = [], $fk_unit = null, $origin_id = 0, $pu_devise = 0, $ref_supplier = '', $special_code = '', $fk_parent_line = 0, $fk_remise_except = 0) + public function addline($desc, $pu, $txtva, $txlocaltax1, $txlocaltax2, $qty, $fk_product = 0, $remise_percent = 0, $date_start = 0, $date_end = 0, $fk_code_ventilation = 0, $info_bits = 0, $price_base_type = 'HT', $type = 0, $rang = -1, $notrigger = 0, $array_options = [], $fk_unit = null, $origin_id = 0, $pu_devise = 0, $ref_supplier = '', $special_code = 0, $fk_parent_line = 0, $fk_remise_except = 0) { global $langs, $mysoc; dol_syslog(get_class($this)."::addline $desc,$pu,$qty,$txtva,$fk_product,$remise_percent,$date_start,$date_end,$fk_code_ventilation,$info_bits,$price_base_type,$type,$fk_unit,fk_remise_except=$fk_remise_except", LOG_DEBUG); include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; - if ($this->statut == self::STATUS_DRAFT) { + if ($this->status == self::STATUS_DRAFT) { // Clean parameters if (empty($remise_percent)) { $remise_percent = 0; @@ -2253,7 +2267,7 @@ class FactureFournisseur extends CommonInvoice $supplierinvoiceline->fk_remise_except = $fk_remise_except; - $supplierinvoiceline->special_code = (string) $special_code; + $supplierinvoiceline->special_code = (int) $special_code; $supplierinvoiceline->fk_parent_line = $fk_parent_line; $supplierinvoiceline->origin = $this->origin; $supplierinvoiceline->origin_id = $origin_id; @@ -2327,8 +2341,8 @@ class FactureFournisseur extends CommonInvoice * @param int|null $fk_unit Code of the unit to use. Null to use the default one * @param double $pu_devise Amount in currency * @param string $ref_supplier Supplier ref - * @param integer $rang line rank - * @return int Return integer <0 if KO, >0 if OK + * @param int $rang Line rank + * @return int<-1,1> Return integer <0 if KO, >0 if OK */ public function updateline($id, $desc, $pu, $vatrate, $txlocaltax1 = 0, $txlocaltax2 = 0, $qty = 1, $idproduct = 0, $price_base_type = 'HT', $info_bits = 0, $type = 0, $remise_percent = 0, $notrigger = 0, $date_start = '', $date_end = '', $array_options = [], $fk_unit = null, $pu_devise = 0, $ref_supplier = '', $rang = 0) { @@ -2428,7 +2442,7 @@ class FactureFournisseur extends CommonInvoice $line->qty = ($this->type == self::TYPE_CREDIT_NOTE ? abs((float) $qty) : $qty); // For credit note, quantity is always positive and unit price negative $line->subprice = ($this->type == self::TYPE_CREDIT_NOTE ? -abs($pu_ht) : $pu_ht); // For credit note, unit price always negative, always positive otherwise - $line->pu_ht = ($this->type == self::TYPE_CREDIT_NOTE ? -abs($pu_ht) : $pu_ht); // For credit note, unit price always negative, always positive otherwise + $line->pu_ht = $line->subprice; // deprecated $line->pu_ttc = ($this->type == self::TYPE_CREDIT_NOTE ? -abs($pu_ttc) : $pu_ttc); // For credit note, unit price always negative, always positive otherwise $line->remise_percent = $remise_percent; @@ -2737,9 +2751,9 @@ class FactureFournisseur extends CommonInvoice /** * getTooltipContentArray * - * @param array $params ex option, infologin + * @param array{moretitle?:string} $params ex option, infologin * @since v18 - * @return array + * @return array{picto:string,ref?:string,refsupplier?:string,label?:string,date?:string,date_echeance?:string,amountht?:string,total_ht?:string,totaltva?:string,amountlt1?:string,amountlt2?:string,amountrevenustamp?:string,totalttc?:string} */ public function getTooltipContentArray($params) { @@ -2968,12 +2982,13 @@ class FactureFournisseur extends CommonInvoice $mybool = ((bool) @include_once $dir.$file) || $mybool; } - if ($mybool === false) { + if (!$mybool) { dol_print_error(null, "Failed to include file ".$file); return ''; } $obj = new $classname(); + '@phan-var-force ModeleNumRefSuppliersInvoices $obj'; $numref = ""; $numref = $obj->getNextValue($soc, $this, $mode); @@ -3047,7 +3062,7 @@ class FactureFournisseur extends CommonInvoice $line->desc = $langs->trans("Description")." ".$xnbp; $line->qty = 1; $line->subprice = 100; - $line->pu_ht = 100; // the canelle template use pu_ht and not subprice + $line->pu_ht = $line->subprice; // the canelle template use pu_ht and not subprice $line->price = 100; $line->tva_tx = 19.6; $line->localtax1_tx = 0; @@ -3152,8 +3167,8 @@ class FactureFournisseur extends CommonInvoice // Clear fields $object->ref_supplier = (empty($this->ref_supplier) ? $langs->trans("CopyOf").' '.$object->ref_supplier : $this->ref_supplier); - $object->author = $user->id; - $object->user_validation_id = 0; + $object->author = $user->id; // FIXME? user_validation_id is replacement for author + $object->user_validation_id = 0; // FIXME? user_validation_id is replacement for author $object->fk_facture_source = 0; $object->date_creation = ''; $object->date_validation = ''; @@ -3209,8 +3224,8 @@ class FactureFournisseur extends CommonInvoice * @param int $hidedetails Hide details of lines * @param int $hidedesc Hide description * @param int $hideref Hide ref - * @param null|array $moreparams Array to provide more information - * @return int Return integer <0 if KO, 0 if nothing done, >0 if OK + * @param ?array $moreparams Array to provide more information + * @return int<-1,1> Return integer <0 if KO, 0 if nothing done, >0 if OK */ public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null) { @@ -3239,7 +3254,7 @@ class FactureFournisseur extends CommonInvoice /** * Returns the rights used for this class - * @return stdClass + * @return int */ public function getRights() { @@ -3326,7 +3341,7 @@ class FactureFournisseur extends CommonInvoice * Return clicable link of object (with eventually picto) * * @param string $option Where point the link (0=> main card, 1,2 => shipment, 'nolink'=>No link) - * @param array $arraydata Array of data + * @param ?array{selected?:int<0,1>} $arraydata Array of data * @return string HTML Code for Kanban thumb. */ public function getKanbanView($option = '', $arraydata = null) @@ -3721,6 +3736,9 @@ class SupplierInvoiceLine extends CommonObjectLine */ public $table_element = 'facture_fourn_det'; + /** + * @var static + */ public $oldline; /** @@ -3778,7 +3796,7 @@ class SupplierInvoiceLine extends CommonObjectLine /** * This field may contains label of line (when invoice create from order) * @var string - * @deprecated + * @deprecated Use $product_label */ public $label; @@ -3797,6 +3815,9 @@ class SupplierInvoiceLine extends CommonObjectLine */ public $fk_code_ventilation; + /** + * @var int<0,1> + */ public $skip_update_total; // Skip update price total for special lines /** @@ -3917,6 +3938,9 @@ class SupplierInvoiceLine extends CommonObjectLine */ public $fk_parent_line; + /** + * @var int special code + */ public $special_code; /** @@ -3990,7 +4014,7 @@ class SupplierInvoiceLine extends CommonObjectLine $this->product_desc = $obj->product_desc; $this->subprice = $obj->pu_ht; - $this->pu_ht = $obj->pu_ht; + $this->pu_ht = $this->subprice; $this->pu_ttc = $obj->pu_ttc; $this->tva_tx = $obj->tva_tx; $this->localtax1_tx = $obj->localtax1_tx; @@ -4010,6 +4034,7 @@ class SupplierInvoiceLine extends CommonObjectLine $this->fk_product = $obj->fk_product; $this->product_type = $obj->product_type; $this->product_label = $obj->product_label; + $this->label = $obj->product_label; $this->info_bits = $obj->info_bits; $this->fk_parent_line = $obj->fk_parent_line; $this->special_code = $obj->special_code; @@ -4090,7 +4115,7 @@ class SupplierInvoiceLine extends CommonObjectLine { global $conf; - $pu = price2num($this->pu_ht); + $pu = price2num($this->subprice); $qty = price2num($this->qty); // Check parameters @@ -4142,7 +4167,7 @@ class SupplierInvoiceLine extends CommonObjectLine $sql .= ", ref = '".$this->db->escape($this->ref_supplier ? $this->ref_supplier : $this->ref)."'"; $sql .= ", date_start = ".($this->date_start != '' ? "'".$this->db->idate($this->date_start)."'" : "null"); $sql .= ", date_end = ".($this->date_end != '' ? "'".$this->db->idate($this->date_end)."'" : "null"); - $sql .= ", pu_ht = ".price2num($this->pu_ht); + $sql .= ", pu_ht = ".price2num($this->subprice); $sql .= ", pu_ttc = ".price2num($this->pu_ttc); $sql .= ", qty = ".price2num($this->qty); $sql .= ", remise_percent = ".price2num($this->remise_percent); @@ -4325,7 +4350,11 @@ class SupplierInvoiceLine extends CommonObjectLine $sql .= ')'; $sql .= " VALUES (".$this->fk_facture_fourn.","; $sql .= " ".($this->fk_parent_line > 0 ? "'".$this->db->escape($this->fk_parent_line)."'" : "null").","; - $sql .= " ".(!empty($this->label) ? "'".$this->db->escape($this->label)."'" : "null").","; + $product_label + = !empty($this->product_label) + ? $this->product_label : + (!empty($this->label) ? $this->label : null); + $sql .= " ".(!empty($product_label) ? "'".$this->db->escape($product_label)."'" : "null").","; $sql .= " '".$this->db->escape($this->desc ? $this->desc : $this->description)."',"; $sql .= " '".$this->db->escape($this->ref_supplier)."',"; $sql .= " ".price2num($this->qty).","; @@ -4391,7 +4420,7 @@ class SupplierInvoiceLine extends CommonObjectLine return -3; } } else { - $result = $discount->link_to_invoice($this->rowid, 0); + $result = $discount->link_to_invoice($this->id, 0); if ($result < 0) { $this->error = $discount->error; dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); @@ -4450,7 +4479,7 @@ class SupplierInvoiceLine extends CommonObjectLine $sql .= ", total_localtax1 = ".price2num($this->total_localtax1); $sql .= ", total_localtax2 = ".price2num($this->total_localtax2); $sql .= ", total_ttc = ".price2num($this->total_ttc); - $sql .= " WHERE rowid = ".((int) $this->rowid); + $sql .= " WHERE rowid = ".((int) $this->id); dol_syslog("FactureFournisseurLigne.class.php::update_total", LOG_DEBUG); diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 0f716bcecc1..f56b77ae139 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -1420,7 +1420,6 @@ if (empty($reshook)) { $langs->load("errors"); $db->rollback(); $action = 'create'; - $_GET['socid'] = $_POST['socid']; } else { $db->commit(); header("Location: ".$_SERVER['PHP_SELF']."?id=".urlencode((string) ($id))); @@ -1503,9 +1502,9 @@ if (empty($reshook)) { $result_order = $soapclient_order->call("createOrder", $ws_parameters, $ws_ns, ''); if (empty($result_order["result"]["result_code"])) { //No result, check error str - setEventMessages($langs->trans("SOAPError")." '".$soapclient_order->error_str."'", null, 'errors'); + setEventMessages($langs->trans("Error")." '".$soapclient_order->error_str."'", null, 'errors'); } elseif ($result_order["result"]["result_code"] != "OK") { //Something went wrong - setEventMessages($langs->trans("SOAPError")." '".$result_order["result"]["result_code"]."' - '".$result_order["result"]["result_label"]."'", null, 'errors'); + setEventMessages($langs->trans("Error")." '".$result_order["result"]["result_code"]."' - '".$result_order["result"]["result_label"]."'", null, 'errors'); } else { setEventMessages($langs->trans("RemoteOrderRef")." ".$result_order["ref"], null, 'mesgs'); } @@ -2893,7 +2892,7 @@ if ($action == 'create') { $ws_parameters = array('authentication' => $ws_authentication, 'id' => '', 'ref' => $ref_supplier); $result_product = $soapclient_product->call("getProductOrService", $ws_parameters, $ws_ns, ''); if (!$result_product) { - setEventMessages($line_id.$langs->trans("SOAPError")." ".$soapclient_product->error_str." - ".$soapclient_product->response, null, 'errors'); + setEventMessages($line_id.$langs->trans("Error")." SOAP ".$soapclient_product->error_str." - ".$soapclient_product->response, null, 'errors'); $error_occurred = true; break; } @@ -2901,7 +2900,7 @@ if ($action == 'create') { // Check the result code $status_code = $result_product["result"]["result_code"]; if (empty($status_code)) { //No result, check error str - setEventMessages($langs->trans("SOAPError")." '".$soapclient_order->error_str."'", null, 'errors'); + setEventMessages($langs->trans("Error")." SOAP '".$soapclient_order->error_str."'", null, 'errors'); } elseif ($status_code != "OK") { //Something went wrong if ($status_code == "NOT_FOUND") { setEventMessages($line_id.$langs->trans("SupplierMissingRef")." '".$ref_supplier."'", null, 'warnings'); diff --git a/htdocs/fourn/commande/index.php b/htdocs/fourn/commande/index.php index 0c96ebe718e..46fa4f15166 100644 --- a/htdocs/fourn/commande/index.php +++ b/htdocs/fourn/commande/index.php @@ -4,6 +4,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2012 Vinicius Nogueira * Copyright (C) 2019 Nicolas ZABOURI + * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -263,7 +264,7 @@ if ($resql) { $userstatic->lastname = $obj->lastname; $userstatic->firstname = $obj->firstname; $userstatic->email = $obj->email; - $userstatic->statut = $obj->statut; + $userstatic->status = $obj->statut; print $userstatic->getNomUrl(1); print ''; print "\n"; diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index e7a23eab863..64df4a9dfa0 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -6,7 +6,7 @@ * Copyright (C) 2014 Marcos García * Copyright (C) 2014 Juanjo Menent * Copyright (C) 2016 Ferran Marcet - * Copyright (C) 2018-2021 Frédéric France + * Copyright (C) 2018-2024 Frédéric France * Copyright (C) 2018-2022 Charlene Benke * Copyright (C) 2019 Nicolas Zabouri * Copyright (C) 2021-2023 Alexandre Spangaro @@ -730,8 +730,8 @@ if (empty($reshook)) { } else { $db->rollback(); $action = 'create'; - $_GET["origin"] = $_POST["origin"]; - $_GET["originid"] = $_POST["originid"]; + $_GET["origin"] = $_POST["origin"]; // Keep this ? + $_GET["originid"] = $_POST["originid"]; // Keep this ? setEventMessages("Error", null, 'errors'); $error++; } @@ -1804,7 +1804,7 @@ if ($resql) { $userstatic->login = $obj->login; $userstatic->photo = $obj->photo; $userstatic->email = $obj->user_email; - $userstatic->statut = $obj->user_status; + $userstatic->status = $obj->user_status; if (!empty($arrayfields['u.login']['checked'])) { print ''; if ($userstatic->id) { diff --git a/htdocs/fourn/facture/card-rec.php b/htdocs/fourn/facture/card-rec.php index 10dd9fd4e45..f7b0db9ae7f 100644 --- a/htdocs/fourn/facture/card-rec.php +++ b/htdocs/fourn/facture/card-rec.php @@ -527,7 +527,7 @@ if (empty($reshook)) { // Define special_code for special lines $special_code = 0; - // if (empty($_POST['qty'])) $special_code=3; // Options should not exists on invoices + // if (!GETPOST('qty')) $special_code=3; // Options should not exists on invoices // Ecrase $pu par celui du produit // Ecrase $desc par celui du produit diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index ead7de640e9..0a6ea8b1570 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -801,7 +801,7 @@ if (empty($reshook)) { if (empty($dateinvoice)) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('DateInvoice')), null, 'errors'); $action = 'create'; - $_GET['socid'] = $_POST['socid']; + //$_GET['socid'] = $_POST['socid']; $error++; } elseif ($dateinvoice > (dol_get_last_hour(dol_now('tzuserrel')) + (!getDolGlobalString('INVOICE_MAX_FUTURE_DELAY') ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) { $error++; @@ -867,7 +867,7 @@ if (empty($reshook)) { if (empty($dateinvoice)) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('DateInvoice')), null, 'errors'); $action = 'create'; - $_GET['socid'] = $_POST['socid']; + //$_GET['socid'] = $_POST['socid']; $error++; } elseif ($dateinvoice > (dol_get_last_hour(dol_now('tzuserrel')) + (!getDolGlobalString('INVOICE_MAX_FUTURE_DELAY') ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) { $error++; @@ -878,7 +878,7 @@ if (empty($reshook)) { if (!GETPOST('ref_supplier')) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('RefSupplierBill')), null, 'errors'); $action = 'create'; - $_GET['socid'] = $_POST['socid']; + //$_GET['socid'] = $_POST['socid']; $error++; } @@ -1035,7 +1035,7 @@ if (empty($reshook)) { if (empty($dateinvoice)) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('DateInvoice')), null, 'errors'); $action = 'create'; - $_GET['socid'] = $_POST['socid']; + //$_GET['socid'] = $_POST['socid']; $error++; } elseif ($dateinvoice > (dol_get_last_hour(dol_now('tzuserrel')) + (!getDolGlobalString('INVOICE_MAX_FUTURE_DELAY') ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) { $error++; @@ -1046,7 +1046,7 @@ if (empty($reshook)) { if (!GETPOST('ref_supplier')) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('RefSupplierBill')), null, 'errors'); $action = 'create'; - $_GET['socid'] = $_POST['socid']; + //$_GET['socid'] = $_POST['socid']; $error++; } @@ -1405,7 +1405,7 @@ if (empty($reshook)) { setEventMessages($object->error, $object->errors, 'errors'); $action = 'create'; - $_GET['socid'] = $_POST['socid']; + //$_GET['socid'] = $_POST['socid']; } else { $db->commit(); @@ -1764,7 +1764,7 @@ if (empty($reshook)) { 0, $pu_devise, GETPOST('fourn_ref', 'alpha'), - '' + 0 ); } if ($idprod == -99 || $idprod == 0) { @@ -2121,6 +2121,7 @@ if ($action == 'create') { $classname = 'CommandeFournisseur'; } $objectsrc = new $classname($db); + '@phan-var-force Project|Commande|Propal|Facture|Contrat|CommandeFournisseur|CommonObject $objectsrc'; $objectsrc->fetch($originid); $objectsrc->fetch_thirdparty(); @@ -2160,19 +2161,19 @@ if ($action == 'create') { $objectsrc->fetch_origin(); } - if (!empty($objectsrc->commandeFournisseur)) { - $supplierOrder = $objectsrc->commandeFournisseur; - if (empty($cond_reglement_id) && !empty($supplierOrder->cond_reglement_id)) { - $cond_reglement_id = $supplierOrder->cond_reglement_id; + if (!empty($objectsrc->origin_object)) { + $originObject = $objectsrc->origin_object; + if (empty($cond_reglement_id) && !empty($originObject->cond_reglement_id)) { + $cond_reglement_id = $originObject->cond_reglement_id; } - if (empty($mode_reglement_id) && !empty($supplierOrder->mode_reglement_id)) { - $mode_reglement_id = $supplierOrder->mode_reglement_id; + if (empty($mode_reglement_id) && !empty($originObject->mode_reglement_id)) { + $mode_reglement_id = $originObject->mode_reglement_id; } - if (empty($fk_account) && !empty($supplierOrder->fk_account)) { - $fk_account = $supplierOrder->fk_account; + if (empty($fk_account) && !empty($originObject->fk_account)) { + $fk_account = $originObject->fk_account; } - if (empty($transport_mode_id) && !empty($supplierOrder->transport_mode_id)) { - $transport_mode_id = $supplierOrder->transport_mode_id; + if (empty($transport_mode_id) && !empty($originObject->transport_mode_id)) { + $transport_mode_id = $originObject->transport_mode_id; } } } @@ -2222,8 +2223,8 @@ if ($action == 'create') { $datetmp = dol_mktime(12, 0, 0, GETPOSTINT('echmonth'), GETPOSTINT('echday'), GETPOSTINT('echyear')); $datedue = ($datetmp == '' ? -1 : $datetmp); - if (isModEnabled("multicurrency") && !empty($soc->multicurrency_code)) { - $currency_code = $soc->multicurrency_code; + if (isModEnabled("multicurrency") && !empty($societe->multicurrency_code)) { + $currency_code = $societe->multicurrency_code; } } diff --git a/htdocs/fourn/facture/document.php b/htdocs/fourn/facture/document.php index ea6fe3335d0..584f9c20303 100644 --- a/htdocs/fourn/facture/document.php +++ b/htdocs/fourn/facture/document.php @@ -157,7 +157,7 @@ if ($object->id > 0) { * Confirm delete file */ if ($action == 'delete') { - print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&urlfile='.urlencode($_GET["urlfile"]), $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile', '', 0, 1); + print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&urlfile='.urlencode(GETPOST("urlfile")), $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile', '', 0, 1); } print ''; diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index 3817273ab6f..6ccb99e4c6e 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -68,8 +68,8 @@ $search_amount_no_tax = GETPOST("search_amount_no_tax", "alpha"); $search_amount_all_tax = GETPOST("search_amount_all_tax", "alpha"); $search_ref = GETPOST('sf_ref') ? GETPOST('sf_ref', 'alpha') : GETPOST('search_ref', 'alpha'); $search_refsupplier = GETPOST('search_refsupplier', 'alpha'); -$search_type = GETPOSTINT('search_type'); -$search_subtype = GETPOSTINT('search_subtype'); +$search_type = GETPOST('search_type', 'intcomma'); +$search_subtype = GETPOST('search_subtype', 'intcomma'); $search_project = GETPOST('search_project', 'alpha'); $search_company = GETPOST('search_company', 'alpha'); $search_company_alias = GETPOST('search_company_alias', 'alpha'); @@ -85,8 +85,8 @@ $search_multicurrency_montant_ht = GETPOST('search_multicurrency_montant_ht', 'a $search_multicurrency_montant_vat = GETPOST('search_multicurrency_montant_vat', 'alpha'); $search_multicurrency_montant_ttc = GETPOST('search_multicurrency_montant_ttc', 'alpha'); $search_status = GETPOST('search_status', 'intcomma'); // Can be '' or a numeric -$search_paymentmode = GETPOSTINT('search_paymentmode'); -$search_paymentcond = GETPOSTINT('search_paymentcond'); +$search_paymentmode = GETPOST('search_paymentmode', 'intcomma'); +$search_paymentcond = GETPOST('search_paymentcond', 'intcomma'); $search_town = GETPOST('search_town', 'alpha'); $search_zip = GETPOST('search_zip', 'alpha'); $search_state = GETPOST("search_state"); @@ -137,7 +137,6 @@ $socid = GETPOSTINT('socid'); // Security check if ($user->socid > 0) { $action = ''; - $_GET["action"] = ''; $socid = $user->socid; } @@ -346,10 +345,10 @@ if (empty($reshook)) { setEventMessages($objecttmp->ref.' '.$langs->trans("ProcessingError"), $hookmanager->errors, 'errors'); } - if ($objecttmp->statut == FactureFournisseur::STATUS_DRAFT) { + if ($objecttmp->status == FactureFournisseur::STATUS_DRAFT) { $error++; setEventMessages($objecttmp->ref.' '.$langs->trans("Draft"), $objecttmp->errors, 'errors'); - } elseif ($objecttmp->paye || $objecttmp->resteapayer == 0) { + } elseif ($objecttmp->paid || $objecttmp->resteapayer == 0) { $error++; setEventMessages($objecttmp->ref.' '.$langs->trans("AlreadyPaid"), $objecttmp->errors, 'errors'); } elseif ($objecttmp->resteapayer < 0) { @@ -1095,20 +1094,13 @@ if (!empty($arrayfields['f.ref_supplier']['checked'])) { // Type if (!empty($arrayfields['f.type']['checked'])) { print ''; } // Invoice Subtype @@ -1597,6 +1589,7 @@ while ($i < $imaxinloop) { $facturestatic->alreadypaid = ($paiement ? $paiement : 0); $facturestatic->paye = $obj->paye; + $facturestatic->paid = $obj->paye; $facturestatic->date = $db->jdate($obj->datef); diff --git a/htdocs/fourn/paiement/card.php b/htdocs/fourn/paiement/card.php index 966cde2511b..0616033cd9f 100644 --- a/htdocs/fourn/paiement/card.php +++ b/htdocs/fourn/paiement/card.php @@ -3,6 +3,7 @@ * Copyright (C) 2005 Marc Barilley / Ocebo * Copyright (C) 2006-2010 Laurent Destailleur * Copyright (C) 2014 Marcos García + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -309,6 +310,7 @@ if ($result > 0) { $facturestatic->total_tva = $objp->total_tva; $facturestatic->total_ttc = $objp->total_ttc; $facturestatic->statut = $objp->status; + $facturestatic->status = $objp->status; $facturestatic->alreadypaid = -1; // unknown print ''; diff --git a/htdocs/holiday/list.php b/htdocs/holiday/list.php index a4eaae03a85..c567bad831d 100644 --- a/htdocs/holiday/list.php +++ b/htdocs/holiday/list.php @@ -53,7 +53,6 @@ $cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button $toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'holidaylist'; // To manage different context of search $mode = GETPOST('mode', 'alpha'); // for switch mode view result - $backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') @@ -83,7 +82,7 @@ if (!$sortfield) { $sortfield = "cp.ref"; } -$sall = trim((GETPOST('search_all', 'alphanohtml') != '') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml')); +$search_all = trim((GETPOST('search_all', 'alphanohtml') != '') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml')); $search_ref = GETPOST('search_ref', 'alphanohtml'); $search_day_create = GETPOST('search_day_create', 'int'); $search_month_create = GETPOST('search_month_create', 'int'); @@ -94,10 +93,10 @@ $search_year_start = GETPOST('search_year_start', 'int'); $search_day_end = GETPOST('search_day_end', 'int'); $search_month_end = GETPOST('search_month_end', 'int'); $search_year_end = GETPOST('search_year_end', 'int'); -$search_employee = GETPOSTINT('search_employee'); -$search_valideur = GETPOSTINT('search_valideur'); +$search_employee = GETPOST('search_employee', 'intcomma'); +$search_valideur = GETPOST('search_valideur', 'intcomma'); $search_status = GETPOST('search_status', 'intcomma'); -$search_type = GETPOSTINT('search_type'); +$search_type = GETPOST('search_type', 'intcomma'); // Initialize technical objects $object = new Holiday($db); @@ -322,8 +321,8 @@ $sql .= ", ".MAIN_DB_PREFIX."user as uu, ".MAIN_DB_PREFIX."user as ua"; $sql .= " WHERE cp.entity IN (".getEntity('holiday').")"; $sql .= " AND cp.fk_user = uu.rowid AND cp.fk_validator = ua.rowid "; // Hack pour la recherche sur le tableau // Search all -if (!empty($sall)) { - $sql .= natural_search(array_keys($fieldstosearchall), $sall); +if (!empty($search_all)) { + $sql .= natural_search(array_keys($fieldstosearchall), $search_all); } // Ref if (!empty($search_ref)) { @@ -552,14 +551,14 @@ $objecttmp = new Holiday($db); $trackid = 'leav'.$object->id; include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; -if ($sall) { +if ($search_all) { $setupstring = ''; foreach ($fieldstosearchall as $key => $val) { $fieldstosearchall[$key] = $langs->trans($val); $setupstring .= $key."=".$val.";"; } print ''."\n"; - print '
      '.$langs->trans("FilterOnInto", $sall).implode(', ', $fieldstosearchall).'
      '; + print '
      '.$langs->trans("FilterOnInto", $search_all).implode(', ', $fieldstosearchall).'
      '; } $moreforfilter = ''; diff --git a/htdocs/hrm/compare.php b/htdocs/hrm/compare.php index 8286c7f0cf4..7e0aab08e4e 100644 --- a/htdocs/hrm/compare.php +++ b/htdocs/hrm/compare.php @@ -5,6 +5,7 @@ * Copyright (C) 2021 Jean-Pascal BOUDET * Copyright (C) 2021 Grégory BLEMAND * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -153,16 +154,16 @@ $fk_usergroup1 = GETPOST('fk_usergroup1');
      '; - $listtype = array( + $typearray = array( FactureFournisseur::TYPE_STANDARD => $langs->trans("InvoiceStandard"), FactureFournisseur::TYPE_REPLACEMENT => $langs->trans("InvoiceReplacement"), FactureFournisseur::TYPE_CREDIT_NOTE => $langs->trans("InvoiceAvoir"), FactureFournisseur::TYPE_DEPOSIT => $langs->trans("InvoiceDeposit"), ); - /* - if (!empty($conf->global->INVOICE_USE_SITUATION)) - { - $listtype[Facture::TYPE_SITUATION] = $langs->trans("InvoiceSituation"); - } - */ - //$listtype[Facture::TYPE_PROFORMA]=$langs->trans("InvoiceProForma"); // A proformat invoice is not an invoice but must be an order. - print $form->selectarray('search_type', $listtype, $search_type, 1, 0, 0, '', 0, 0, 0, 'ASC', 'maxwidth100'); + print $form->selectarray('search_type', $typearray, $search_type, 1, 0, 0, '', 0, 0, 0, 'ASC', 'maxwidth100'); print '
      trans('OrJobToCompare') . ''; - $j = new Job($db); - $jobs = $j->fetchAll(); - $TJobs = array(); + echo $langs->trans('OrJobToCompare') . ''; + $j = new Job($db); + $jobs = $j->fetchAll(); + $TJobs = array(); foreach ($jobs as &$j) { $TJobs[$j->id] = $j->label; } - print img_picto('', 'jobprofile', 'class="pictofixedwidth"').$form->selectarray('fk_job', $TJobs, $fk_job, 1); + print img_picto('', 'jobprofile', 'class="pictofixedwidth"').$form->selectarray('fk_job', $TJobs, $fk_job, 1); ?>
      @@ -502,8 +503,8 @@ function displayUsersListWithPicto(&$TUser, $fk_usergroup = 0, $namelist = 'list * * Allow to get skill(s) of a user * - * @param array $TUser array of employees we need to get skills - * @return array|int + * @param int[] $TUser array of employees we need to get skills + * @return array */ function getSkillForUsers($TUser) { @@ -515,12 +516,12 @@ function getSkillForUsers($TUser) } $sql = 'SELECT sk.rowid, sk.label, sk.description, sk.skill_type, sr.fk_object, sr.objecttype, sr.fk_skill, '; - $sql.= ' MAX(sr.rankorder) as rankorder'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'hrm_skill sk'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'hrm_skillrank sr ON (sk.rowid = sr.fk_skill)'; - $sql.= " WHERE sr.objecttype = '".$db->escape(SkillRank::SKILLRANK_TYPE_USER)."'"; - $sql.= ' AND sr.fk_object IN ('.$db->sanitize(implode(',', $TUser)).')'; - $sql.= " GROUP BY sk.rowid, sk.label, sk.description, sk.skill_type, sr.fk_object, sr.objecttype, sr.fk_skill "; // group par competence + $sql .= ' MAX(sr.rankorder) as rankorder'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'hrm_skill sk'; + $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'hrm_skillrank sr ON (sk.rowid = sr.fk_skill)'; + $sql .= " WHERE sr.objecttype = '".$db->escape(SkillRank::SKILLRANK_TYPE_USER)."'"; + $sql .= ' AND sr.fk_object IN ('.$db->sanitize(implode(',', $TUser)).')'; + $sql .= " GROUP BY sk.rowid, sk.label, sk.description, sk.skill_type, sr.fk_object, sr.objecttype, sr.fk_skill "; // group par competence $resql = $db->query($sql); $Tab = array(); @@ -530,10 +531,10 @@ function getSkillForUsers($TUser) $num = 0; while ($obj = $db->fetch_object($resql)) { $sql1 = "SELECT COUNT(rowid) as how_many_max FROM ".MAIN_DB_PREFIX."hrm_skillrank as sr"; - $sql1.=" WHERE sr.rankorder = ".((int) $obj->rankorder); - $sql1.=" AND sr.objecttype = '".$db->escape(SkillRank::SKILLRANK_TYPE_USER)."'"; - $sql1.=" AND sr.fk_skill = ".((int) $obj->fk_skill); - $sql1.=" AND sr.fk_object IN (".$db->sanitize(implode(',', $TUser)).")"; + $sql1 .= " WHERE sr.rankorder = ".((int) $obj->rankorder); + $sql1 .= " AND sr.objecttype = '".$db->escape(SkillRank::SKILLRANK_TYPE_USER)."'"; + $sql1 .= " AND sr.fk_skill = ".((int) $obj->fk_skill); + $sql1 .= " AND sr.fk_object IN (".$db->sanitize(implode(',', $TUser)).")"; $resql1 = $db->query($sql1); $objMax = $db->fetch_object($resql1); @@ -561,7 +562,7 @@ function getSkillForUsers($TUser) * Allow to get skill(s) of a job * * @param int $fk_job job we need to get required skills - * @return array|int + * @return stdClass[] */ function getSkillForJob($fk_job) { @@ -572,12 +573,12 @@ function getSkillForJob($fk_job) } $sql = 'SELECT sk.rowid, sk.label, sk.description, sk.skill_type, sr.fk_object, sr.objecttype, sr.fk_skill,'; - $sql.= " MAX(sr.rankorder) as rankorder"; - $sql.=' FROM '.MAIN_DB_PREFIX.'hrm_skill as sk'; - $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'hrm_skillrank as sr ON (sk.rowid = sr.fk_skill)'; - $sql.=" WHERE sr.objecttype = '".SkillRank::SKILLRANK_TYPE_JOB."'"; - $sql.=' AND sr.fk_object = '.((int) $fk_job); - $sql.=' GROUP BY sk.rowid, sk.label, sk.description, sk.skill_type, sr.fk_object, sr.objecttype, sr.fk_skill'; // group par competence*/ + $sql .= " MAX(sr.rankorder) as rankorder"; + $sql .= ' FROM '.MAIN_DB_PREFIX.'hrm_skill as sk'; + $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'hrm_skillrank as sr ON (sk.rowid = sr.fk_skill)'; + $sql .= " WHERE sr.objecttype = '".SkillRank::SKILLRANK_TYPE_JOB."'"; + $sql .= ' AND sr.fk_object = '.((int) $fk_job); + $sql .= ' GROUP BY sk.rowid, sk.label, sk.description, sk.skill_type, sr.fk_object, sr.objecttype, sr.fk_skill'; // group par competence*/ $resql = $db->query($sql); $Tab = array(); diff --git a/htdocs/hrm/index.php b/htdocs/hrm/index.php index 0bf7d5c5ff6..6790b12942c 100644 --- a/htdocs/hrm/index.php +++ b/htdocs/hrm/index.php @@ -4,7 +4,7 @@ * Copyright (C) 2012-2014 Regis Houssin * Copyright (C) 2015-2016 Alexandre Spangaro * Copyright (C) 2019 Nicolas ZABOURI - * Copyright (C) 2021 Frédéric France + * Copyright (C) 2021-2024 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -223,8 +223,13 @@ if (isModEnabled('holiday') && $user->hasRight('holiday', 'read')) { print ''.$langs->trans("BoxTitleLastLeaveRequests", min($max, $num)).''; print ''.$langs->trans("from").''; print ''.$langs->trans("to").''; - print ''.$langs->trans("FullList").''; + print ''; + print ''; + print ''; + print img_picto($langs->trans("FullList"), 'holiday'); + print ''; print ''; + if ($num) { while ($i < $num && $i < $max) { $obj = $db->fetch_object($result); @@ -300,11 +305,13 @@ if (isModEnabled('expensereport') && $user->hasRight('expensereport', 'read')) { print ''; print ''.$langs->trans("BoxTitleLastModifiedExpenses", min($max, $num)).''; print ''.$langs->trans("TotalTTC").''; - print ''.$langs->trans("FullList").''; + print ''; + print ''; + print img_picto($langs->trans("FullList"), 'expensereport'); + print ''; print ''; - if ($num) { - $total_ttc = $totalam = $total = 0; + if ($num) { $expensereportstatic = new ExpenseReport($db); $userstatic = new User($db); while ($i < $num && $i < $max) { @@ -320,7 +327,7 @@ if (isModEnabled('expensereport') && $user->hasRight('expensereport', 'read')) { $userstatic->firstname = $obj->firstname; $userstatic->email = $obj->email; $userstatic->login = $obj->login; - $userstatic->statut = $obj->user_status; + $userstatic->status = $obj->user_status; $userstatic->photo = $obj->photo; print ''; @@ -377,7 +384,11 @@ if (isModEnabled('recruitment') && $user->hasRight('recruitment', 'recruitmentjo print ''; print $langs->trans("BoxTitleLatestModifiedCandidatures", min($max, $num)); print ''; - print ''.$langs->trans("FullList").''; + print ''; + print ''; + print img_picto($langs->trans("FullList"), 'recruitmentcandidature'); + //print $langs->trans("FullList"); + print ''; print ''; if ($num) { while ($i < $num) { diff --git a/htdocs/imports/emptyexample.php b/htdocs/imports/emptyexample.php index 6d8b3f2d647..e1ca1e55bbd 100644 --- a/htdocs/imports/emptyexample.php +++ b/htdocs/imports/emptyexample.php @@ -80,13 +80,13 @@ $fieldstarget = $objimport->array_import_fields[0]; $valuestarget = $objimport->array_import_examplevalues[0]; $attachment = true; -if (isset($_GET["attachment"])) { - $attachment = $_GET["attachment"]; +if (GETPOSTISSET("attachment")) { + $attachment = GETPOST("attachment"); } //$attachment = false; $contenttype = dol_mimetype($format); -if (isset($_GET["contenttype"])) { - $contenttype = $_GET["contenttype"]; +if (GETPOSTISSET("contenttype")) { + $contenttype = GETPOST("contenttype"); } //$contenttype='text/plain'; $outputencoding = 'UTF-8'; diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index ba8128b7316..57071a1b17d 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -184,41 +184,6 @@ if (empty($array_match_file_to_database)) { * Actions */ -/* -if ($action=='downfield' || $action=='upfield') -{ - $pos=$array_match_file_to_database[$_GET["field"]]; - if ($action=='downfield') $newpos=$pos+1; - if ($action=='upfield') $newpos=$pos-1; - // Recherche code avec qui switcher - $newcode=""; - foreach($array_match_file_to_database as $code=>$value) - { - if ($value == $newpos) - { - $newcode=$code; - break; - } - } - //print("Switch pos=$pos (code=".$_GET["field"].") and newpos=$newpos (code=$newcode)"); - if ($newcode) // Si newcode trouve (protection contre resoumission de page) - { - $array_match_file_to_database[$_GET["field"]]=$newpos; - $array_match_file_to_database[$newcode]=$pos; - $_SESSION["dol_array_match_file_to_database"]=$serialized_array_match_file_to_database; - } -} -*/ -// if ($action == 'builddoc') { -// // Build import file -// $result = $objimport->build_file($user, GETPOST('model', 'alpha'), $datatoimport, $array_match_file_to_database); -// if ($result < 0) { -// setEventMessages($objimport->error, $objimport->errors, 'errors'); -// } else { -// setEventMessages($langs->trans("FileSuccessfullyBuilt"), null, 'mesgs'); -// } -// } - if ($action == 'deleteprof') { if (GETPOSTINT("id")) { $objimport->fetch(GETPOSTINT("id")); @@ -286,7 +251,7 @@ if ($step == 3 && $datatoimport) { $param .= '&endatlinenb='.urlencode($endatlinenb); } - $file = $conf->import->dir_temp.'/'.GETPOST('urlfile'); // Do not use urldecode here ($_GET and $_REQUEST are already decoded by PHP). + $file = $conf->import->dir_temp.'/'.GETPOST('urlfile'); $ret = dol_delete_file($file); if ($ret) { setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs'); @@ -2085,7 +2050,7 @@ if ($step == 6 && $datatoimport) { $obj->import_close_file(); } - $nboflines = (!empty($_GET["nboflines"]) ? $_GET["nboflines"] : dol_count_nb_of_line($conf->import->dir_temp.'/'.$filetoimport)); + $nboflines = GETPOST("nboflines", dol_count_nb_of_line($conf->import->dir_temp.'/'.$filetoimport)); $param = '&format='.$format.'&datatoimport='.urlencode($datatoimport).'&filetoimport='.urlencode($filetoimport).'&nboflines='.urlencode($nboflines); if ($excludefirstline) { diff --git a/htdocs/index.php b/htdocs/index.php index 6ab07c74f12..1d44347356c 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -32,7 +32,7 @@ require 'main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; // If not defined, we select menu "home" -$_GET['mainmenu'] = GETPOST('mainmenu', 'aZ09') ? GETPOST('mainmenu', 'aZ09') : 'home'; +$_GET['mainmenu'] = GETPOST('mainmenu', 'aZ09') ? GETPOST('mainmenu', 'aZ09') : 'home'; // Keep this ? $action = GETPOST('action', 'aZ09'); $hookmanager->initHooks(array('index')); @@ -48,7 +48,7 @@ if (in_array('export', $conf->modules)) $nbmodulesnotautoenabled--; if (in_array('import', $conf->modules)) $nbmodulesnotautoenabled--; // Check if company name is defined (first install) -if (!isset($conf->global->MAIN_INFO_SOCIETE_NOM) || !getDolGlobalString('MAIN_INFO_SOCIETE_NOM')) { +if (!getDolGlobalString('MAIN_INFO_SOCIETE_NOM') || !getDolGlobalString('MAIN_INFO_SOCIETE_COUNTRY')) { header("Location: ".DOL_URL_ROOT."/admin/index.php?mainmenu=home&leftmenu=setup&mesg=setupnotcomplete"); exit; } diff --git a/htdocs/install/mysql/data/llx_accounting_account_fr.sql b/htdocs/install/mysql/data/llx_accounting_account_fr.sql index f640e8de59b..a4b2a6e5386 100644 --- a/htdocs/install/mysql/data/llx_accounting_account_fr.sql +++ b/htdocs/install/mysql/data/llx_accounting_account_fr.sql @@ -517,6 +517,8 @@ INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, acc INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5971,'PCG14-DEV','FINAN', '5', 0, 'Comptes financiers','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5972,'PCG14-DEV','EXPENSE', '6', 0, 'Comptes de charges','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5973,'PCG14-DEV','INCOME', '7', 0, 'Comptes de produits','1'); +-- Rowid 5974 ajouté en erratum, ajout de "697 - Imposition forfaitaire annuelle des sociétés" (absent de la liste dans PCG officiel, mais présent dans articles +-- Rowid 5975 à 5977, ajouts pour les codes 4421 (pour le prélèvement à la source de l'impot sur le revenu), 4422 et 4423 INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5000,'PCG14-DEV','CAPIT', '10',5967,'Capital et réserves','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5001,'PCG14-DEV','CAPIT', '101',5000,'Capital','1'); @@ -623,7 +625,7 @@ INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, acc INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5102,'PCG14-DEV','CAPIT', '1655',5100,'Cautionnements','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5103,'PCG14-DEV','CAPIT', '166',5095,'Participation des salariés aux résultats','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5104,'PCG14-DEV','CAPIT', '1661',5103,'Comptes bloqués','1'); -INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5105,'PCG14-DEV','CAPIT', '1662',5013,'Fonds de participation','1'); +INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5105,'PCG14-DEV','CAPIT', '1662',5103,'Fonds de participation','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5106,'PCG14-DEV','CAPIT', '167',5095,'Emprunts et dettes assortis de conditions particulières','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5107,'PCG14-DEV','CAPIT', '1671',5106,'Emissions de titres participatifs','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5108,'PCG14-DEV','CAPIT', '1674',5106,'Avances conditionnées de l''Etat','1'); @@ -635,7 +637,7 @@ INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, acc INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5114,'PCG14-DEV','CAPIT', '1688',5110,'Intérêts courus','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5115,'PCG14-DEV','CAPIT','16881',5114,'sur emprunts obligataires convertibles','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5116,'PCG14-DEV','CAPIT','16883',5114,'sur autres emprunts obligataires','1'); -INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5117,'PCG14-DEV','CAPIT','16684',5114,'sur emprunts auprès des établissements de crédit','1'); +INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5117,'PCG14-DEV','CAPIT','16884',5114,'sur emprunts auprès des établissements de crédit','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5118,'PCG14-DEV','CAPIT','16885',5114,'sur dépôts et cautionnements reçus','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5119,'PCG14-DEV','CAPIT','16886',5114,'sur participation des salariés aux résultats','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5120,'PCG14-DEV','CAPIT','16887',5114,'sur emprunts et dettes assortis de conditions particulières','1'); @@ -851,16 +853,16 @@ INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, acc INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5330,'PCG14-DEV','STOCK','3511',5329,'Produits intermédiaires (ou groupe) A','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5331,'PCG14-DEV','STOCK','3512',5329,'Produits intermédiaires (ou groupe) B','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5332,'PCG14-DEV','STOCK','355',5328,'Produits finis','1'); -INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5333,'PCG14-DEV','STOCK','3551',5333,'Produits finis (ou groupe) A','1'); -INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5334,'PCG14-DEV','STOCK','3552',5333,'Produits finis (ou groupe) B','1'); +INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5333,'PCG14-DEV','STOCK','3551',5332,'Produits finis (ou groupe) A','1'); +INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5334,'PCG14-DEV','STOCK','3552',5332,'Produits finis (ou groupe) B','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5335,'PCG14-DEV','STOCK','358',5328,'Produits résiduels (ou matières de récupération)','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5336,'PCG14-DEV','STOCK','3581',5335,'Déchets','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5337,'PCG14-DEV','STOCK','3585',5335,'Rebuts','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5338,'PCG14-DEV','STOCK','3586',5335,'Matières de récupération','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5339,'PCG14-DEV','STOCK','36',5969,'(compte à ouvrir, le cas échéant, sous l''intitulé ''Stocks provenant d''immobilisations'')','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5340,'PCG14-DEV','STOCK','37',5969,'Stocks de marchandises','1'); -INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5341,'PCG14-DEV','STOCK','371',5341,'Marchandises (ou groupe) A','1'); -INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5342,'PCG14-DEV','STOCK','372',5341,'Marchandises (ou groupe) B','1'); +INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5341,'PCG14-DEV','STOCK','371',5340,'Marchandises (ou groupe) A','1'); +INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5342,'PCG14-DEV','STOCK','372',5340,'Marchandises (ou groupe) B','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5343,'PCG14-DEV','STOCK','38',5969,'(lorsque l''entité tient un inventaire permanent en comptabilité générale, le compte 38 peut être utilisé pour comptabiliser les stocks en voie d''acheminement, mis en dépôt ou donnés en consignation)','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5344,'PCG14-DEV','STOCK','39',5969,'Dépréciations des stocks et en-cours','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5345,'PCG14-DEV','STOCK','391',5344,'Dépréciations des matières premières (et fournitures)','1'); @@ -947,6 +949,9 @@ INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, acc INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5426,'PCG14-DEV','THIRDPARTY','4418',5423,'Subventions d''équilibre','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5427,'PCG14-DEV','THIRDPARTY','4419',5423,'Avances sur subventions','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5428,'PCG14-DEV','THIRDPARTY','442',5422,'Etat - Impôts et taxes recouvrables sur des tiers','1'); +INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5975,'PCG14-DEV','THIRDPARTY','4421',5428,'Prélèvements à la source (Impôt sur le revenu)','1'); +INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5976,'PCG14-DEV','THIRDPARTY','4422',5428,'Prélèvements forfaitaires non libératoires','1'); +INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5977,'PCG14-DEV','THIRDPARTY','4423',5428,'Retenues et prélèvements sur les distributions','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5429,'PCG14-DEV','THIRDPARTY','4424',5428,'Obligataires','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5430,'PCG14-DEV','THIRDPARTY','4425',5428,'Associés','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5431,'PCG14-DEV','THIRDPARTY','443',5422,'Opérations particulières avec l''Etat les collectivités publiques, les organismes internationaux','1'); @@ -1042,7 +1047,7 @@ INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, acc INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5521,'PCG14-DEV','THIRDPARTY','4962',5520,'Créances sur cessions d''immobilisations','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5522,'PCG14-DEV','THIRDPARTY','4965',5520,'Créances sur cessions de valeurs mobilières de placement','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5523,'PCG14-DEV','THIRDPARTY','4967',5520,'Autres comptes débiteurs','1'); -INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5524,'PCG14-DEV','FINAN','50',5524,'Parts dans des entreprises liées','1'); +INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5524,'PCG14-DEV','FINAN','501',5971,'Parts dans des entreprises liées','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5526,'PCG14-DEV','FINAN','502',5524,'Actions propres','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5527,'PCG14-DEV','FINAN','5021',5526,'Actons destinées à être attribuées aux employés et affectées à des plans déterminés','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5528,'PCG14-DEV','FINAN','5022',5526,'Actons disponibles pour être attribuées aux employés ou pour la régularisation des cours de bourse','1'); @@ -1101,7 +1106,7 @@ INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, acc INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5581,'PCG14-DEV','EXPENSE','6012',5579,'Matières (ou groupe) B','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5582,'PCG14-DEV','EXPENSE','6017',5579,'Fournitures A, B, C,','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5583,'PCG14-DEV','EXPENSE','602',5578,'Achats stockés - Autres approvisionnements','1'); -INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5584,'PCG14-DEV','EXPENSE','6201',5583,'Matières consommables','1'); +INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5584,'PCG14-DEV','EXPENSE','6021',5583,'Matières consommables','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5585,'PCG14-DEV','EXPENSE','60211',5584,'Matières (ou groupe) C','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5586,'PCG14-DEV','EXPENSE','60212',5584,'Matières (ou groupe) D','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5587,'PCG14-DEV','EXPENSE','6022',5583,'Fournitures consommables','1'); @@ -1122,8 +1127,8 @@ INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, acc INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5602,'PCG14-DEV','EXPENSE','6064',5599,'Fournitures administratives','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5603,'PCG14-DEV','EXPENSE','6068',5599,'Autres matières et fournitures','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5604,'PCG14-DEV','EXPENSE','607',5578,'Achats de marchandises','1'); -INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5605,'PCG14-DEV','EXPENSE','6071',5605,'Marchandise (ou groupe) A','1'); -INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5606,'PCG14-DEV','EXPENSE','6072',5605,'Marchandise (ou groupe) B','1'); +INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5605,'PCG14-DEV','EXPENSE','6071',5604,'Marchandise (ou groupe) A','1'); +INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5606,'PCG14-DEV','EXPENSE','6072',5604,'Marchandise (ou groupe) B','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5607,'PCG14-DEV','EXPENSE','608',5578,'(Compte réservé, le cas échéant, à la récapitulation des frais accessoires incorporés aux achats)','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5608,'PCG14-DEV','EXPENSE','609',5578,'Rabais, remises et ristournes obtenus sur achats','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5609,'PCG14-DEV','EXPENSE','6091',5608,'de matières premières (et fournitures)','1'); @@ -1133,7 +1138,7 @@ INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, acc INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5613,'PCG14-DEV','EXPENSE','6096',5608,'d''approvisionnements non stockés','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5614,'PCG14-DEV','EXPENSE','6097',5608,'de marchandises','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5615,'PCG14-DEV','EXPENSE','6098',5608,'Rabais, remises et ristournes non affectés','1'); -INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5616,'PCG14-DEV','EXPENSE','603',5578,'Variations des stocks (approvisionnements et marchandises)','1'); +INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5616,'PCG14-DEV','EXPENSE','603',5972,'Variations des stocks (approvisionnements et marchandises)','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5617,'PCG14-DEV','EXPENSE','6031',5616,'Variation des stocks de matières premières (et fournitures)','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5618,'PCG14-DEV','EXPENSE','6032',5616,'Variation des stocks des autres approvisionnements','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5619,'PCG14-DEV','EXPENSE','6037',5616,'Variation des stocks de marchandises','1'); @@ -1350,6 +1355,7 @@ INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, acc INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5830,'PCG14-DEV','EXPENSE','6952',5828,'Contribution additionnelle à l''impôt sur les bénéfices','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5831,'PCG14-DEV','EXPENSE','6954',5828,'Impôts dus à l''étranger','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5832,'PCG14-DEV','EXPENSE','696',5826,'Suppléments d''impôt sur les sociétés liés aux distributions','1'); +INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5974,'PCG14-DEV','EXPENSE','697',5826,'Imposition forfaitaire annuelle des sociétés','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5833,'PCG14-DEV','EXPENSE','698',5826,'Intégration fiscale','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5834,'PCG14-DEV','EXPENSE','6981',5833,'Intégration fiscale - Charges','1'); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 5835,'PCG14-DEV','EXPENSE','6989',5833,'Intégration fiscale - Produits','1'); diff --git a/htdocs/install/mysql/data/llx_c_action_trigger.sql b/htdocs/install/mysql/data/llx_c_action_trigger.sql index 5ed3730adc1..eeda692ce9f 100644 --- a/htdocs/install/mysql/data/llx_c_action_trigger.sql +++ b/htdocs/install/mysql/data/llx_c_action_trigger.sql @@ -192,11 +192,9 @@ insert into llx_c_action_trigger (code,label,description,elementtype,rang) value insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILLREC_CREATE','Template invoices created','Executed when a Template invoices is created','facturerec',900); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILLREC_MODIFY','Template invoices update','Executed when a Template invoices is updated','facturerec',901); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILLREC_DELETE','Template invoices deleted','Executed when a Template invoices is deleted','facturerec',902); ---insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILLREC_AUTOCREATEBILL','Template invoices use to create invoices with auto batch','Executed when a Template invoices is use to create invoice with auto batch','facturerec',903); -- partnership module insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PARTNERSHIP_CREATE','Partnership created','Executed when a partnership is created','partnership',58000); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PARTNERSHIP_MODIFY','Partnership modified','Executed when a partnership is modified','partnership',58002); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PARTNERSHIP_SENTBYMAIL','Mails sent from partnership file','Executed when you send email from partnership file','partnership',58004); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PARTNERSHIP_DELETE','Partnership deleted','Executed when a partnership is deleted','partnership',58006); - diff --git a/htdocs/install/mysql/migration/19.0.0-20.0.0.sql b/htdocs/install/mysql/migration/19.0.0-20.0.0.sql index a99b9731232..f682187eb03 100644 --- a/htdocs/install/mysql/migration/19.0.0-20.0.0.sql +++ b/htdocs/install/mysql/migration/19.0.0-20.0.0.sql @@ -288,3 +288,7 @@ ALTER TABLE llx_expeditiondet ADD COLUMN element_type varchar(50) DEFAULT 'order ALTER TABLE llx_receptiondet_batch CHANGE COLUMN fk_commande fk_element integer; ALTER TABLE llx_receptiondet_batch CHANGE COLUMN fk_commandefourndet fk_elementdet integer; + +ALTER TABLE llx_supplier_proposaldet MODIFY ref_fourn VARCHAR(128) NULL; + +ALTER TABLE llx_projet ADD COLUMN ref_ext varchar(50) after ref; diff --git a/htdocs/install/mysql/tables/llx_projet.sql b/htdocs/install/mysql/tables/llx_projet.sql index 8b4db824ca5..3c71ab719e6 100644 --- a/htdocs/install/mysql/tables/llx_projet.sql +++ b/htdocs/install/mysql/tables/llx_projet.sql @@ -26,7 +26,8 @@ create table llx_projet tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, dateo date, -- date start project datee date, -- date end project - ref varchar(50), + ref varchar(50), -- reference number + ref_ext varchar(50), -- reference into an external system (not used by dolibarr) entity integer DEFAULT 1 NOT NULL, -- multi company id title varchar(255) NOT NULL, description text, @@ -37,7 +38,7 @@ create table llx_projet fk_opp_status integer DEFAULT NULL, -- if project is used to manage opportunities opp_percent double(5,2), fk_opp_status_end integer DEFAULT NULL, -- if project is used to manage opportunities (the opportunity status the project has when set to lose) - date_close datetime DEFAULT NULL, + date_close datetime DEFAULT NULL, fk_user_close integer DEFAULT NULL, note_private text, note_public text, diff --git a/htdocs/install/mysql/tables/llx_supplier_proposaldet.sql b/htdocs/install/mysql/tables/llx_supplier_proposaldet.sql index bbf3decd7fa..2e61c58cc18 100644 --- a/htdocs/install/mysql/tables/llx_supplier_proposaldet.sql +++ b/htdocs/install/mysql/tables/llx_supplier_proposaldet.sql @@ -47,7 +47,7 @@ CREATE TABLE llx_supplier_proposaldet ( fk_product_fournisseur_price integer DEFAULT NULL, special_code integer DEFAULT 0, rang integer DEFAULT 0, - ref_fourn varchar(30) DEFAULT NULL, + ref_fourn varchar(128) DEFAULT NULL, fk_multicurrency integer, multicurrency_code varchar(3), multicurrency_subprice double(24,8) DEFAULT 0, diff --git a/htdocs/install/step4.php b/htdocs/install/step4.php index 7d7d3133e53..c93f4c815e1 100644 --- a/htdocs/install/step4.php +++ b/htdocs/install/step4.php @@ -87,13 +87,13 @@ if ($db->ok) { print ''; print ''; - if (isset($_GET["error"]) && $_GET["error"] == 1) { + if (GETPOSTINT("error") == 1) { print '
      '; print '
      '.$langs->trans("PasswordsMismatch").'
      '; $error = 0; // We show button } - if (isset($_GET["error"]) && $_GET["error"] == 2) { + if (GETPOSTINT("error") == 2) { print '
      '; print '
      '; print $langs->trans("PleaseTypePassword"); @@ -101,7 +101,7 @@ if ($db->ok) { $error = 0; // We show button } - if (isset($_GET["error"]) && $_GET["error"] == 3) { + if (GETPOSTINT("error") == 3) { print '
      '; print '
      '.$langs->trans("PleaseTypeALogin").'
      '; $error = 0; // We show button diff --git a/htdocs/install/upgrade.php b/htdocs/install/upgrade.php index d80205028c8..67b22abf07d 100644 --- a/htdocs/install/upgrade.php +++ b/htdocs/install/upgrade.php @@ -418,9 +418,9 @@ if (!$ok && isset($argv[1])) { } dolibarr_install_syslog("Exit ".$ret); -dolibarr_install_syslog("--- upgrade: end ".((int) (!$ok && empty($_GET["ignoreerrors"])))." dirmodule=".$dirmodule); +dolibarr_install_syslog("--- upgrade: end ".((int) (!$ok && !GETPOST("ignoreerrors")))." dirmodule=".$dirmodule); -$nonext = (!$ok && empty($_GET["ignoreerrors"])) ? 2 : 0; +$nonext = (!$ok && !GETPOST("ignoreerrors")) ? 2 : 0; if ($dirmodule) { $nonext = 1; } diff --git a/htdocs/intracommreport/card.php b/htdocs/intracommreport/card.php index 7adc9ea0eb7..8557b019fa6 100644 --- a/htdocs/intracommreport/card.php +++ b/htdocs/intracommreport/card.php @@ -1,6 +1,7 @@ * Copyright (C) 2019-2020 Open-DSI + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -234,7 +235,7 @@ if ($id > 0 && $action != 'edit') { */ //$head = intracommreport_prepare_head($object); - print dol_get_fiche_head("", 'general', $langs->trans("IntracommReport"), -1, 'user'); + print dol_get_fiche_head(array(), 'general', $langs->trans("IntracommReport"), -1, 'user'); // Confirm remove report if ($action == 'delete') { diff --git a/htdocs/knowledgemanagement/class/api_knowledgemanagement.class.php b/htdocs/knowledgemanagement/class/api_knowledgemanagement.class.php index 8bb3e044889..0a01ba6b471 100644 --- a/htdocs/knowledgemanagement/class/api_knowledgemanagement.class.php +++ b/htdocs/knowledgemanagement/class/api_knowledgemanagement.class.php @@ -238,7 +238,7 @@ class KnowledgeManagement extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->knowledgerecord->context['caller'] = $request_data['caller']; + $this->knowledgerecord->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } @@ -286,7 +286,7 @@ class KnowledgeManagement extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->knowledgerecord->context['caller'] = $request_data['caller']; + $this->knowledgerecord->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index c91dfd164bc..851690956a4 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -372,7 +372,7 @@ DateValidationAndLock=Date validation and lock ConfirmExportFile=Confirmation of the generation of the accounting export file ? ExportDraftJournal=Export draft journal Modelcsv=Model of export -Selectmodelcsv=Select a model of export +Selectmodelcsv=Select the default format for export Modelcsv_normal=Classic export Modelcsv_CEGID=Export for CEGID Expert Comptabilité Modelcsv_COALA=Export for Sage Coala diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 90077daa51b..a9d4bde40ae 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -89,7 +89,7 @@ NotAvailableWhenAjaxDisabled=Not available when Ajax disabled AllowToSelectProjectFromOtherCompany=On document of a third party, can choose a project linked to another third party TimesheetPreventAfterFollowingMonths=Prevent recording time spent after the following number of months PROJECT_DISPLAY_LINKED_BY_CONTACT=Display project linked by a common contact -PROJECT_DISPLAY_LINKED_BY_CONTACT_help=That option add a new list on Project tab with all projects linked to that thirdparty via a contact relationship +PROJECT_DISPLAY_LINKED_BY_CONTACT_help=This option adds a new list on Project tab with all projects linked to thirdparty via a contact relationship JavascriptDisabled=JavaScript disabled UsePreviewTabs=Use preview tabs ShowPreview=Show preview diff --git a/htdocs/langs/en_US/cashdesk.lang b/htdocs/langs/en_US/cashdesk.lang index ff42af8c3fb..3baf275ab15 100644 --- a/htdocs/langs/en_US/cashdesk.lang +++ b/htdocs/langs/en_US/cashdesk.lang @@ -106,7 +106,7 @@ ControlCashOpening=Open the "Control cash box" popup when opening the POS CloseCashFence=Close cash box control CashReport=Cash report MainPrinterToUse=Main printer to use -MainPrinterToUseMore=empty means the browser printer system +MainPrinterToUseMore=leave empty to use the browser printer system OrderPrinterToUse=Order printer to use MainTemplateToUse=Main template to use MainTemplateToUseMore=when not using browser printing system diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang index d1ca72b826a..3d641dfb8fa 100644 --- a/htdocs/langs/en_US/companies.lang +++ b/htdocs/langs/en_US/companies.lang @@ -273,6 +273,11 @@ EditContact=Edit contact EditContactAddress=Edit contact/address Contact=Contact/Address Contacts=Contacts/Addresses +ContactNotes=Notes +ContactPersonalData=Personal data +ContactRelatedItems=Related items +ContactLinkedFiles=Linked files +ContactEvents=Events/Agenda ContactId=Contact id ContactsAddresses=Contacts/Addresses FromContactName=Name: @@ -383,7 +388,8 @@ SupplierCategory=Vendor category JuridicalStatus200=Independent DeleteFile=Delete file ConfirmDeleteFile=Are you sure you want to delete this file %s? -AllocateCommercial=Assigned to sales representative +AllocateCommercial=Assign to sales representatives +UnallocateCommercial=Unassigned sales representatives Organization=Organization FiscalYearInformation=Fiscal Year FiscalMonthStart=Starting month of the fiscal year @@ -400,7 +406,8 @@ ListSuppliersShort=List of Vendors ListProspectsShort=List of Prospects ListCustomersShort=List of Customers ThirdPartiesArea=Third Parties/Contacts -LastModifiedThirdParties=Latest %s Third Parties which were modified +LastModifiedThirdParties=The latest %s modified Third Parties +LastModifiedContacts=The latest %s modified contacts UniqueThirdParties=Total number of Third Parties InActivity=Open ActivityCeased=Closed diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 0c5881caf05..dec04d18cd5 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -416,4 +416,4 @@ ThisIdNotDefined=Id not defined OperNotDefined=Payment method not defined ErrorThisContactXIsAlreadyDefinedAsThisType=%s is already defined as contact for this type. ErrorThisGroupIsAlreadyDefinedAsThisType=The contacts with this group are already defined as contact for this type. -EmptyMessageNotAllowedError=Empty Message Not Allowed Error +EmptyMessageNotAllowedError=Empty message is not allowed diff --git a/htdocs/langs/en_US/help.lang b/htdocs/langs/en_US/help.lang index 88a1b006591..eafea7c0281 100644 --- a/htdocs/langs/en_US/help.lang +++ b/htdocs/langs/en_US/help.lang @@ -21,4 +21,4 @@ LinkToGoldMember=You can call one of the trainers preselected by Dolibarr for yo PossibleLanguages=Supported languages SubscribeToFoundation=Help the Dolibarr project, subscribe to the foundation SeeOfficalSupport=For official Dolibarr support in your language:
      %s -AIProcessingPleaseWait=AI interrogation in progress, please wait... \ No newline at end of file +AIProcessingPleaseWait=AI is processing your request, please wait... diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 73ebf6faa54..24e96d2a6a1 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -705,7 +705,6 @@ CloseWindow=Close window Response=Response Priority=Priority SendByMail=Send by email -MailSentBy=Email sent by MailSentByTo=Email sent by %s to %s NotSent=Not sent TextUsedInTheMessageBody=Email body @@ -1222,9 +1221,13 @@ Terminated=Terminated Position=Position AddLineOnPosition=Add line on position (at the end if empty) ConfirmAllocateCommercial=Assign sales representative confirmation +ConfirmUnallocateCommercial=Are you sure you want to unassign the sales representative(s) from all selected thirdparties? ConfirmAllocateCommercialQuestion=Are you sure you want to assign the %s selected record(s)? +ConfirmUnallocateCommercialQuestion=Are you sure you want to unassign the selected %s record(s)? CommercialsAffected=Sales representatives assigned CommercialAffected=Sales representative assigned +CommercialsDisaffected=Sales representatives disassigned +CommercialDisaffected=Sales representative disassigned YourMessage=Your message YourMessageHasBeenReceived=Your message has been received. We will answer or contact you as soon as possible. UrlToCheck=Url to check diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang index 12955cc9f0e..41a8ac3985d 100644 --- a/htdocs/langs/en_US/other.lang +++ b/htdocs/langs/en_US/other.lang @@ -42,6 +42,7 @@ notiftouserandtofixedemail=To user and fixed mail Notify_ORDER_VALIDATE=Sales order validated Notify_ORDER_SENTBYMAIL=Sales order sent by mail Notify_ORDER_CLOSE=Sales order delivered +Notify_ORDER_CANCEL=Sales order canceled Notify_ORDER_SUPPLIER_SENTBYMAIL=Purchase order sent by email Notify_ORDER_SUPPLIER_VALIDATE=Purchase order recorded Notify_ORDER_SUPPLIER_APPROVE=Purchase order approved diff --git a/htdocs/langs/en_US/salaries.lang b/htdocs/langs/en_US/salaries.lang index 2f6ad0a56be..adf8ed60dff 100644 --- a/htdocs/langs/en_US/salaries.lang +++ b/htdocs/langs/en_US/salaries.lang @@ -1,6 +1,6 @@ # Dolibarr language file - Source file is en_US - salaries SALARIES_ACCOUNTING_ACCOUNT_PAYMENT=Account (from the Chart of Account) used by default for "users" on salaries -SALARIES_ACCOUNTING_ACCOUNT_PAYMENT_Desc=The dedicated account defined on the user card will be used for Subledger accounting only. This one will be used for General Ledger, bt also as the default value of Subledger accounting if no dedicated user accounting account is defined on the user. +SALARIES_ACCOUNTING_ACCOUNT_PAYMENT_Desc=The dedicated account defined on the user card will be used for Subledger accounting only. This one will be used for General Ledger, but also as the default value of Subledger accounting if no dedicated user accounting account is defined on the user. SALARIES_ACCOUNTING_ACCOUNT_CHARGE=Accounting account by default for wage payments CREATE_NEW_SALARY_WITHOUT_AUTO_PAYMENT=By default, leave empty the option "Automatically create a total payment" when creating a Salary Salary=Salary diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index 7740eb8d647..c7e32d9d706 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -332,5 +332,6 @@ ConfirmDeleteBatch=Are you sure you want to delete lot/serial ? WarehouseUsage=Warehouse usage InternalWarehouse=Internal warehouse ExternalWarehouse=External warehouse -QtyCurrentlyKnownInStock=The quantity the system think you have in stock. As long as the inventory is not closed, this is a realtime value and it may change if you continue to make stock movement during the inventory (not recommended). -QtyInStockWhenInventoryWasValidated=The quantity the system think you had in stock when the inventory was validated (before the stock correction) +LatestModifiedWarehouses=Latest %s modified warehouses +QtyCurrentlyKnownInStock=System estimated quantity you have in stock. As long as the inventory is not closed, this is a realtime value and it may change if you continue to make stock movement during the inventory (not recommended). +QtyInStockWhenInventoryWasValidated=System estimated quantity you had in stock when the inventory was validated (before the stock correction) diff --git a/htdocs/langs/en_US/stripe.lang b/htdocs/langs/en_US/stripe.lang index 239c1cf0345..ac750a737fe 100644 --- a/htdocs/langs/en_US/stripe.lang +++ b/htdocs/langs/en_US/stripe.lang @@ -77,4 +77,13 @@ TERMINAL_LOCATION=Location (address) for Stripe Terminals RequestDirectDebitWithStripe=Request Direct Debit with Stripe RequesCreditTransferWithStripe=Request Credit Transfer with Stripe STRIPE_SEPA_DIRECT_DEBIT=Enable the Direct Debit payments through Stripe -StripeConnect_Mode=Stripe Connect mode \ No newline at end of file +STRIPE_KLARNA=Enable the payments using Klarna +STRIPE_BANCONTACT=Enable the payments using BANCONTACT +STRIPE_IDEAL=Enable the payments using IDEAL +STRIPE_GIROPAY=Enable the payments using GIROPAY +STRIPE_SOFORT=Enable the payments using SOFORT +StripeConnect_Mode=Stripe Connect mode +ExampleOnlyForBECustomers=Only for belgium customers +ExampleOnlyForDECustomers=Only for german customers +ExampleOnlyForNLCustomers=Only for dutch customers +ExampleOnlyForATBEDEITNLESCustomers=Only for customers from Austria, Belgium, Germany, Italy, Netherlands, Spain diff --git a/htdocs/langs/en_US/website.lang b/htdocs/langs/en_US/website.lang index a1543ba61f5..5676ed45400 100644 --- a/htdocs/langs/en_US/website.lang +++ b/htdocs/langs/en_US/website.lang @@ -162,7 +162,7 @@ AssignedContacts=Assigned contacts WebsiteTypeLabel=Type of Web site WebsiteTypeDolibarrWebsite=Web site (Module WebSites CMS) WebsiteTypeDolibarrPortal=Native and ready to use web portal (Module Web Portal) -WebPortalURL=Web portal URL +WebPortalURL=Web portal URL NewWebsiteAccount=New accounts for websites ModuleWebPortalName=Web portal ModuleWebPortalDesc=A ready to use native web portal for customers, suppliers, partners or members @@ -235,4 +235,5 @@ WebPortalPartnership=Partnership WebPortalPropal=Proposal WebPortalGroupMenuAdmin=Administration WebPortalGroupMenuTechnical=System -PreviewPageContent=Page content +PreviewPageContent=Page content +Cart=Cart diff --git a/htdocs/langs/fr_FR/website.lang b/htdocs/langs/fr_FR/website.lang index 5dc984ebce6..6771817e37e 100644 --- a/htdocs/langs/fr_FR/website.lang +++ b/htdocs/langs/fr_FR/website.lang @@ -235,3 +235,4 @@ WebPortalPartnership=Partenariat WebPortalPropal=Proposition WebPortalGroupMenuAdmin=Administration WebPortalGroupMenuTechnical=Système +Cart=Panier diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 5a1f7684755..910720b56f2 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -220,10 +220,10 @@ function testSqlAndScriptInject($val, $type) /** * Return true if security check on parameters are OK, false otherwise. * - * @param string|array $var Variable name - * @param int $type 1=GET, 0=POST, 2=PHP_SELF - * @param int $stopcode 0=No stop code, 1=Stop code (default) if injection found - * @return boolean|null True if there is no injection. + * @param string|array $var Variable name + * @param int<0,2> $type 1=GET, 0=POST, 2=PHP_SELF + * @param int<0,1> $stopcode 0=No stop code, 1=Stop code (default) if injection found + * @return boolean True if there is no injection. */ function analyseVarsForSqlAndScriptsInjection(&$var, $type, $stopcode = 1) { @@ -327,15 +327,15 @@ require_once 'filefunc.inc.php'; // If there is a POST parameter to tell to save automatically some POST parameters into cookies, we do it. // This is used for example by form of boxes to save personalization of some options. // DOL_AUTOSET_COOKIE=cookiename:val1,val2 and cookiename_val1=aaa cookiename_val2=bbb will set cookie_name with value json_encode(array('val1'=> , )) -if (!empty($_POST["DOL_AUTOSET_COOKIE"])) { - $tmpautoset = explode(':', $_POST["DOL_AUTOSET_COOKIE"], 2); +if (GETPOST("DOL_AUTOSET_COOKIE")) { + $tmpautoset = explode(':', GETPOST("DOL_AUTOSET_COOKIE"), 2); $tmplist = explode(',', $tmpautoset[1]); $cookiearrayvalue = array(); foreach ($tmplist as $tmpkey) { $postkey = $tmpautoset[0].'_'.$tmpkey; - //var_dump('tmpkey='.$tmpkey.' postkey='.$postkey.' value='.$_POST[$postkey]); - if (!empty($_POST[$postkey])) { - $cookiearrayvalue[$tmpkey] = $_POST[$postkey]; + //var_dump('tmpkey='.$tmpkey.' postkey='.$postkey.' value='.GETPOST($postkey); + if (GETPOST($postkey)) { + $cookiearrayvalue[$tmpkey] = GETPOST($postkey); } } $cookiename = $tmpautoset[0]; @@ -764,7 +764,6 @@ if (!defined('NOLOGIN')) { $dol_optimize_smallscreen = GETPOSTINT('dol_optimize_smallscreen', 3); $dol_no_mouse_hover = GETPOSTINT('dol_no_mouse_hover', 3); $dol_use_jmobile = GETPOSTINT('dol_use_jmobile', 3); // 0=default, 1=to say we use app from a webview app, 2=to say we use app from a webview app and keep ajax - //dol_syslog("POST key=".join(array_keys($_POST),',').' value='.join($_POST,',')); // If in demo mode, we check we go to home page through the public/demo/index.php page if (!empty($dolibarr_main_demo) && $_SERVER['PHP_SELF'] == DOL_URL_ROOT.'/index.php') { // We ask index page @@ -1600,8 +1599,8 @@ if (!function_exists("llxHeader")) { /** * Show HTTP header. Called by top_htmlhead(). * - * @param string $contenttype Content type. For example, 'text/html' - * @param int $forcenocache Force disabling of cache for the page + * @param string $contenttype Content type. For example, 'text/html' + * @param int<0,1> $forcenocache Force disabling of cache for the page * @return void */ function top_httphead($contenttype = 'text/html', $forcenocache = 0) @@ -1731,15 +1730,15 @@ function top_httphead($contenttype = 'text/html', $forcenocache = 0) * Output html header of a page. It calls also top_httphead() * This code is also duplicated into security2.lib.php::dol_loginfunction * - * @param string $head Optional head lines - * @param string $title HTML title - * @param int $disablejs Disable js output - * @param int $disablehead Disable head output - * @param array $arrayofjs Array of complementary js files - * @param array $arrayofcss Array of complementary css files - * @param int $disableforlogin Do not load heavy js and css for login pages - * @param int $disablenofollow Disable nofollow tag for meta robots - * @param int $disablenoindex Disable noindex tag for meta robots + * @param string $head Optional head lines + * @param string $title HTML title + * @param int<0,1> $disablejs Disable js output + * @param int<0,1> $disablehead Disable head output + * @param string[] $arrayofjs Array of complementary js files + * @param string[] $arrayofcss Array of complementary css files + * @param int<0,1> $disableforlogin Do not load heavy js and css for login pages + * @param int<0,1> $disablenofollow Disable nofollow tag for meta robots + * @param int<0,1> $disablenoindex Disable noindex tag for meta robots * @return void */ function top_htmlhead($head, $title = '', $disablejs = 0, $disablehead = 0, $arrayofjs = array(), $arrayofcss = array(), $disableforlogin = 0, $disablenofollow = 0, $disablenoindex = 0) @@ -2147,10 +2146,10 @@ function top_htmlhead($head, $title = '', $disablejs = 0, $disablehead = 0, $arr * @param string $head Lines in the HEAD * @param string $title Title of web page * @param string $target Target to use in menu links (Example: '' or '_top') - * @param int $disablejs Do not output links to js (Ex: qd fonction utilisee par sous formulaire Ajax) - * @param int $disablehead Do not output head section - * @param array $arrayofjs Array of js files to add in header - * @param array $arrayofcss Array of css files to add in header + * @param int<0,1> $disablejs Do not output links to js (Ex: qd fonction utilisee par sous formulaire Ajax) + * @param int<0,1> $disablehead Do not output head section + * @param string[] $arrayofjs Array of js files to add in header + * @param string[] $arrayofcss Array of css files to add in header * @param string $morequerystring Query string to add to the link "print" to get same parameters (use only if autodetect fails) * @param string $helppagename Name of wiki page for help ('' by default). * Syntax is: For a wiki page: EN:EnglishPage|FR:FrenchPage|ES:SpanishPage|DE:GermanPage @@ -2413,7 +2412,7 @@ function top_menu($head, $title = '', $target = '', $disablejs = 0, $disablehead /** * Build the tooltip on user login * - * @param int $hideloginname Hide login name. Show only the image. + * @param int<0,1> $hideloginname Hide login name. Show only the image. * @param string $urllogout URL for logout (Will use DOL_URL_ROOT.'/user/logout.php?token=...' if empty) * @return string HTML content */ @@ -2697,12 +2696,16 @@ function top_menu_quickadd() // accesskey is for Windows or Linux: ALT + key for chrome, ALT + SHIFT + KEY for firefox // accesskey is for Mac: CTRL + key for all browsers $stringforfirstkey = $langs->trans("KeyboardShortcut"); - if ($conf->browser->name == 'chrome') { - $stringforfirstkey .= ' ALT +'; - } elseif ($conf->browser->name == 'firefox') { - $stringforfirstkey .= ' ALT + SHIFT +'; - } else { + if ($conf->browser->os === 'macintosh') { $stringforfirstkey .= ' CTL +'; + } else { + if ($conf->browser->name == 'chrome') { + $stringforfirstkey .= ' ALT +'; + } elseif ($conf->browser->name == 'firefox') { + $stringforfirstkey .= ' ALT + SHIFT +'; + } else { + $stringforfirstkey .= ' CTL +'; + } } $html .= ' @@ -2728,10 +2731,18 @@ function top_menu_quickadd() // Key map shortcut $(document).keydown(function(event){ - if ( event.which === 76 && event.ctrlKey && event.shiftKey ){ - console.log(\'control + shift + l : trigger open quick add dropdown\'); - openQuickAddDropDown(event); - } + var ostype = "'.$conf->browser->os.'"; + if (ostype === "macintosh") { + if ( event.which === 65 && event.ctrlKey ) { + console.log(\'control + a : trigger open quick add dropdown\'); + openQuickAddDropDown(event); + } + } else { + if ( event.which === 65 && event.ctrlKey && event.shiftKey ) { + console.log(\'control + shift + a : trigger open quick add dropdown\'); + openQuickAddDropDown(event); + } + } }); var openQuickAddDropDown = function(event) { @@ -2944,12 +2955,16 @@ function top_menu_bookmark() // accesskey is for Windows or Linux: ALT + key for chrome, ALT + SHIFT + KEY for firefox // accesskey is for Mac: CTRL + key for all browsers $stringforfirstkey = $langs->trans("KeyboardShortcut"); - if ($conf->browser->name == 'chrome') { - $stringforfirstkey .= ' ALT +'; - } elseif ($conf->browser->name == 'firefox') { - $stringforfirstkey .= ' ALT + SHIFT +'; - } else { + if ($conf->browser->os === 'macintosh') { $stringforfirstkey .= ' CTL +'; + } else { + if ($conf->browser->name == 'chrome') { + $stringforfirstkey .= ' ALT +'; + } elseif ($conf->browser->name == 'firefox') { + $stringforfirstkey .= ' ALT + SHIFT +'; + } else { + $stringforfirstkey .= ' CTL +'; + } } if (!defined('JS_JQUERY_DISABLE_DROPDOWN') && !empty($conf->use_javascript_ajax)) { // This may be set by some pages that use different jquery version to avoid errors @@ -2987,11 +3002,19 @@ function top_menu_bookmark() }); // Key map shortcut - jQuery(document).keydown(function(event){ - if( event.which === 77 && event.ctrlKey && event.shiftKey ){ - console.log("Click on control + shift + m : trigger open bookmark dropdown"); - openBookMarkDropDown(event); - } + jQuery(document).keydown(function(event) { + var ostype = "'.$conf->browser->os.'"; + if (ostype === "macintosh") { + if ( event.which === 66 && event.ctrlKey ) { + console.log("Click on control + b : trigger open bookmark dropdown"); + openBookMarkDropDown(event); + } + } else { + if ( event.which === 66 && event.ctrlKey && event.shiftKey ) { + console.log("Click on control + shift + b : trigger open bookmark dropdown"); + openBookMarkDropDown(event); + } + } }); var openBookMarkDropDown = function(event) { @@ -3178,15 +3201,15 @@ function top_menu_search() /** * Show left menu bar * - * @param array $menu_array_before Table of menu entries to show before entries of menu handler. This param is deprecated and must be provided to ''. - * @param string $helppagename Name of wiki page for help ('' by default). - * Syntax is: For a wiki page: EN:EnglishPage|FR:FrenchPage|ES:SpanishPage|DE:GermanPage - * For other external page: http://server/url - * @param string $notused Deprecated. Used in past to add content into left menu. Hooks can be used now. - * @param array $menu_array_after Table of menu entries to show after entries of menu handler - * @param int $leftmenuwithoutmainarea Must be set to 1. 0 by default for backward compatibility with old modules. - * @param string $title Title of web page - * @param int $acceptdelayedhtml 1 if caller request to have html delayed content not returned but saved into global $delayedhtmlcontent (so caller can show it at end of page to avoid flash FOUC effect) + * @param string $menu_array_before Table of menu entries to show before entries of menu handler. This param is deprecated and must be provided to ''. + * @param string $helppagename Name of wiki page for help ('' by default). + * Syntax is: For a wiki page: EN:EnglishPage|FR:FrenchPage|ES:SpanishPage|DE:GermanPage + * For other external page: http://server/url + * @param string $notused Deprecated. Used in past to add content into left menu. Hooks can be used now. + * @param array $menu_array_after Table of menu entries to show after entries of menu handler + * @param int $leftmenuwithoutmainarea Must be set to 1. 0 by default for backward compatibility with old modules. + * @param string $title Title of web page + * @param int<0,1> $acceptdelayedhtml 1 if caller request to have html delayed content not returned but saved into global $delayedhtmlcontent (so caller can show it at end of page to avoid flash FOUC effect) * @return void */ function left_menu($menu_array_before, $helppagename = '', $notused = '', $menu_array_after = array(), $leftmenuwithoutmainarea = 0, $title = '', $acceptdelayedhtml = 0) @@ -3500,7 +3523,7 @@ function main_area($title = '') * * @param string $helppagename Page name ('EN:xxx,ES:eee,FR:fff,DE:ddd...' or 'http://localpage') * @param Translate $langs Language - * @return array Array of help urls + * @return array{helpbaseurl:string,helppage:string,mode:string} Array of help urls */ function getHelpParamFor($helppagename, $langs) { diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 3c0d1e41776..f2261034547 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -2102,8 +2102,7 @@ if (($dirins && $action == 'confirm_deletedictionary' && $dicname) || ($dirins & } //chercher la table dicname - $query = "SHOW TABLES LIKE '" . MAIN_DB_PREFIX.strtolower($newdicname) . "'"; - $checkTable = $db->query($query); + $checkTable = $db->DDLDescTable(MAIN_DB_PREFIX.strtolower($newdicname)); if ($checkTable && $db->num_rows($checkTable) <= 0) { $error++; } @@ -2942,7 +2941,7 @@ if ($dirins && $action == "update_menu" && GETPOSTINT('menukey') && GETPOST('tab } } } else { - $_POST['type'] = ''; + $_POST['type'] = ''; // TODO Use a var here and later $_POST['titre'] = ''; $_POST['fk_menu'] = ''; $_POST['leftmenu'] = ''; @@ -4960,7 +4959,7 @@ if ($module == 'initmodule') { print ''.$langs->trans("EnterNameOfDictionaryDesc").'

      '; - print dol_get_fiche_head(''); + print dol_get_fiche_head(); print ''; print ''; print ''; diff --git a/htdocs/modulebuilder/template/class/actions_mymodule.class.php b/htdocs/modulebuilder/template/class/actions_mymodule.class.php index 5070ae77e0a..3b9d04b0e38 100644 --- a/htdocs/modulebuilder/template/class/actions_mymodule.class.php +++ b/htdocs/modulebuilder/template/class/actions_mymodule.class.php @@ -108,7 +108,7 @@ class ActionsMyModule extends CommonHookActions /* print_r($parameters); print_r($object); echo "action: " . $action; */ if (in_array($parameters['currentcontext'], array('somecontext1', 'somecontext2'))) { // do something only for the context 'somecontext1' or 'somecontext2' // Do what you want here... - // You can for example call global vars like $fieldstosearchall to overwrite them, or update database depending on $action and $_POST values. + // You can for example load and use call global vars like $fieldstosearchall to overwrite them, or update database depending on $action and GETPOST values. } if (!$error) { diff --git a/htdocs/modulebuilder/template/class/api_mymodule.class.php b/htdocs/modulebuilder/template/class/api_mymodule.class.php index d716869cfcc..25291332ffd 100644 --- a/htdocs/modulebuilder/template/class/api_mymodule.class.php +++ b/htdocs/modulebuilder/template/class/api_mymodule.class.php @@ -76,7 +76,7 @@ class MyModuleApi extends DolibarrApi throw new RestException(403); } if (!DolibarrApi::_checkAccessToResource('myobject', $id, 'mymodule_myobject')) { - throw new RestException(403, 'Access to instance id='.$this->myobject->id.' of object not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access to instance id='.$id.' of object not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->myobject->fetch($id); @@ -206,7 +206,14 @@ class MyModuleApi extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->myobject->context['caller'] = $request_data['caller']; + $this->myobject->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); + continue; + } + + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->myobject->array_options[$index] = $this->_checkValForAPI('extrafields', $val, $this->myobject); + } continue; } @@ -255,7 +262,14 @@ class MyModuleApi extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->myobject->context['caller'] = $request_data['caller']; + $this->myobject->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); + continue; + } + + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->myobject->array_options[$index] = $this->_checkValForAPI('extrafields', $val, $this->myobject); + } continue; } diff --git a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php index c288ca7f3d9..7d0f0941b0b 100644 --- a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php +++ b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php @@ -42,6 +42,7 @@ class modMyModule extends DolibarrModules public function __construct($db) { global $langs, $conf; + $this->db = $db; // Id for module (must be unique). @@ -70,7 +71,8 @@ class modMyModule extends DolibarrModules // Author $this->editor_name = 'Editor name'; - $this->editor_url = 'https://www.example.com'; + $this->editor_url = 'https://www.example.com'; // Must be an external online web site + $this->editor_squarred_logo = ''; // Must be image filename into the module/img directory followed with @modulename. Example: 'myimage.png@mymodule' // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated', 'experimental_deprecated' or a version string like 'x.y.z' $this->version = '1.0'; diff --git a/htdocs/modulebuilder/template/mymoduleindex.php b/htdocs/modulebuilder/template/mymoduleindex.php index f11670f0906..9597abbd11f 100644 --- a/htdocs/modulebuilder/template/mymoduleindex.php +++ b/htdocs/modulebuilder/template/mymoduleindex.php @@ -63,9 +63,10 @@ $langs->loadLangs(array("mymodule@mymodule")); $action = GETPOST('action', 'aZ09'); -$max = 5; $now = dol_now(); +$max = getDolGlobalInt('MAIN_SIZE_SHORTLIST_LIMIT'); + // Security check - Protection if external user $socid = GETPOST('socid', 'int'); if (isset($user->socid) && $user->socid > 0) { @@ -184,9 +185,6 @@ END MODULEBUILDER DRAFT MYOBJECT */ print '
      '; -$NBMAX = getDolGlobalInt('MAIN_SIZE_SHORTLIST_LIMIT'); -$max = getDolGlobalInt('MAIN_SIZE_SHORTLIST_LIMIT'); - /* BEGIN MODULEBUILDER LASTMODIFIED MYOBJECT // Last modified myobject if (isModEnabled('mymodule') && $user->hasRight('mymodule', 'read')) { diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php index f006c4933ab..62cfd250fdd 100644 --- a/htdocs/modulebuilder/template/myobject_card.php +++ b/htdocs/modulebuilder/template/myobject_card.php @@ -282,8 +282,6 @@ if ($action == 'create') { print dol_get_fiche_head(array(), ''); - // Set some default values - //if (! GETPOSTISSET('fieldname')) $_POST['fieldname'] = 'myvalue'; print '
      '.$langs->trans("Table").'
      '."\n"; diff --git a/htdocs/mrp/class/api_mos.class.php b/htdocs/mrp/class/api_mos.class.php index a67d23b6877..23d07091d5b 100644 --- a/htdocs/mrp/class/api_mos.class.php +++ b/htdocs/mrp/class/api_mos.class.php @@ -187,11 +187,11 @@ class Mos extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->mo->context['caller'] = $request_data['caller']; + $this->mo->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->mo->$field = $value; + $this->mo->$field = $this->_checkValForAPI($field, $value, $this->mo); } $this->checkRefNumbering(); @@ -221,7 +221,7 @@ class Mos extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('mrp', $this->mo->id, 'mrp_mo')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach ($request_data as $field => $value) { @@ -230,11 +230,11 @@ class Mos extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->mo->context['caller'] = $request_data['caller']; + $this->mo->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->mo->$field = $value; + $this->mo->$field = $this->_checkValForAPI($field, $value, $this->mo); } $this->checkRefNumbering(); @@ -347,7 +347,7 @@ class Mos extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $stockmove->context['caller'] = $request_data['caller']; + $stockmove->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } } diff --git a/htdocs/mrp/index.php b/htdocs/mrp/index.php index 835a06cc7c6..409f1847a8b 100644 --- a/htdocs/mrp/index.php +++ b/htdocs/mrp/index.php @@ -42,6 +42,8 @@ $langs->loadLangs(array("companies", "mrp")); // Security check $result = restrictedArea($user, 'bom|mrp'); +$max = getDolGlobalInt('MAIN_SIZE_SHORTLIST_LIMIT'); + /* * View @@ -93,7 +95,8 @@ if ($conf->use_javascript_ajax) { print '
      '; print '
      '; - print ''."\n"; + print ''; + print ''."\n"; $listofstatus = array(0, 1, 2, 3, 9); foreach ($listofstatus as $status) { $dataseries[] = array($staticmo->LibStatut($status, 1), (isset($vals[$status]) ? (int) $vals[$status] : 0)); @@ -150,12 +153,11 @@ print '
      '; print '
      '; + /* * Last modified BOM */ -$max = 5; - $sql = "SELECT a.rowid, a.status, a.ref, a.tms as datem, a.status, a.fk_product"; $sql .= " FROM ".MAIN_DB_PREFIX."bom_bom as a"; $sql .= " WHERE a.entity IN (".getEntity('bom').")"; @@ -167,7 +169,9 @@ if ($resql) { print '
      '; print '
      '.$langs->trans("Statistics").' - '.$langs->trans("ManufacturingOrder").'
      '.$langs->trans("Statistics").' - '.$langs->trans("ManufacturingOrder").'
      '; print ''; - print ''; + print ''; + print ''; + print ''; $num = $db->num_rows($resql); if ($num) { @@ -190,7 +194,7 @@ if ($resql) { } } else { print ''; - print ''; + print ''; print ''; } print "
      '.$langs->trans("LatestBOMModified", $max).'
      '.$langs->trans("LatestBOMModified", $max).''.img_picto($langs->trans("FullList"), 'bom').'
      '.$langs->trans("None").''.$langs->trans("None").'
      "; @@ -203,7 +207,6 @@ if ($resql) { * Last modified MOs */ -$max = 5; $sql = "SELECT a.rowid, a.status, a.ref, a.tms as datem, a.status"; $sql .= " FROM ".MAIN_DB_PREFIX."mrp_mo as a"; @@ -216,7 +219,9 @@ if ($resql) { print '
      '; print ''; print ''; - print ''; + print ''; + print ''; + print ''; $num = $db->num_rows($resql); if ($num) { @@ -238,7 +243,7 @@ if ($resql) { } } else { print ''; - print ''; + print ''; print ''; } print "
      '.$langs->trans("LatestMOModified", $max).'
      '.$langs->trans("LatestMOModified", $max).''.img_picto($langs->trans("FullList"), 'mrp').'
      '.$langs->trans("None").''.$langs->trans("None").'
      "; diff --git a/htdocs/mrp/js/lib_dispatch.js.php b/htdocs/mrp/js/lib_dispatch.js.php index 58c3abc68f5..01077ab77e5 100644 --- a/htdocs/mrp/js/lib_dispatch.js.php +++ b/htdocs/mrp/js/lib_dispatch.js.php @@ -160,7 +160,7 @@ function addDispatchTR(qtyOrdered, qtyDispatched, index, nbrTrs, warehouseId, in $.jnotify(errormsg, 'error', true); return -1; } else if (qtyDispatched >= qtyOrdered) { - let errormsg = 'trans('NoRemainQtyToDispatch')); ?>; + let errormsg = 'trans('NoRemainQtyToDispatch')); ?>'; $.jnotify(errormsg, 'error', true); return -1; } else if (qtyDispatched < qtyOrdered) { diff --git a/htdocs/multicurrency/class/api_multicurrencies.class.php b/htdocs/multicurrency/class/api_multicurrencies.class.php index 3158263c0b7..77bc13f098b 100644 --- a/htdocs/multicurrency/class/api_multicurrencies.class.php +++ b/htdocs/multicurrency/class/api_multicurrencies.class.php @@ -212,8 +212,16 @@ class MultiCurrencies extends DolibarrApi } $multicurrency = new MultiCurrency($this->db); - $multicurrency->code = $request_data['code']; - $multicurrency->name = $request_data['name']; + + foreach ($request_data as $field => $value) { + if ($field === 'caller') { + // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller + $multicurrency->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); + continue; + } + + $multicurrency->$field = $this->_checkValForAPI($field, $value, $multicurrency); + } // Create Currency if ($multicurrency->create(DolibarrApiAccess::$user) < 0) { @@ -258,11 +266,11 @@ class MultiCurrencies extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $multicurrency->context['caller'] = $request_data['caller']; + $multicurrency->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $multicurrency->$field = $value; + $multicurrency->$field = $this->_checkValForAPI($field, $value, $multicurrency); } if ($multicurrency->update(DolibarrApiAccess::$user) < 0) { diff --git a/htdocs/opensurvey/lib/opensurvey.lib.php b/htdocs/opensurvey/lib/opensurvey.lib.php index 141f01ab5af..80e272eaf90 100644 --- a/htdocs/opensurvey/lib/opensurvey.lib.php +++ b/htdocs/opensurvey/lib/opensurvey.lib.php @@ -175,9 +175,9 @@ function get_server_name() /** * Fonction vérifiant l'existance et la valeur non vide d'une clé d'un tableau * - * @param string $name La clé à tester - * @param array $tableau Le tableau où rechercher la clé ($_POST par défaut) - * @return bool Vrai si la clé existe et renvoie une valeur non vide + * @param string $name Key to test + * @param array $tableau Array in which searching key ($_POST by default) + * @return bool True if key exists and return a non empty value */ function issetAndNoEmpty($name, $tableau = null) { diff --git a/htdocs/partnership/class/api_partnerships.class.php b/htdocs/partnership/class/api_partnerships.class.php index 0fda760e704..8261422c64a 100644 --- a/htdocs/partnership/class/api_partnerships.class.php +++ b/htdocs/partnership/class/api_partnerships.class.php @@ -198,7 +198,7 @@ class Partnerships extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->partnership->context['caller'] = $request_data['caller']; + $this->partnership->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } @@ -246,7 +246,7 @@ class Partnerships extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->partnership->context['caller'] = $request_data['caller']; + $this->partnership->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } diff --git a/htdocs/product/ajax/products.php b/htdocs/product/ajax/products.php index 3f26a9ad2b4..711af593d2e 100644 --- a/htdocs/product/ajax/products.php +++ b/htdocs/product/ajax/products.php @@ -35,7 +35,7 @@ if (!defined('NOREQUIREHTML')) { if (!defined('NOREQUIREAJAX')) { define('NOREQUIREAJAX', '1'); } -if (empty($_GET['keysearch']) && !defined('NOREQUIREHTML')) { +if (empty($_GET['keysearch']) && !defined('NOREQUIREHTML')) { // Keep $_GET here, GETPOST is not yet defined define('NOREQUIREHTML', '1'); } @@ -67,7 +67,6 @@ restrictedArea($user, 'produit|service|commande|propal|facture', 0, 'product&pro */ // print ''."\n"; -// print_r($_GET); if ($action == 'fetch' && !empty($id)) { // action='fetch' is used to get product information on a product. So when action='fetch', id must be the product id. diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 3813ec3432e..a9a7923b3c2 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -923,7 +923,7 @@ if (empty($reshook)) { // We use native clone to keep this->db valid and allow to use later all the methods of object. $clone = dol_clone($object, 1); - $clone->id = null; + $clone->id = 0; $clone->ref = GETPOST('clone_ref', 'alphanohtml'); $clone->status = 0; $clone->status_buy = 0; @@ -1364,7 +1364,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($canvasdisplayactio $object->country = $tmparray['label']; } - print dol_get_fiche_head(''); + print dol_get_fiche_head(); // Call Hook tabContentCreateProduct $parameters = array(); @@ -3032,7 +3032,7 @@ if (getDolGlobalString('PRODUCT_ADD_FORM_ADD_TO') && $object->id && ($action == print load_fiche_titre($langs->trans("AddToDraft"), '', ''); - print dol_get_fiche_head(''); + print dol_get_fiche_head(); $html .= ''.$langs->trans("Quantity").' '; $html .= ''; diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 48ab72e66d4..0d01072f8e8 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -315,11 +315,11 @@ class Products extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->product->context['caller'] = $request_data['caller']; + $this->product->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->product->$field = $value; + $this->product->$field = $this->_checkValForAPI($field, $value, $this->product); } if ($this->product->create(DolibarrApiAccess::$user) < 0) { throw new RestException(500, "Error creating product", array_merge(array($this->product->error), $this->product->errors)); @@ -351,7 +351,7 @@ class Products extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('product', $this->product->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $oldproduct = dol_clone($this->product); @@ -365,11 +365,11 @@ class Products extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->product->context['caller'] = $request_data['caller']; + $this->product->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->product->$field = $value; + $this->product->$field = $this->_checkValForAPI($field, $value, $this->product); } $updatetype = false; @@ -453,7 +453,7 @@ class Products extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('product', $this->product->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } // The Product::delete() method uses the global variable $user. @@ -494,7 +494,7 @@ class Products extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('product', $id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $childrenArbo = $this->product->getChildsArbo($id, 1); @@ -532,7 +532,7 @@ class Products extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('product', $id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->product->add_sousproduit($id, $subproduct_id, $qty, $incdec); @@ -562,7 +562,7 @@ class Products extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('product', $id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->product->del_sousproduit($id, $subproduct_id); @@ -775,7 +775,7 @@ class Products extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('product', $this->productsupplier->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : ''; @@ -832,7 +832,7 @@ class Products extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('product', $this->productsupplier->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $resultsupplier = 0; @@ -987,7 +987,7 @@ class Products extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('product', $this->product->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $product_fourn_list = array(); @@ -1281,11 +1281,11 @@ class Products extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $prodattr->context['caller'] = $request_data['caller']; + $prodattr->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $prodattr->$field = $value; + $prodattr->$field = $this->_checkValForAPI($field, $value, $prodattr); } if ($prodattr->update(DolibarrApiAccess::$user) > 0) { @@ -1594,11 +1594,11 @@ class Products extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $objectval->context['caller'] = $request_data['caller']; + $objectval->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $objectval->$field = $value; + $objectval->$field = $this->_checkValForAPI($field, $value, $objectval); } if ($objectval->update(DolibarrApiAccess::$user) > 0) { @@ -1861,11 +1861,11 @@ class Products extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $prodcomb->context['caller'] = $request_data['caller']; + $prodcomb->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $prodcomb->$field = $value; + $prodcomb->$field = $this->_checkValForAPI($field, $value, $prodcomb); } $result = $prodcomb->update(DolibarrApiAccess::$user); @@ -2064,7 +2064,7 @@ class Products extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('product', $this->product->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if (!empty($includestockdata) && DolibarrApiAccess::$user->hasRight('stock', 'lire')) { diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 079abdacd05..641ba49ed29 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -72,7 +72,7 @@ class Product extends CommonObject public $fk_element = 'fk_product'; /** - * @var Product + * @var static */ public $oldcopy; @@ -777,6 +777,7 @@ class Product extends CommonObject } dol_include_once('/core/modules/product/'.$module.'.php'); $modCodeProduct = new $module(); + '@phan-var-force ModeleProductCode $modCodeProduct'; if (!empty($modCodeProduct->code_auto)) { $this->ref = $modCodeProduct->getNextValue($this, $this->type); } @@ -1048,6 +1049,7 @@ class Product extends CommonObject } $mod = new $module(); + '@phan-var-force ModeleNumRefBarCode $mod'; dol_syslog(get_class($this)."::check_barcode value=".$valuetotest." type=".$typefortest." module=".$module); $result = $mod->verif($this->db, $valuetotest, $this, 0, $typefortest); @@ -6358,6 +6360,7 @@ class Product extends CommonObject } $var = getDolGlobalString('BARCODE_PRODUCT_ADDON_NUM'); $mod = new $var(); + '@phan-var-force ModeleNumRefBarCode $module'; $result = $mod->getNextValue($object, $type); diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index 646c8fc7fef..3de815d6f73 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -66,8 +66,8 @@ $extrafields = new ExtraFields($db); // If socid provided by ajax company selector if (GETPOSTINT('search_fourn_id')) { - $_GET['id_fourn'] = GETPOSTINT('search_fourn_id'); - $_POST['id_fourn'] = GETPOSTINT('search_fourn_id'); + $_GET['id_fourn'] = GETPOSTINT('search_fourn_id'); // Keep set to $_GET an $_POST. Used later. + $_POST['id_fourn'] = GETPOSTINT('search_fourn_id'); // Keep set to $_GET an $_POST. Used later. } // Security check diff --git a/htdocs/product/index.php b/htdocs/product/index.php index d7fb18d737b..02ffb3632f2 100644 --- a/htdocs/product/index.php +++ b/htdocs/product/index.php @@ -78,11 +78,16 @@ if (GETPOST('addbox')) { } } +$max = getDolGlobalInt('MAIN_SIZE_SHORTLIST_LIMIT'); + /* * View */ +$producttmp = new Product($db); +$warehouse = new Entrepot($db); + $transAreaType = $langs->trans("ProductsAndServicesArea"); $helpurl = ''; @@ -304,15 +309,14 @@ if (isModEnabled('category') && getDolGlobalString('CATEGORY_GRAPHSTATS_ON_PRODU * Latest modified products */ if ((isModEnabled("product") || isModEnabled("service")) && ($user->hasRight("produit", "lire") || $user->hasRight("service", "lire"))) { - $max = 15; $sql = "SELECT p.rowid, p.label, p.price, p.ref, p.fk_product_type, p.tosell, p.tobuy, p.tobatch, p.fk_price_expression,"; $sql .= " p.entity,"; $sql .= " p.tms as datem"; $sql .= " FROM ".MAIN_DB_PREFIX."product as p"; $sql .= " WHERE p.entity IN (".getEntity($product_static->element, 1).")"; - if ($type != '') { + /*if ($type != '') { $sql .= " AND p.fk_product_type = ".((int) $type); - } + }*/ // Add where from hooks $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $product_static); // Note that $action and $object may have been modified by hook @@ -330,10 +334,10 @@ if ((isModEnabled("product") || isModEnabled("service")) && ($user->hasRight("pr if ($num > 0) { $transRecordedType = $langs->trans("LastModifiedProductsAndServices", $max); - if (GETPOSTISSET("type") && GETPOST("type") == '0') { + if (!isModEnabled('service')) { $transRecordedType = $langs->trans("LastRecordedProducts", $max); } - if (GETPOSTISSET("type") && GETPOST("type") == '1') { + if (!isModEnabled('product')) { $transRecordedType = $langs->trans("LastRecordedServices", $max); } @@ -346,7 +350,15 @@ if ((isModEnabled("product") || isModEnabled("service")) && ($user->hasRight("pr } $lastmodified .= ''.$transRecordedType.''; - $lastmodified .= ''.$langs->trans("FullList").''; + $lastmodified .= ''; + $lastmodified .= ''; + //$lastmodified .= $langs->trans("FullList"); + $lastmodified .= img_picto($langs->trans("FullList").' - '.$langs->trans("Products"), 'product'); + $lastmodified .= '   '; + $lastmodified .= ''; + //$langs->trans("FullList").''; + $lastmodified .= img_picto($langs->trans("FullList").' - '.$langs->trans("Services"), 'service'); + $lastmodified .= ''; $lastmodified .= ''; while ($i < $num) { @@ -435,6 +447,174 @@ if ((isModEnabled("product") || isModEnabled("service")) && ($user->hasRight("pr } } +$latestwarehouse = ''; +if (isModEnabled('stock')) { + $sql = "SELECT e.rowid, e.ref as label, e.lieu, e.statut as status"; + $sql .= " FROM ".MAIN_DB_PREFIX."entrepot as e"; + $sql .= " WHERE e.statut in (".Entrepot::STATUS_CLOSED.",".Entrepot::STATUS_OPEN_ALL.")"; + $sql .= " AND e.entity IN (".getEntity('stock').")"; + $sql .= $db->order('e.tms', 'DESC'); + $sql .= $db->plimit($max + 1, 0); + + $result = $db->query($sql); + + if ($result) { + $num = $db->num_rows($result); + + $latestwarehouse .= '
      '; + $latestwarehouse .= ''; + $latestwarehouse .= ''; + $latestwarehouse .= ''; + $latestwarehouse .= ''; + + $i = 0; + if ($num) { + while ($i < min($max, $num)) { + $objp = $db->fetch_object($result); + + $warehouse->id = $objp->rowid; + $warehouse->statut = $objp->status; + $warehouse->label = $objp->label; + $warehouse->lieu = $objp->lieu; + + $latestwarehouse .= ''; + $latestwarehouse .= ''."\n"; + $latestwarehouse .= ''; + $latestwarehouse .= "\n"; + $i++; + } + $db->free($result); + } else { + $latestwarehouse .= ''; + } + /*if ($num > $max) { + $latestwarehouse .= ''; + }*/ + + $latestwarehouse .= "
      '; + $latestwarehouse .= $langs->trans("LatestModifiedWarehouses", $max); + //$latestwarehouse .= ''; + // TODO: "search_status" on "/product/stock/list.php" currently only accept a single integer value + //print ''; + //$latestwarehouse .= ''.$num.''; + $latestwarehouse .= ''; + $latestwarehouse .= ''; + $latestwarehouse .= img_picto($langs->trans("FullList"), 'stock'); + $latestwarehouse .= ''; + $latestwarehouse .= '
      '; + $latestwarehouse .= $warehouse->getNomUrl(1); + $latestwarehouse .= ''; + $latestwarehouse .= $warehouse->getLibStatut(5); + $latestwarehouse .= '
      '.$langs->trans("None").'
      '.$langs->trans("More").'...
      "; + $latestwarehouse .= '
      '; + $latestwarehouse .= '
      '; + } else { + dol_print_error($db); + } +} + + +$latestmovement = ''; +if (isModEnabled('product')) { + // Latest movements + $sql = "SELECT p.rowid, p.label as produit, p.tobatch, p.tosell, p.tobuy,"; + $sql .= " e.ref as warehouse_ref, e.rowid as warehouse_id, e.ref as warehouse_label, e.lieu, e.statut as warehouse_status,"; + $sql .= " m.rowid as mid, m.value as qty, m.datem, m.batch, m.eatby, m.sellby"; + $sql .= " FROM ".MAIN_DB_PREFIX."entrepot as e"; + $sql .= ", ".MAIN_DB_PREFIX."stock_mouvement as m"; + $sql .= ", ".MAIN_DB_PREFIX."product as p"; + $sql .= " WHERE m.fk_product = p.rowid"; + $sql .= " AND m.fk_entrepot = e.rowid"; + $sql .= " AND e.entity IN (".getEntity('stock').")"; + if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) { + $sql .= " AND p.fk_product_type = ".Product::TYPE_PRODUCT; + } + $sql .= $db->order("datem", "DESC"); + $sql .= $db->plimit($max, 0); + + dol_syslog("Index:list stock movements", LOG_DEBUG); + $resql = $db->query($sql); + if ($resql) { + $num = $db->num_rows($resql); + + $latestmovement .= '
      '; + $latestmovement .= ''; + $latestmovement .= ''; + $latestmovement .= ''; + $latestmovement .= ''; + if (isModEnabled('productbatch')) { + $latestmovement .= ''; + } + $latestmovement .= ''; + $latestmovement .= ''; + $latestmovement .= "\n"; + + $tmplotstatic = new Productlot($db); + + $i = 0; + while ($i < min($num, $max)) { + $objp = $db->fetch_object($resql); + + $producttmp->id = $objp->rowid; + $producttmp->ref = $objp->produit; + $producttmp->status_batch = $objp->tobatch; + $producttmp->status_sell = $objp->tosell; + $producttmp->status_buy = $objp->tobuy; + + $warehouse->id = $objp->warehouse_id; + $warehouse->ref = $objp->warehouse_ref; + $warehouse->statut = $objp->warehouse_status; + $warehouse->label = $objp->warehouse_label; + $warehouse->lieu = $objp->lieu; + + $tmplotstatic->batch = $objp->batch; + $tmplotstatic->sellby = $objp->sellby; + $tmplotstatic->eatby = $objp->eatby; + + $latestmovement .= ''; + $latestmovement .= ''; + $latestmovement .= '\n"; + if (isModEnabled('productbatch')) { + $latestmovement .= ''; + /*if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) { + print ''; + } + if (empty($conf->global->PRODUCT_DISABLE_EATBY)) { + print ''; + }*/ + } + $latestmovement .= '\n"; + $latestmovement .= ''; + $latestmovement .= "\n"; + $i++; + } + $db->free($resql); + + $latestmovement .= "
      '.$langs->trans("LastMovements", min($num, $max)).''.$langs->trans("Product").''.$langs->trans("Batch").''.$langs->trans("Warehouse").''; + $latestmovement .= img_picto($langs->trans("FullList"), 'movement'); + $latestmovement .= '
      '.img_picto($langs->trans("Ref").' '.$objp->mid, 'movement', 'class="pictofixedwidth"').dol_print_date($db->jdate($objp->datem), 'dayhour').''; + $latestmovement .= $producttmp->getNomUrl(1); + $latestmovement .= "'; + $latestmovement .= $tmplotstatic->getNomUrl(0, 'nolink'); + $latestmovement .= ''.dol_print_date($db->jdate($objp->sellby), 'day').''.dol_print_date($db->jdate($objp->eatby), 'day').''; + $latestmovement .= $warehouse->getNomUrl(1); + $latestmovement .= "'; + if ($objp->qty < 0) { + $latestmovement .= ''; + } + if ($objp->qty > 0) { + $latestmovement .= ''; + $latestmovement .= '+'; + } + $latestmovement .= $objp->qty; + $latestmovement .= ''; + $latestmovement .= '
      "; + $latestmovement .= '
      '; + $latestmovement .= '
      '; + } else { + dol_print_error($db); + } +} // TODO Move this into a page that should be available into menu "accountancy - report - turnover - per quarter" // Also method used for counting must provide the 2 possible methods like done by all other reports into menu "accountancy - report - turnover": @@ -468,6 +648,8 @@ $boxlist .= "
      \n"; $boxlist .= '
      '; $boxlist .= $lastmodified; +$boxlist .= $latestwarehouse; +$boxlist .= $latestmovement; $boxlist .= $resultboxes['boxlistb']; $boxlist .= '
      '."\n"; diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 0aab3be055c..a70a9a08faf 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -412,7 +412,7 @@ if (empty($reshook)) { } } else { // Clear var - $_POST['batch'] = ''; + $_POST['batch'] = ''; // TODO Replace this with a var $_POST['qtytoadd'] = ''; } } diff --git a/htdocs/product/price.php b/htdocs/product/price.php index 075ebd97277..e6301b19aaa 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -1417,7 +1417,7 @@ if ($action == 'edit_vat' && ($user->hasRight('produit', 'creer') || $user->hasR print ''; print ''; - print dol_get_fiche_head(''); + print dol_get_fiche_head(); print ''; @@ -1446,7 +1446,7 @@ if ($action == 'edit_price' && $object->getRights()->creer) { print ''; print ''; - print dol_get_fiche_head(''); + print dol_get_fiche_head(); print '
      '; print '
      '; @@ -1582,7 +1582,7 @@ if ($action == 'edit_price' && $object->getRights()->creer) { print ''; print ''; - //print dol_get_fiche_head('', '', '', -1); + //print dol_get_fiche_head(array(), '', '', -1); if ((getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES')) && getDolGlobalString('PRODUIT_MULTIPRICES_ALLOW_AUTOCALC_PRICELEVEL')) { print $langs->trans('UseMultipriceRules').' price_autogen ? 'checked' : '').'>

      '; diff --git a/htdocs/product/stock/class/api_stockmovements.class.php b/htdocs/product/stock/class/api_stockmovements.class.php index e2457e09f8d..485aebbc9e6 100644 --- a/htdocs/product/stock/class/api_stockmovements.class.php +++ b/htdocs/product/stock/class/api_stockmovements.class.php @@ -75,7 +75,7 @@ class StockMovements extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('warehouse',$this->stockmovement->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } return $this->_cleanObjectDatas($this->stockmovement); @@ -228,7 +228,7 @@ class StockMovements extends DolibarrApi } if( ! DolibarrApi::_checkAccessToResource('stock',$this->stockmovement->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach($request_data as $field => $value) { @@ -260,7 +260,7 @@ class StockMovements extends DolibarrApi } if (! DolibarrApi::_checkAccessToResource('stock',$this->stockmovement->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if (! $this->stockmovement->delete(DolibarrApiAccess::$user)) { diff --git a/htdocs/product/stock/class/api_warehouses.class.php b/htdocs/product/stock/class/api_warehouses.class.php index 1af08af0534..ecea11b5dea 100644 --- a/htdocs/product/stock/class/api_warehouses.class.php +++ b/htdocs/product/stock/class/api_warehouses.class.php @@ -72,7 +72,7 @@ class Warehouses extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('stock', $this->warehouse->id, 'entrepot')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } return $this->_cleanObjectDatas($this->warehouse); @@ -173,11 +173,11 @@ class Warehouses extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->warehouse->context['caller'] = $request_data['caller']; + $this->warehouse->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->warehouse->$field = $value; + $this->warehouse->$field = $this->_checkValForAPI($field, $value, $this->warehouse); } if ($this->warehouse->create(DolibarrApiAccess::$user) < 0) { throw new RestException(500, "Error creating warehouse", array_merge(array($this->warehouse->error), $this->warehouse->errors)); @@ -204,7 +204,7 @@ class Warehouses extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('stock', $this->warehouse->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach ($request_data as $field => $value) { @@ -213,11 +213,11 @@ class Warehouses extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->warehouse->context['caller'] = $request_data['caller']; + $this->warehouse->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->warehouse->$field = $value; + $this->warehouse->$field = $this->_checkValForAPI($field, $value, $this->warehouse); } if ($this->warehouse->update($id, DolibarrApiAccess::$user)) { @@ -244,7 +244,7 @@ class Warehouses extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('stock', $this->warehouse->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if (!$this->warehouse->delete(DolibarrApiAccess::$user)) { diff --git a/htdocs/product/stock/massstockmove.php b/htdocs/product/stock/massstockmove.php index 88b51aa78ab..77c23f943c4 100644 --- a/htdocs/product/stock/massstockmove.php +++ b/htdocs/product/stock/massstockmove.php @@ -308,7 +308,7 @@ if ($action == 'createmovements' && $user->hasRight('stock', 'mouvement', 'creer $db->commit(); setEventMessages($langs->trans("StockMovementRecorded"), null, 'mesgs'); - header("Location: ".DOL_URL_ROOT.'/product/stock/index.php'); // Redirect to avoid pb when using back + header("Location: ".DOL_URL_ROOT.'/product/stock/list.php'); // Redirect to avoid pb when using back exit; } else { $db->rollback(); @@ -519,7 +519,7 @@ if ($action == 'confirm_deletefile' && $confirm == 'yes') { $param .= '&endatlinenb='.urlencode($endatlinenb); } - $file = $conf->stock->dir_temp.'/'.GETPOST('urlfile'); // Do not use urldecode here ($_GET and $_REQUEST are already decoded by PHP). + $file = $conf->stock->dir_temp.'/'.GETPOST('urlfile'); $ret = dol_delete_file($file); if ($ret) { setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs'); diff --git a/htdocs/product/stock/movement_list.php b/htdocs/product/stock/movement_list.php index 34c08a3186f..99305884287 100644 --- a/htdocs/product/stock/movement_list.php +++ b/htdocs/product/stock/movement_list.php @@ -64,8 +64,8 @@ $mode = GETPOST('mode', 'aZ'); // The output mode ('list', 'kanban', 'hier $id = GETPOSTINT('id'); $ref = GETPOST('ref', 'alpha'); $msid = GETPOSTINT('msid'); -$idproduct = GETPOSTINT('idproduct'); -$product_id = GETPOSTINT("product_id"); +$idproduct = GETPOST('idproduct', 'intcomma'); +$product_id = GETPOST("product_id", 'intcomma'); $show_files = GETPOSTINT('show_files'); $search_all = trim((GETPOST('search_all', 'alphanohtml') != '') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml')); @@ -86,8 +86,8 @@ $search_inventorycode = trim(GETPOST("search_inventorycode")); $search_user = trim(GETPOST("search_user")); $search_batch = trim(GETPOST("search_batch")); $search_qty = trim(GETPOST("search_qty")); -$search_type_mouvement = GETPOSTINT('search_type_mouvement'); -$search_fk_project = GETPOSTINT("search_fk_project"); +$search_type_mouvement = GETPOST('search_type_mouvement'); +$search_fk_project = GETPOST("search_fk_project"); $type = GETPOSTINT("type"); diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php index 39f35080378..0677267100c 100644 --- a/htdocs/product/stock/product.php +++ b/htdocs/product/stock/product.php @@ -70,7 +70,7 @@ $ref = GETPOST('ref', 'alpha'); $stocklimit = (float) GETPOST('seuil_stock_alerte'); $desiredstock = GETPOST('desiredstock'); $cancel = GETPOST('cancel', 'alpha'); -$fieldid = isset($_GET["ref"]) ? 'ref' : 'rowid'; +$fieldid = GETPOSTISSET("ref") ? 'ref' : 'rowid'; $d_eatby = dol_mktime(0, 0, 0, GETPOSTINT('eatbymonth'), GETPOSTINT('eatbyday'), GETPOSTINT('eatbyyear')); $d_sellby = dol_mktime(0, 0, 0, GETPOSTINT('sellbymonth'), GETPOSTINT('sellbyday'), GETPOSTINT('sellbyyear')); $pdluoid = GETPOSTINT('pdluoid'); diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php index e83e505f3e0..c725a339a45 100644 --- a/htdocs/product/stock/replenish.php +++ b/htdocs/product/stock/replenish.php @@ -452,7 +452,7 @@ if ($usevirtualstock) { $sqlReceptionFourn = "(SELECT ".$db->ifsql("SUM(fd4.qty) IS NULL", "0", "SUM(fd4.qty)")." as qty"; // We need the ifsql because if result is 0 for product p.rowid, we must return 0 and not NULL $sqlReceptionFourn .= " FROM ".MAIN_DB_PREFIX."commande_fournisseur as cf4,"; $sqlReceptionFourn .= " ".MAIN_DB_PREFIX."receptiondet_batch as fd4"; - $sqlReceptionFourn .= " WHERE fd4.fk_commande = cf4.rowid AND cf4.entity IN (".getEntity(getDolGlobalString('STOCK_CALCULATE_VIRTUAL_STOCK_TRANSVERSE_MODE') ? 'stock' : 'supplier_order').")"; + $sqlReceptionFourn .= " WHERE fd4.fk_element = cf4.rowid AND cf4.entity IN (".getEntity(getDolGlobalString('STOCK_CALCULATE_VIRTUAL_STOCK_TRANSVERSE_MODE') ? 'stock' : 'supplier_order').")"; $sqlReceptionFourn .= " AND fd4.fk_product = p.rowid"; $sqlReceptionFourn .= " AND cf4.fk_statut IN (3,4))"; } else { @@ -845,7 +845,9 @@ while ($i < ($limit ? min($num, $limit) : $num)) { } } else { $stock = $prod->stock_reel; - $stockwarehouse = $prod->stock_warehouse[$fk_entrepot]->real; + if (getDolGlobalString('STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE') && $fk_entrepot > 0) { + $stockwarehouse = $prod->stock_warehouse[$fk_entrepot]->real; + } } // Force call prod->load_stats_xxx to choose status to count (otherwise it is loaded by load_stock function) diff --git a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php index 363929ec4ac..ff385fd5fdf 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php @@ -47,6 +47,11 @@ class StockTransfer extends CommonObject */ public $table_element = 'stocktransfer_stocktransfer'; + /** + * @var string Name of subtable line + */ + public $table_element_line = 'stocktransfer_stocktransferline'; + /** * @var int Does this object support multicompany module ? * 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php index 7521fb2ef3b..96b228fba9e 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_card.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -439,8 +439,6 @@ if ($action == 'create') { print dol_get_fiche_head(array(), ''); - // Set some default values - //if (! GETPOSTISSET('fieldname')) $_POST['fieldname'] = 'myvalue'; print '
      '."\n"; diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_contact.php b/htdocs/product/stock/stocktransfer/stocktransfer_contact.php index 33d2ff92f04..8f599eb71de 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_contact.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_contact.php @@ -78,7 +78,7 @@ $result = restrictedArea($user, 'stocktransfer', $id, '', 'stocktransfer'); if ($action == 'addcontact' && $user->hasRight('stocktransfer', 'stocktransfer', 'write')) { if ($object->id > 0) { $contactid = (GETPOSTINT('userid') ? GETPOSTINT('userid') : GETPOSTINT('contactid')); - $result = $object->add_contact($contactid, !empty($_POST["typecontact"]) ? $_POST["typecontact"] : $_POST["type"], $_POST["source"]); + $result = $object->add_contact($contactid, GETPOST("typecontact") ? GETPOST("typecontact") : GETPOST("type"), GETPOST("source")); } if ($result >= 0) { @@ -106,12 +106,6 @@ if ($action == 'addcontact' && $user->hasRight('stocktransfer', 'stocktransfer', dol_print_error($db); } } -/* -elseif ($action == 'setaddress' && $user->rights->stocktransfer->stocktransfer->write) -{ - $result=$object->setDeliveryAddress($_POST['fk_address']); - if ($result < 0) dol_print_error($db,$object->error); -}*/ /* diff --git a/htdocs/product/stock/valo.php b/htdocs/product/stock/valo.php index 259f139a177..36ab59584ae 100644 --- a/htdocs/product/stock/valo.php +++ b/htdocs/product/stock/valo.php @@ -30,30 +30,32 @@ require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php'; // Load translation files required by the page $langs->load("stocks"); -// Security check -$result = restrictedArea($user, 'stock'); - $sref = GETPOST("sref", 'alpha'); $snom = GETPOST("snom", 'alpha'); $sall = trim((GETPOST('search_all', 'alphanohtml') != '') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml')); +$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit; $sortfield = GETPOST('sortfield', 'aZ09comma'); $sortorder = GETPOST('sortorder', 'aZ09comma'); +$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT('page'); +if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) { + // If $page is not defined, or '' or -1 or if we click on clear filters + $page = 0; +} +$offset = $limit * $page; + if (!$sortfield) { $sortfield = "e.ref"; } if (!$sortorder) { $sortorder = "ASC"; } -$page = $_GET["page"]; -if ($page < 0) { - $page = 0; -} -$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit; -$offset = $limit * $page; $year = dol_print_date(dol_now('gmt'), "%Y", 'gmt'); +// Security check +$result = restrictedArea($user, 'stock'); + /* * View diff --git a/htdocs/projet/class/api_projects.class.php b/htdocs/projet/class/api_projects.class.php index b3637643169..cae608e5c5e 100644 --- a/htdocs/projet/class/api_projects.class.php +++ b/htdocs/projet/class/api_projects.class.php @@ -77,18 +77,78 @@ class Projects extends DolibarrApi $result = $this->project->fetch($id); if (!$result) { - throw new RestException(404, 'Project not found'); + throw new RestException(404, 'Project with supplied id not found'); } if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->project->fetchObjectLinked(); return $this->_cleanObjectDatas($this->project); } + /** + * Get properties of a project object + * + * Return an array with project information + * + * @param string $ref Ref of project + * @return Object Object with cleaned properties + * + * @url GET ref/{ref} + * + * @throws RestException + */ + public function getByRef($ref) + { + if (!DolibarrApiAccess::$user->hasRight('projet', 'lire')) { + throw new RestException(403); + } + $result = $this->project->fetch('', $ref); + if (!$result) { + throw new RestException(404, 'Project with supplied ref not found'); + } + + if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) { + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $this->project->fetchObjectLinked(); + return $this->_cleanObjectDatas($this->project); + } + + /** + * Get properties of a project object + * + * Return an array with project information + * + * @param string $email_msgid Email msgid of project + * @return Object Object with cleaned properties + * + * @url GET email_msgid/{email_msgid} + * + * @throws RestException + */ + public function getByMsgId($email_msgid) + { + if (!DolibarrApiAccess::$user->hasRight('projet', 'lire')) { + throw new RestException(403); + } + + $result = $this->project->fetch('', '', '', $email_msgid); + if (!$result) { + throw new RestException(404, 'Project with supplied email_msgid not found'); + } + + if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) { + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $this->project->fetchObjectLinked(); + return $this->_cleanObjectDatas($this->project); + } /** * List projects @@ -202,11 +262,11 @@ class Projects extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->project->context['caller'] = $request_data['caller']; + $this->project->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->project->$field = $value; + $this->project->$field = $this->_checkValForAPI($field, $value, $this->project); } /*if (isset($request_data["lines"])) { $lines = array(); @@ -244,7 +304,7 @@ class Projects extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->project->getLinesArray(DolibarrApiAccess::$user); $result = array(); @@ -284,7 +344,7 @@ class Projects extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; @@ -327,7 +387,7 @@ class Projects extends DolibarrApi } if( ! DolibarrApi::_checkAccessToResource('project',$this->project->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $request_data = (object) $request_data; @@ -394,7 +454,7 @@ class Projects extends DolibarrApi } if( ! DolibarrApi::_checkAccessToResource('project',$this->project->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $request_data = (object) $request_data; @@ -454,7 +514,7 @@ class Projects extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach ($request_data as $field => $value) { if ($field == 'id') { @@ -462,11 +522,11 @@ class Projects extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->project->context['caller'] = $request_data['caller']; + $this->project->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->project->$field = $value; + $this->project->$field = $this->_checkValForAPI($field, $value, $this->project); } if ($this->project->update(DolibarrApiAccess::$user) >= 0) { @@ -494,7 +554,7 @@ class Projects extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if (!$this->project->delete(DolibarrApiAccess::$user)) { @@ -538,7 +598,7 @@ class Projects extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->project->setValid(DolibarrApiAccess::$user, $notrigger); diff --git a/htdocs/projet/class/api_tasks.class.php b/htdocs/projet/class/api_tasks.class.php index 89907456672..2188087a220 100644 --- a/htdocs/projet/class/api_tasks.class.php +++ b/htdocs/projet/class/api_tasks.class.php @@ -77,7 +77,7 @@ class Tasks extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('task', $this->task->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if ($includetimespent == 1) { @@ -198,11 +198,11 @@ class Tasks extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->task->context['caller'] = $request_data['caller']; + $this->task->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->task->$field = $value; + $this->task->$field = $this->_checkValForAPI($field, $value, $this->task); } /*if (isset($request_data["lines"])) { $lines = array(); @@ -239,7 +239,7 @@ class Tasks extends DolibarrApi } if( ! DolibarrApi::_checkAccessToResource('project',$this->project->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->project->getLinesArray(DolibarrApiAccess::$user); $result = array(); @@ -284,7 +284,7 @@ class Tasks extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('tasks', $this->task->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $usert = DolibarrApiAccess::$user; @@ -325,7 +325,7 @@ class Tasks extends DolibarrApi } if( ! DolibarrApi::_checkAccessToResource('project',$this->project->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $request_data = (object) $request_data; @@ -392,7 +392,7 @@ class Tasks extends DolibarrApi } if( ! DolibarrApi::_checkAccessToResource('project',$this->project->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $request_data = (object) $request_data; @@ -451,7 +451,7 @@ class Tasks extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('task', $this->task->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach ($request_data as $field => $value) { if ($field == 'id') { @@ -459,11 +459,17 @@ class Tasks extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->task->context['caller'] = $request_data['caller']; + $this->task->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); + continue; + } + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->task->array_options[$index] = $this->_checkValForAPI($field, $val, $this->task);; + } continue; } - $this->task->$field = $value; + $this->task->$field = $this->_checkValForAPI($field, $value, $this->task); } if ($this->task->update(DolibarrApiAccess::$user) > 0) { @@ -491,7 +497,7 @@ class Tasks extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('task', $this->task->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if (!$this->task->delete(DolibarrApiAccess::$user)) { @@ -534,7 +540,7 @@ class Tasks extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('project', $this->task->fk_project)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $uid = $user_id; @@ -590,7 +596,7 @@ class Tasks extends DolibarrApi $this->timespentRecordChecks($id, $timespent_id); if (!DolibarrApi::_checkAccessToResource('task', $this->task->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $newdate = dol_stringtotime($date, 1); @@ -635,7 +641,7 @@ class Tasks extends DolibarrApi $this->timespentRecordChecks($id, $timespent_id); if (!DolibarrApi::_checkAccessToResource('task', $this->task->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if ($this->task->delTimeSpent(DolibarrApiAccess::$user, 0) < 0) { diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 779f4995f51..17a7ab6d654 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -406,8 +406,6 @@ class Project extends CommonObject */ public function create($user, $notrigger = 0) { - global $conf, $langs; - $error = 0; $ret = 0; diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 9b07083156d..c2834b649df 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -9,6 +9,7 @@ * Copyright (C) 2019 Juanjo Menent * Copyright (C) 2020 Tobias Sean * Copyright (C) 2024 MDW + * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -225,7 +226,7 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = dol_eval($val['visible'], 1, 1, '1'); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['p.'.$key] = array( 'label' => $val['label'], 'checked' => (($visible < 0) ? 0 : 1), @@ -1631,7 +1632,7 @@ while ($i < $imaxinloop) { $userstatic->lastname = $obj->lastname; $userstatic->firstname = $obj->firstname; $userstatic->email = $obj->user_email; - $userstatic->statut = $obj->user_statut; + $userstatic->status = $obj->user_statut; $userstatic->entity = $obj->entity; $userstatic->photo = $obj->photo; $userstatic->office_phone = $obj->office_phone; @@ -1724,7 +1725,7 @@ while ($i < $imaxinloop) { $userstatic->lastname = $val['lastname']; $userstatic->firstname = $val['firstname']; $userstatic->email = $val['email']; - $userstatic->statut = $val['statut']; + $userstatic->status = $val['statut']; $userstatic->entity = $val['entity']; $userstatic->photo = $val['photo']; $userstatic->login = $val['login']; diff --git a/htdocs/projet/tasks.php b/htdocs/projet/tasks.php index bc0f4463f95..a490a3c9d33 100644 --- a/htdocs/projet/tasks.php +++ b/htdocs/projet/tasks.php @@ -737,7 +737,7 @@ if ($action == 'create' && $user->hasRight('projet', 'creer') && (empty($object- print ''; } - print dol_get_fiche_head(''); + print dol_get_fiche_head(); print '
      '; print '
      '; diff --git a/htdocs/projet/tasks/contact.php b/htdocs/projet/tasks/contact.php index 015c70a72e2..77402f0e98c 100644 --- a/htdocs/projet/tasks/contact.php +++ b/htdocs/projet/tasks/contact.php @@ -2,6 +2,7 @@ /* Copyright (C) 2005 Rodolphe Quiedeville * Copyright (C) 2006-2015 Laurent Destailleur * Copyright (C) 2010-2012 Regis Houssin + * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -426,7 +427,7 @@ if ($id > 0 || !empty($ref)) { print ''; @@ -501,7 +502,7 @@ if ($id > 0 || !empty($ref)) { $userstatic->photo = $tab[$i]['photo']; $userstatic->login = $tab[$i]['login']; $userstatic->email = $tab[$i]['email']; - $userstatic->statut = $tab[$i]['statuscontact']; + $userstatic->status = $tab[$i]['statuscontact']; print $userstatic->getNomUrl(-1); } diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php index d4a51ee90f4..34be3bb5c3f 100644 --- a/htdocs/projet/tasks/list.php +++ b/htdocs/projet/tasks/list.php @@ -1127,7 +1127,7 @@ if (getDolGlobalString('PROJECT_TIMES_SPENT_FORMAT')) { // -------------------------------------------------------------------- $i = 0; $savnbfield = $totalarray['nbfield']; -$totalarray = array(); + $totalarray['nbfield'] = 0; $imaxinloop = ($limit ? min($num, $limit) : $num); while ($i < $imaxinloop) { diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index d36587339a1..b2bbf98186f 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -2338,7 +2338,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser // Product if (!empty($arrayfields['t.fk_product']['checked'])) { print '
      '; $thirdpartyofproject = $projectstatic->getListContactId('thirdparty'); - $selectedCompany = isset($_GET["newcompany"]) ? $_GET["newcompany"] : $projectstatic->socid; + $selectedCompany = GETPOSTISSET("newcompany") ? GETPOST("newcompany") : $projectstatic->socid; $selectedCompany = $formcompany->selectCompaniesForNewContact($object, 'id', $selectedCompany, 'newcompany', $thirdpartyofproject, 0, '&withproject='.$withproject); print ''; - if ($action == 'editline' && $_GET['lineid'] == $task_time->rowid) { + if ($action == 'editline' && GETPOSTINT('lineid') == $task_time->rowid) { print img_picto('', 'service'); print $form->select_produits($task_time->fk_product, 'fk_product', '1', 0, $projectstatic->thirdparty->price_level, 1, 2, '', 1, array(), $projectstatic->thirdparty->id, 'None', 0, 'maxwidth500', 0, '', null, 1); } elseif (!empty($task_time->fk_product)) { @@ -2395,7 +2395,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser if ($task_time->invoice_id) { $result = $tmpinvoice->fetch($task_time->invoice_id); if ($result > 0) { - if ($action == 'editline' && $_GET['lineid'] == $task_time->rowid) { + if ($action == 'editline' && GETPOSTINT('lineid') == $task_time->rowid) { print $formproject->selectInvoiceAndLine($task_time->invoice_id, $task_time->invoice_line_id, 'invoiceid', 'invoicelineid', 'maxwidth500', array('p.rowid' => $projectstatic->id)); } else { print $tmpinvoice->getNomUrl(1); diff --git a/htdocs/public/agenda/agendaexport.php b/htdocs/public/agenda/agendaexport.php index 484b3bab1d3..0aa90ef50ec 100644 --- a/htdocs/public/agenda/agendaexport.php +++ b/htdocs/public/agenda/agendaexport.php @@ -74,6 +74,7 @@ function llxFooterVierge() // For MultiCompany module. // Do not use GETPOST here, function is not defined and define must be done before including main.inc.php +// Because 2 entities can have the same ref $entity = (!empty($_GET['entity']) ? (int) $_GET['entity'] : (!empty($_POST['entity']) ? (int) $_POST['entity'] : 1)); if (is_numeric($entity)) { define("DOLENTITY", $entity); @@ -178,7 +179,7 @@ if ($reshook < 0) { llxFooterVierge(); } elseif (empty($reshook)) { // Check exportkey - if (empty($_GET["exportkey"]) || getDolGlobalString('MAIN_AGENDA_XCAL_EXPORTKEY') != $_GET["exportkey"]) { + if (!GETPOST("exportkey") || getDolGlobalString('MAIN_AGENDA_XCAL_EXPORTKEY') != GETPOST("exportkey")) { $user->getrights(); top_httphead(); @@ -328,13 +329,13 @@ if ($format == 'rss') { $result = $agenda->build_exportfile($format, $type, $cachedelay, $filename, $filters, $exportholidays); if ($result >= 0) { $attachment = false; - if (isset($_GET["attachment"])) { - $attachment = $_GET["attachment"]; + if (GETPOSTISSET("attachment")) { + $attachment = GETPOST("attachment"); } //$attachment = false; $contenttype = 'application/rss+xml'; - if (isset($_GET["contenttype"])) { - $contenttype = $_GET["contenttype"]; + if (GETPOSTISSET("contenttype")) { + $contenttype = GETPOST("contenttype"); } //$contenttype='text/plain'; $outputencoding = 'UTF-8'; diff --git a/htdocs/public/company/new.php b/htdocs/public/company/new.php index 289adc1020b..b6e84d2437b 100644 --- a/htdocs/public/company/new.php +++ b/htdocs/public/company/new.php @@ -8,6 +8,7 @@ * Copyright (C) 2018 Alexandre Spangaro * Copyright (C) 2021 Waël Almoman * Copyright (C) 2022 Udo Tamm + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -43,6 +44,7 @@ if (!defined('NOBROWSERNOTIF')) { // For MultiCompany module. // Do not use GETPOST here, function is not defined and define must be done before including main.inc.php +// Because 2 entities can have the same ref $entity = (!empty($_GET['entity']) ? (int) $_GET['entity'] : (!empty($_POST['entity']) ? (int) $_POST['entity'] : 1)); if (is_numeric($entity)) { define("DOLENTITY", $entity); @@ -202,7 +204,7 @@ if (empty($reshook) && $action == 'add') { // Check Captcha code if is enabled if (getDolGlobalString('MAIN_SECURITY_ENABLECAPTCHA')) { $sessionkey = 'dol_antispam_value'; - $ok = (array_key_exists($sessionkey, $_SESSION) === true && (strtolower($_SESSION[$sessionkey]) == strtolower($_POST['code']))); + $ok = (array_key_exists($sessionkey, $_SESSION) === true && (strtolower($_SESSION[$sessionkey]) == strtolower(GETPOST('code')))); if (!$ok) { $error++; $errmsg .= $langs->trans("ErrorBadValueForCode") . "
      \n"; @@ -327,7 +329,7 @@ $messagemandatory = '' . $langs->trans("FieldsWithAreMandatory", //print '
      '.$langs->trans("FieldsWithAreMandatory", '*').'
      '; //print $langs->trans("FieldsWithIsForPublic",'**').'
      '; -print dol_get_fiche_head(''); +print dol_get_fiche_head(); print ' diff --git a/htdocs/public/ticket/create_ticket.php b/htdocs/public/ticket/create_ticket.php index 1a482944772..f7c408c07ed 100644 --- a/htdocs/public/ticket/create_ticket.php +++ b/htdocs/public/ticket/create_ticket.php @@ -45,6 +45,7 @@ if (!defined('NOBROWSERNOTIF')) { // For MultiCompany module. // Do not use GETPOST here, function is not defined and define must be done before including main.inc.php +// Because 2 entities can have the same ref. $entity = (!empty($_GET['entity']) ? (int) $_GET['entity'] : (!empty($_POST['entity']) ? (int) $_POST['entity'] : 1)); if (is_numeric($entity)) { define("DOLENTITY", $entity); diff --git a/htdocs/public/ticket/index.php b/htdocs/public/ticket/index.php index 64a70c95c0d..860a82ec0ff 100644 --- a/htdocs/public/ticket/index.php +++ b/htdocs/public/ticket/index.php @@ -40,6 +40,7 @@ if (!defined('NOBROWSERNOTIF')) { // For MultiCompany module // Do not use GETPOST here, function is not defined and define must be done before including main.inc.php +// Because 2 entities can have the same ref. $entity = (!empty($_GET['entity']) ? (int) $_GET['entity'] : (!empty($_POST['entity']) ? (int) $_POST['entity'] : 1)); if (is_numeric($entity)) { define("DOLENTITY", $entity); diff --git a/htdocs/public/ticket/list.php b/htdocs/public/ticket/list.php index 1842af349b4..aa6687371a9 100644 --- a/htdocs/public/ticket/list.php +++ b/htdocs/public/ticket/list.php @@ -38,6 +38,7 @@ if (!defined('NOBROWSERNOTIF')) { // For MultiCompany module. // Do not use GETPOST here, function is not defined and define must be done before including main.inc.php +// Because 2 entities can have the same ref. $entity = (!empty($_GET['entity']) ? (int) $_GET['entity'] : (!empty($_POST['entity']) ? (int) $_POST['entity'] : 1)); if (is_numeric($entity)) { define("DOLENTITY", $entity); diff --git a/htdocs/public/ticket/view.php b/htdocs/public/ticket/view.php index a966813ca05..60a3c512969 100644 --- a/htdocs/public/ticket/view.php +++ b/htdocs/public/ticket/view.php @@ -40,6 +40,7 @@ if (!defined('NOBROWSERNOTIF')) { // For MultiCompany module. // Do not use GETPOST here, function is not defined and define must be done before including main.inc.php +// Because 2 entities can have the same ref. $entity = (!empty($_GET['entity']) ? (int) $_GET['entity'] : (!empty($_POST['entity']) ? (int) $_POST['entity'] : 1)); if (is_numeric($entity)) { define("DOLENTITY", $entity); diff --git a/htdocs/public/website/index.php b/htdocs/public/website/index.php index 29e389ae1bd..09d91111f63 100644 --- a/htdocs/public/website/index.php +++ b/htdocs/public/website/index.php @@ -81,6 +81,11 @@ $error = 0; $websitekey = GETPOST('website', 'alpha'); $pageid = GETPOST('page', 'alpha') ? GETPOST('page', 'alpha') : GETPOST('pageid', 'alpha'); $pageref = GETPOST('pageref', 'alphanohtml') ? GETPOST('pageref', 'alphanohtml') : ''; +// If page is xx/pagename, xx is a language, we set $pageref to pagename +$reg = array(); +if (preg_match('/^(\w\w)\/(.*)$/', $pageref, $reg)) { + $pageref = $reg[2]; +} $accessallowed = 1; $type = ''; diff --git a/htdocs/reception/card.php b/htdocs/reception/card.php index 5a831b445a7..1fceafab74e 100644 --- a/htdocs/reception/card.php +++ b/htdocs/reception/card.php @@ -450,7 +450,7 @@ if (empty($reshook)) { exit; } else { $db->rollback(); - $_GET["commande_id"] = GETPOSTINT('commande_id'); + //$_GET["commande_id"] = GETPOSTINT('commande_id'); $action = 'create'; } } elseif ($action == 'confirm_valid' && $confirm == 'yes' && $permissiontovalidate) { @@ -807,7 +807,7 @@ if ($action == 'create') { print ''; } - print dol_get_fiche_head(''); + print dol_get_fiche_head(); print ''; diff --git a/htdocs/reception/class/api_receptions.class.php b/htdocs/reception/class/api_receptions.class.php index e8a035c4049..e5f646cf407 100644 --- a/htdocs/reception/class/api_receptions.class.php +++ b/htdocs/reception/class/api_receptions.class.php @@ -73,7 +73,7 @@ class Receptions extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('reception', $this->reception->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->reception->fetchObjectLinked(); @@ -188,11 +188,11 @@ class Receptions extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->reception->context['caller'] = $request_data['caller']; + $this->reception->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->reception->$field = $value; + $this->reception->$field = $this->_checkValForAPI($field, $value, $this->reception); } if (isset($request_data["lines"])) { $lines = array(); @@ -231,7 +231,7 @@ class Receptions extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('reception',$this->reception->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->reception->getLinesArray(); $result = array(); @@ -265,7 +265,7 @@ class Receptions extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('reception',$this->reception->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $request_data = (object) $request_data; @@ -333,7 +333,7 @@ class Receptions extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('reception',$this->reception->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $request_data = (object) $request_data; @@ -398,7 +398,7 @@ class Receptions extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('reception', $this->reception->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } // TODO Check the lineid $lineid is a line of object @@ -435,7 +435,7 @@ class Receptions extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('reception', $this->reception->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach ($request_data as $field => $value) { if ($field == 'id') { @@ -443,11 +443,11 @@ class Receptions extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->reception->context['caller'] = $request_data['caller']; + $this->reception->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $this->reception->$field = $value; + $this->reception->$field = $this->_checkValForAPI($field, $value, $this->reception); } if ($this->reception->update(DolibarrApiAccess::$user) > 0) { @@ -474,7 +474,7 @@ class Receptions extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('reception', $this->reception->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if (!$this->reception->delete(DolibarrApiAccess::$user)) { @@ -519,7 +519,7 @@ class Receptions extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('reception', $this->reception->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->reception->valid(DolibarrApiAccess::$user, $notrigger); @@ -642,7 +642,7 @@ class Receptions extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('reception', $this->reception->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->reception->setClosed(); diff --git a/htdocs/reception/class/reception.class.php b/htdocs/reception/class/reception.class.php index a98b5f1c157..2b417854a61 100644 --- a/htdocs/reception/class/reception.class.php +++ b/htdocs/reception/class/reception.class.php @@ -125,11 +125,6 @@ class Reception extends CommonObject public $meths; public $listmeths; // List of carriers - /** - * @var ?CommandeFournisseur - */ - public $commandeFournisseur; - /** * @var CommandeFournisseurDispatch[] */ @@ -620,17 +615,17 @@ class Reception extends CommonObject } if (!$error) { - // Change status of order to "reception in process" or "totally received" + // Change status of purchase order to "reception in process" or "totally received" $status = $this->getStatusDispatch(); if ($status < 0) { $error++; } else { $trigger_key = ''; - if ($status == CommandeFournisseur::STATUS_RECEIVED_COMPLETELY) { - $ret = $this->commandeFournisseur->Livraison($user, dol_now(), 'tot', ''); + if ($this->origin_object instanceof CommandeFournisseur && $status == CommandeFournisseur::STATUS_RECEIVED_COMPLETELY) { + $ret = $this->origin_object->Livraison($user, dol_now(), 'tot', ''); if ($ret < 0) { $error++; - $this->errors = array_merge($this->errors, $this->commandeFournisseur->errors); + $this->errors = array_merge($this->errors, $this->origin_object->errors); } } else { $ret = $this->setStatut($status, $this->origin_id, 'commande_fournisseur', $trigger_key); @@ -767,8 +762,8 @@ class Reception extends CommonObject } } - // qty wished in order supplier (origin) - foreach ($this->commandeFournisseur->lines as $origin_line) { + // qty wished in origin (purchase order, ...) + foreach ($this->origin_object->lines as $origin_line) { // exclude lines not qualified for reception if (!getDolGlobalInt('STOCK_SUPPORTS_SERVICES') && $origin_line->product_type > 0) { continue; @@ -1448,9 +1443,8 @@ class Reception extends CommonObject $this->socid = 1; $this->origin_id = 1; - $this->origin = 'commande'; + $this->origin_type = 'supplier_order'; $this->origin_object = $order; - $this->commandeFournisseur = $order; // deprecated $this->note_private = 'Private note'; $this->note_public = 'Public note'; diff --git a/htdocs/reception/list.php b/htdocs/reception/list.php index 5721ff01232..64957fbfa5d 100644 --- a/htdocs/reception/list.php +++ b/htdocs/reception/list.php @@ -286,8 +286,8 @@ if (empty($reshook)) { } // try to get from source of reception (supplier order) - if (!empty($rcp->commandeFournisseur)) { - $supplierOrder = $rcp->commandeFournisseur; + if (!empty($rcp->origin_object)) { + $supplierOrder = $rcp->origin_object; if (empty($cond_reglement_id) && !empty($supplierOrder->cond_reglement_id)) { $cond_reglement_id = $supplierOrder->cond_reglement_id; } @@ -487,7 +487,7 @@ if (empty($reshook)) { $product_type, $rang, false, - 0, + array(), null, $lines[$i]->rowid, 0, @@ -571,8 +571,8 @@ if (empty($reshook)) { $db->rollback(); $action = 'create'; - $_GET["origin"] = $_POST["origin"]; - $_GET["originid"] = $_POST["originid"]; + $_GET["origin"] = $_POST["origin"]; // Keep this ? + $_GET["originid"] = $_POST["originid"]; // Keep this ? setEventMessages($object->error, $errors, 'errors'); $error++; } diff --git a/htdocs/recruitment/class/api_recruitments.class.php b/htdocs/recruitment/class/api_recruitments.class.php index 030c9c81e69..59f9c7e2df0 100644 --- a/htdocs/recruitment/class/api_recruitments.class.php +++ b/htdocs/recruitment/class/api_recruitments.class.php @@ -329,7 +329,7 @@ class Recruitments extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->jobposition->context['caller'] = $request_data['caller']; + $this->jobposition->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } @@ -367,7 +367,7 @@ class Recruitments extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->jobposition->context['caller'] = $request_data['caller']; + $this->jobposition->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } @@ -415,7 +415,7 @@ class Recruitments extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->jobposition->context['caller'] = $request_data['caller']; + $this->jobposition->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } @@ -464,7 +464,7 @@ class Recruitments extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->candidature->context['caller'] = $request_data['caller']; + $this->candidature->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } diff --git a/htdocs/resource/card.php b/htdocs/resource/card.php index 6b2063fe5a6..318a1496f6c 100644 --- a/htdocs/resource/card.php +++ b/htdocs/resource/card.php @@ -1,6 +1,7 @@ * Copyright (C) 2023-2024 William Mead + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -79,7 +80,7 @@ $permissiontodelete = $user->hasRight('resource', 'delete'); */ $hookmanager->initHooks(array('resource', 'resource_card', 'globalcard')); -$parameters = array('resource_id'=>$id); +$parameters = array('resource_id' => $id); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) { setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); @@ -224,7 +225,7 @@ $formresource = new FormResource($db); if ($action == 'create' || $object->fetch($id, $ref) > 0) { if ($action == 'create') { print load_fiche_titre($title, '', 'object_resource'); - print dol_get_fiche_head(''); + print dol_get_fiche_head(); } else { $head = resource_prepare_head($object); print dol_get_fiche_head($head, 'resource', $title, -1, 'resource'); @@ -256,13 +257,13 @@ if ($action == 'create' || $object->fetch($id, $ref) > 0) { print ''; // Zip / Town - print 'browser->layout == 'phone' ? ' colspan="3"': '').'>'; + print 'browser->layout == 'phone' ? ' colspan="3"' : '').'>'; print $formresource->select_ziptown($object->zip, 'zipcode', array('town', 'selectcountry_id', 'state_id'), 0, 0, '', 'maxwidth100'); print ''; if ($conf->browser->layout == 'phone') { print ''; } - print 'browser->layout == 'phone' ? ' colspan="3"': '').'>'; + print 'browser->layout == 'phone' ? ' colspan="3"' : '').'>'; print $formresource->select_ziptown($object->town, 'town', array('zipcode', 'selectcountry_id', 'state_id')); print $form->widgetForTranslation("town", $object, $permissiontoadd, 'string', 'alphanohtml', 'maxwidth100 quatrevingtpercent'); print ''; diff --git a/htdocs/resource/class/dolresource.class.php b/htdocs/resource/class/dolresource.class.php index a1ab7ab07f7..36b6dfd78d0 100644 --- a/htdocs/resource/class/dolresource.class.php +++ b/htdocs/resource/class/dolresource.class.php @@ -128,7 +128,7 @@ class Dolresource extends CommonObject public $cache_code_type_resource; /** - * @var Dolresource Clone of object before changing it + * @var static Clone of object before changing it */ public $oldcopy; diff --git a/htdocs/salaries/card.php b/htdocs/salaries/card.php index 4e7024d83c2..03f8eb68c67 100644 --- a/htdocs/salaries/card.php +++ b/htdocs/salaries/card.php @@ -561,7 +561,7 @@ if ($action == 'create' && $permissiontoadd) { print ''."\n"; } - print dol_get_fiche_head(''); + print dol_get_fiche_head(); print '
      '.$form->editfieldkey('Zip', 'zipcode', '', $object, 0).'
      '.$form->editfieldkey('Zip', 'zipcode', '', $object, 0).'
      '.$form->editfieldkey('Town', 'town', '', $object, 0).''.$form->editfieldkey('Town', 'town', '', $object, 0).'
      '; diff --git a/htdocs/salaries/virement_request.php b/htdocs/salaries/virement_request.php index 2c9b444655e..e4aeb57fd4f 100644 --- a/htdocs/salaries/virement_request.php +++ b/htdocs/salaries/virement_request.php @@ -3,6 +3,7 @@ * Copyright (C) 2015 Charlie BENKE * Copyright (C) 2017-2019 Alexandre Spangaro * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -117,7 +118,7 @@ if ($type == 'bank-transfer') { // Load object if ($id > 0 || !empty($ref)) { $ret = $object->fetch($id, $ref); - $isdraft = (($obj->statut == FactureFournisseur::STATUS_DRAFT) ? 1 : 0); + $isdraft = (($obj->status == FactureFournisseur::STATUS_DRAFT) ? 1 : 0); if ($ret > 0) { $object->fetch_thirdparty(); } @@ -346,21 +347,21 @@ print '
      '; /* * Payments */ - $sql = "SELECT p.rowid, p.num_payment as num_payment, p.datep as dp, p.amount,"; - $sql .= " c.code as type_code,c.libelle as paiement_type,"; - $sql .= ' ba.rowid as baid, ba.ref as baref, ba.label, ba.number as banumber, ba.account_number, ba.currency_code as bacurrency_code, ba.fk_accountancy_journal'; - $sql .= " FROM ".MAIN_DB_PREFIX."payment_salary as p"; - $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid'; - $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid'; - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as c ON p.fk_typepayment = c.id"; - $sql .= ", ".MAIN_DB_PREFIX."salary as s"; - $sql .= " WHERE p.fk_salary = ".((int) $id); - $sql .= " AND p.fk_salary = s.rowid"; - $sql .= " AND s.entity IN (".getEntity('tax').")"; - $sql .= " ORDER BY dp DESC"; +$sql = "SELECT p.rowid, p.num_payment as num_payment, p.datep as dp, p.amount,"; +$sql .= " c.code as type_code,c.libelle as paiement_type,"; +$sql .= ' ba.rowid as baid, ba.ref as baref, ba.label, ba.number as banumber, ba.account_number, ba.currency_code as bacurrency_code, ba.fk_accountancy_journal'; +$sql .= " FROM ".MAIN_DB_PREFIX."payment_salary as p"; +$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid'; +$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid'; +$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as c ON p.fk_typepayment = c.id"; +$sql .= ", ".MAIN_DB_PREFIX."salary as s"; +$sql .= " WHERE p.fk_salary = ".((int) $id); +$sql .= " AND p.fk_salary = s.rowid"; +$sql .= " AND s.entity IN (".getEntity('tax').")"; +$sql .= " ORDER BY dp DESC"; - //print $sql; - $resql = $db->query($sql); +//print $sql; +$resql = $db->query($sql); if ($resql) { $totalpaid = 0; @@ -450,23 +451,23 @@ print dol_get_fiche_end(); print '
      '."\n"; $sql = "SELECT pfd.rowid, pfd.traite, pfd.date_demande as date_demande,"; - $sql .= " pfd.date_traite as date_traite, pfd.amount, pfd.fk_prelevement_bons,"; - $sql .= " pb.ref, pb.date_trans, pb.method_trans, pb.credite, pb.date_credit, pb.datec, pb.statut as status, pb.amount as pb_amount,"; - $sql .= " u.rowid as user_id, u.email, u.lastname, u.firstname, u.login, u.statut as user_status"; - $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as pfd"; - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on pfd.fk_user_demande = u.rowid"; - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."prelevement_bons as pb ON pb.rowid = pfd.fk_prelevement_bons"; +$sql .= " pfd.date_traite as date_traite, pfd.amount, pfd.fk_prelevement_bons,"; +$sql .= " pb.ref, pb.date_trans, pb.method_trans, pb.credite, pb.date_credit, pb.datec, pb.statut as status, pb.amount as pb_amount,"; +$sql .= " u.rowid as user_id, u.email, u.lastname, u.firstname, u.login, u.statut as user_status"; +$sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as pfd"; +$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on pfd.fk_user_demande = u.rowid"; +$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."prelevement_bons as pb ON pb.rowid = pfd.fk_prelevement_bons"; if ($type == 'salaire') { $sql .= " WHERE pfd.fk_salary = ".((int) $object->id); } else { $sql .= " WHERE fk_facture = ".((int) $object->id); } - $sql .= " AND pfd.traite = 0"; - $sql .= " AND pfd.type = 'ban'"; - $sql .= " ORDER BY pfd.date_demande DESC"; - $resql = $db->query($sql); +$sql .= " AND pfd.traite = 0"; +$sql .= " AND pfd.type = 'ban'"; +$sql .= " ORDER BY pfd.date_demande DESC"; +$resql = $db->query($sql); - $hadRequest = $db->num_rows($resql); +$hadRequest = $db->num_rows($resql); if ($object->paye == 0 && $hadRequest == 0) { if ($resteapayer > 0) { if ($user_perms) { @@ -528,31 +529,31 @@ $bprev = new BonPrelevement($db); * Withdrawals */ - print '
      '; - print '
      '; +print '
      '; +print '
      '; - print ''; - // Action column +print ''; +// Action column if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { print ''; } - print ''; - print ''; - print ''; - print ''; +print ''; +print ''; +print ''; +print ''; if ($type == 'bank-transfer') { print ''; } else { print ''; } - print ''; - // Action column +print ''; +// Action column if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { print ''; } - print ''; +print ''; - $num = 0; +$num = 0; if ($resql) { $i = 0; @@ -653,25 +654,25 @@ if ($resql) { dol_print_error($db); } - // Past requests when bon prelevement +// Past requests when bon prelevement - $sql = "SELECT pfd.rowid, pfd.traite, pfd.date_demande as date_demande,"; - $sql .= " pfd.date_traite as date_traite, pfd.amount, pfd.fk_prelevement_bons,"; - $sql .= " pb.ref, pb.date_trans, pb.method_trans, pb.credite, pb.date_credit, pb.datec, pb.statut as status, pb.amount as pb_amount,"; - $sql .= " u.rowid as user_id, u.email, u.lastname, u.firstname, u.login, u.statut as user_status"; - $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as pfd"; - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on pfd.fk_user_demande = u.rowid"; - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."prelevement_bons as pb ON pb.rowid = pfd.fk_prelevement_bons"; +$sql = "SELECT pfd.rowid, pfd.traite, pfd.date_demande as date_demande,"; +$sql .= " pfd.date_traite as date_traite, pfd.amount, pfd.fk_prelevement_bons,"; +$sql .= " pb.ref, pb.date_trans, pb.method_trans, pb.credite, pb.date_credit, pb.datec, pb.statut as status, pb.amount as pb_amount,"; +$sql .= " u.rowid as user_id, u.email, u.lastname, u.firstname, u.login, u.statut as user_status"; +$sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as pfd"; +$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on pfd.fk_user_demande = u.rowid"; +$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."prelevement_bons as pb ON pb.rowid = pfd.fk_prelevement_bons"; if ($type == 'salaire') { $sql .= " WHERE pfd.fk_salary = ".((int) $object->id); } else { $sql .= " WHERE fk_facture = ".((int) $object->id); } - $sql .= " AND pfd.traite = 1"; - $sql .= " AND pfd.type = 'ban'"; - $sql .= " ORDER BY pfd.date_demande DESC"; +$sql .= " AND pfd.traite = 1"; +$sql .= " AND pfd.type = 'ban'"; +$sql .= " ORDER BY pfd.date_demande DESC"; - $resql = $db->query($sql); +$resql = $db->query($sql); if ($resql) { $numOfBp = $db->num_rows($resql); $i = 0; @@ -766,8 +767,8 @@ if ($num == 0 && $numOfBp == 0) { print ''; } - print "
       '.$langs->trans("DateRequest").''.$langs->trans("User").''.$langs->trans("Amount").''.$langs->trans("DateProcess").''.$langs->trans("DateRequest").''.$langs->trans("User").''.$langs->trans("Amount").''.$langs->trans("DateProcess").''.$langs->trans("BankTransferReceipt").''.$langs->trans("WithdrawalReceipt").'   
      '.$langs->trans("None").'
      "; - print ''; +print "
      "; +print '
      '; // End of page llxFooter(); diff --git a/htdocs/societe/ajax/company.php b/htdocs/societe/ajax/company.php index db97f1aa138..e0c5e1fe42d 100644 --- a/htdocs/societe/ajax/company.php +++ b/htdocs/societe/ajax/company.php @@ -2,6 +2,7 @@ /* Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2007-2019 Laurent Destailleur + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -49,8 +50,8 @@ $outjson = (GETPOSTINT('outjson') ? GETPOSTINT('outjson') : 0); $action = GETPOST('action', 'aZ09'); $id = GETPOSTINT('id'); $excludeids = GETPOST('excludeids', 'intcomma'); -$showtype = GETPOSTINT('showtype', 'alpha'); -$showcode = GETPOSTINT('showcode', 'alpha'); +$showtype = GETPOSTINT('showtype'); +$showcode = GETPOSTINT('showcode'); $object = new Societe($db); if ($id > 0) { @@ -73,7 +74,6 @@ restrictedArea($user, 'societe', $object->id, '&societe'); top_httphead('application/json'); //print ''."\n"; -//print_r($_GET); if (!empty($action) && $action == 'fetch' && !empty($id)) { require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; diff --git a/htdocs/societe/canvas/actions_card_common.class.php b/htdocs/societe/canvas/actions_card_common.class.php index 5125bfdc389..42820ce8369 100644 --- a/htdocs/societe/canvas/actions_card_common.class.php +++ b/htdocs/societe/canvas/actions_card_common.class.php @@ -93,19 +93,19 @@ abstract class ActionsCardCommon $this->assign_post($action); } - if ($_GET["type"] == 'f') { + if (GETPOST("type") == 'f') { $this->object->fournisseur = 1; } - if ($_GET["type"] == 'c') { + if (GETPOST("type") == 'c') { $this->object->client = 1; } - if ($_GET["type"] == 'p') { + if (GETPOST("type") == 'p') { $this->object->client = 2; } - if ($_GET["type"] == 'cp') { + if (GETPOST("type") == 'cp') { $this->object->client = 3; } - if ($_REQUEST["private"] == 1) { + if (GETPOST("private") == 1) { $this->object->particulier = 1; } diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 39cbc75b199..722e21c5cd0 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -1213,7 +1213,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($canvasdisplayactio print ''; } - print dol_get_fiche_head(null, 'card', '', 0, ''); + print dol_get_fiche_head(array(), 'card', '', 0, ''); // Call Hook tabContentCreateThirdparty $parameters = array(); diff --git a/htdocs/societe/class/api_contacts.class.php b/htdocs/societe/class/api_contacts.class.php index db6e2158e1f..4ff0235e74f 100644 --- a/htdocs/societe/class/api_contacts.class.php +++ b/htdocs/societe/class/api_contacts.class.php @@ -87,7 +87,7 @@ class Contacts extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('contact', $this->contact->id, 'socpeople&societe')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if ($includecount) { @@ -135,7 +135,7 @@ class Contacts extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('contact', $this->contact->id, 'socpeople&societe')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if ($includecount) { @@ -288,12 +288,12 @@ class Contacts extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->contact->context['caller'] = $request_data['caller']; + $this->contact->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } if ($field == 'array_options' && is_array($value)) { foreach ($value as $index => $val) { - $this->contact->array_options[$index] = $val; + $this->contact->array_options[$index] = $this->_checkValForAPI('extrafields', $val, $this->contact); } continue; } @@ -328,7 +328,7 @@ class Contacts extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('contact', $this->contact->id, 'socpeople&societe')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach ($request_data as $field => $value) { @@ -337,12 +337,12 @@ class Contacts extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->contact->context['caller'] = $request_data['caller']; + $this->contact->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } if ($field == 'array_options' && is_array($value)) { foreach ($value as $index => $val) { - $this->contact->array_options[$index] = $val; + $this->contact->array_options[$index] = $this->_checkValForAPI('extrafields', $val, $this->contact); } continue; } @@ -378,7 +378,7 @@ class Contacts extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('contact', $this->contact->id, 'socpeople&societe')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->contact->oldcopy = clone $this->contact; return $this->contact->delete(DolibarrApiAccess::$user); @@ -498,10 +498,10 @@ class Contacts extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('contact', $this->contact->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if (!DolibarrApi::_checkAccessToResource('category', $category->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $category->add_type($this->contact, 'contact'); @@ -538,10 +538,10 @@ class Contacts extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('contact', $this->contact->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if (!DolibarrApi::_checkAccessToResource('category', $category->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $category->del_type($this->contact, 'contact'); diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php index 1735efc4f7f..15cbe1d4d1f 100644 --- a/htdocs/societe/class/api_thirdparties.class.php +++ b/htdocs/societe/class/api_thirdparties.class.php @@ -256,7 +256,7 @@ class Thirdparties extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->company->context['caller'] = $request_data['caller']; + $this->company->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } @@ -292,7 +292,7 @@ class Thirdparties extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach ($request_data as $field => $value) { @@ -301,7 +301,7 @@ class Thirdparties extends DolibarrApi } if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->company->context['caller'] = $request_data['caller']; + $this->company->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } @@ -349,7 +349,7 @@ class Thirdparties extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $companytoremove = new Societe($this->db); @@ -359,7 +359,7 @@ class Thirdparties extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('societe', $companytoremove->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $user = DolibarrApiAccess::$user; @@ -387,7 +387,7 @@ class Thirdparties extends DolibarrApi throw new RestException(404, 'Thirdparty not found'); } if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->company->oldcopy = clone $this->company; @@ -493,7 +493,7 @@ class Thirdparties extends DolibarrApi throw new RestException(404, 'User not found'); } if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->company->add_commercial(DolibarrApiAccess::$user, $representative_id); @@ -527,7 +527,7 @@ class Thirdparties extends DolibarrApi throw new RestException(404, 'User not found'); } if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->company->del_commercial(DolibarrApiAccess::$user, $representative_id); @@ -598,10 +598,10 @@ class Thirdparties extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if (!DolibarrApi::_checkAccessToResource('category', $category->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $category->add_type($this->company, 'customer'); @@ -636,10 +636,10 @@ class Thirdparties extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if (!DolibarrApi::_checkAccessToResource('category', $category->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $category->del_type($this->company, 'customer'); @@ -713,10 +713,10 @@ class Thirdparties extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if (!DolibarrApi::_checkAccessToResource('category', $category->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $category->add_type($this->company, 'supplier'); @@ -751,10 +751,10 @@ class Thirdparties extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } if (!DolibarrApi::_checkAccessToResource('category', $category->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $category->del_type($this->company, 'supplier'); @@ -788,7 +788,7 @@ class Thirdparties extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('societe', $id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->company->fetch($id); @@ -830,7 +830,7 @@ class Thirdparties extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('societe', $id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->company->fetch($id); @@ -871,7 +871,7 @@ class Thirdparties extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('societe', $id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->company->fetch($id); @@ -912,7 +912,7 @@ class Thirdparties extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('societe', $id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->company->fetch($id); @@ -955,7 +955,7 @@ class Thirdparties extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('societe', $id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $result = $this->company->fetch($id); @@ -1014,7 +1014,7 @@ class Thirdparties extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('societe', $id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } /*$result = $this->thirdparty->fetch($id); @@ -1057,7 +1057,7 @@ class Thirdparties extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('societe', $id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } /*$result = $this->thirdparty->fetch($id); @@ -1265,7 +1265,7 @@ class Thirdparties extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('societe', $id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } /** @@ -1345,11 +1345,11 @@ class Thirdparties extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $this->company->context['caller'] = $request_data['caller']; + $this->company->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $account->$field = $value; + $account->$field = $this->_checkValForAPI('extrafields', $value, $account); } if ($account->create(DolibarrApiAccess::$user) < 0) { @@ -1402,11 +1402,11 @@ class Thirdparties extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $account->context['caller'] = $request_data['caller']; + $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $account->$field = $value; + $account->$field = $this->_checkValForAPI($field, $value, $account); } if (empty($account->rum)) { @@ -1562,7 +1562,7 @@ class Thirdparties extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('societe', $id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } /** @@ -1654,11 +1654,11 @@ class Thirdparties extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $account->context['caller'] = $request_data['caller']; + $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $account->$field = $value; + $account->$field = $this->_checkValForAPI($field, $value, $account); } if ($account->create(DolibarrApiAccess::$user) < 0) { @@ -1717,11 +1717,11 @@ class Thirdparties extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $account->context['caller'] = $request_data['caller']; + $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $account->$field = $value; + $account->$field = $this->_checkValForAPI($field, $value, $account); } $account->fk_soc = $id; @@ -1756,11 +1756,11 @@ class Thirdparties extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $account->context['caller'] = $request_data['caller']; + $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $account->$field = $value; + $account->$field = $this->_checkValForAPI($field, $value, $account); } if ($account->update(DolibarrApiAccess::$user) < 0) { @@ -1818,11 +1818,11 @@ class Thirdparties extends DolibarrApi foreach ($request_data as $field => $value) { if ($field === 'caller') { // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller - $account->context['caller'] = $request_data['caller']; + $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09'); continue; } - $account->$field = $value; + $account->$field = $this->_checkValForAPI($field, $value, $account); } if ($account->update(DolibarrApiAccess::$user) < 0) { @@ -2003,7 +2003,7 @@ class Thirdparties extends DolibarrApi global $conf; if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login.'. No read permission on thirdparties.'); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login.'. No read permission on thirdparties.'); } if ($rowid === 0) { @@ -2016,7 +2016,7 @@ class Thirdparties extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login.' on this thirdparty'); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login.' on this thirdparty'); } if (isModEnabled('mailing')) { $this->company->getNoEmail(); diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 4723d7085bd..aecf5211359 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -145,7 +145,7 @@ class Societe extends CommonObject public $restrictiononfksoc = 1; /** - * @var Societe To store a cloned copy of object before to edit it and keep track of old properties + * @var static To store a cloned copy of object before to edit it and keep track of old properties */ public $oldcopy; @@ -2498,11 +2498,11 @@ class Societe extends CommonObject /** * Returns amount of included taxes of the current discounts/credits available from the company * - * @param ?User $user Filter on a user author of discounts - * @param string $filter Other filter - * @param integer $maxvalue Filter on max value for discount - * @param int $discount_type 0 => customer discount, 1 => supplier discount - * @return int Return integer <0 if KO, Credit note amount otherwise + * @param ?User $user Filter on a user author of discounts + * @param string $filter Other filter + * @param int $maxvalue Filter on max value for discount + * @param int<0,1> $discount_type 0 => customer discount, 1 => supplier discount + * @return float|int<-1,-1> Return integer <0 if KO, Credit note amount otherwise */ public function getAvailableDiscounts($user = null, $filter = '', $maxvalue = 0, $discount_type = 0) { diff --git a/htdocs/societe/index.php b/htdocs/societe/index.php index 3f008867bd3..f2b5fd2b824 100644 --- a/htdocs/societe/index.php +++ b/htdocs/societe/index.php @@ -30,6 +30,7 @@ // Load Dolibarr environment require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; +require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; @@ -42,7 +43,6 @@ $hookmanager = new HookManager($db); $hookmanager->initHooks(array('thirdpartiesindex')); - $socid = GETPOSTINT('socid'); if ($user->socid) { $socid = $user->socid; @@ -52,6 +52,7 @@ if ($user->socid) { $result = restrictedArea($user, 'societe', 0, '', '', '', ''); $thirdparty_static = new Societe($db); +$contact_static = new Contact($db); if (!isset($form) || !is_object($form)) { $form = new Form($db); @@ -73,6 +74,8 @@ if (GETPOST('addbox')) { } } +$max = getDolGlobalInt('MAIN_SIZE_SHORTLIST_LIMIT'); + /* * View @@ -86,9 +89,7 @@ llxHeader("", $langs->trans("ThirdParties"), $helpurl); print load_fiche_titre($transAreaType, $resultboxes['selectboxlist'], 'companies'); -/* - * Statistics area - */ +// Statistics area $third = array( 'customer' => 0, @@ -276,7 +277,6 @@ if (isModEnabled('category') && getDolGlobalString('CATEGORY_GRAPHSTATS_ON_THIRD /* * Latest modified third parties */ -$max = 15; $sql = "SELECT s.rowid, s.nom as name, s.email, s.client, s.fournisseur"; $sql .= ", s.code_client"; $sql .= ", s.code_fournisseur"; @@ -294,6 +294,7 @@ $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) { $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe_perentity as spe ON spe.fk_soc = s.rowid AND spe.entity = " . ((int) $conf->entity); } +// TODO Replace this if (!$user->hasRight('societe', 'client', 'voir')) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } @@ -333,7 +334,7 @@ if ($result) { $lastmodified .= ''.$transRecordedType.''; $lastmodified .= ' '; - $lastmodified .= ''.$langs->trans("FullList").''; + $lastmodified .= ''.img_picto($langs->trans("FullList"), 'company').''; $lastmodified .= ''."\n"; while ($i < $num) { @@ -384,7 +385,132 @@ if ($result) { dol_print_error($db); } -//print '
      '; + + +/* + * Latest modified contacts + */ +$sql = "SELECT s.rowid, s.nom as name, s.email, s.client, s.fournisseur"; +$sql .= ", s.code_client"; +$sql .= ", s.code_fournisseur"; +if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) { + $sql .= ", spe.accountancy_code_supplier as code_compta_fournisseur"; + $sql .= ", spe.accountancy_code_customer as code_compta"; +} else { + $sql .= ", s.code_compta_fournisseur"; + $sql .= ", s.code_compta"; +} +$sql .= ", s.logo"; +$sql .= ", s.entity"; +$sql .= ", s.canvas"; +$sql .= ", s.tms as date_modification, s.status as status"; +$sql .= ", sp.rowid as cid, sp.canvas as ccanvas, sp.email as cemail, sp.firstname, sp.lastname"; +$sql .= ", sp.address as caddress, sp.phone as cphone"; +$sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."socpeople as sp"; +if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) { + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe_perentity as spe ON spe.fk_soc = s.rowid AND spe.entity = " . ((int) $conf->entity); +} +// TODO Replace this +if (!$user->hasRight('societe', 'client', 'voir')) { + $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; +} +$sql .= ' WHERE s.entity IN ('.getEntity('societe').') AND sp.fk_soc = s.rowid'; +if (!$user->hasRight('societe', 'client', 'voir')) { + $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); +} +if (!$user->hasRight('fournisseur', 'lire')) { + $sql .= " AND (s.fournisseur != 1 OR s.client != 0)"; +} +// Add where from hooks +$parameters = array('socid' => $socid); +$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $thirdparty_static); // Note that $action and $object may have been modified by hook +if (empty($reshook)) { + if ($socid > 0) { + $sql .= " AND s.rowid = ".((int) $socid); + } +} +$sql .= $hookmanager->resPrint; +$sql .= $db->order("s.tms", "DESC"); +$sql .= $db->plimit($max, 0); + +//print $sql; +$lastmodifiedcontact = ''; +$result = $db->query($sql); +if ($result) { + $num = $db->num_rows($result); + + $i = 0; + + if ($num > 0) { + $transRecordedType = $langs->trans("LastModifiedContacts", $max); + + $lastmodifiedcontact = "\n\n"; + $lastmodifiedcontact .= '
      '; + $lastmodifiedcontact .= ''; + + $lastmodifiedcontact .= ''; + $lastmodifiedcontact .= ''; + $lastmodifiedcontact .= ''; + $lastmodifiedcontact .= ''."\n"; + + while ($i < $num) { + $objp = $db->fetch_object($result); + + $thirdparty_static->id = $objp->rowid; + $thirdparty_static->name = $objp->name; + $thirdparty_static->client = $objp->client; + $thirdparty_static->fournisseur = $objp->fournisseur; + $thirdparty_static->logo = $objp->logo; + $thirdparty_static->date_modification = $db->jdate($objp->date_modification); + $thirdparty_static->status = $objp->status; + $thirdparty_static->code_client = $objp->code_client; + $thirdparty_static->code_fournisseur = $objp->code_fournisseur; + $thirdparty_static->canvas = $objp->canvas; + $thirdparty_static->email = $objp->email; + $thirdparty_static->entity = $objp->entity; + $thirdparty_static->code_compta_fournisseur = $objp->code_compta_fournisseur; + $thirdparty_static->code_compta = $objp->code_compta; + $thirdparty_static->code_compta_client = $objp->code_compta; + + $contact_static->id = $objp->cid; + $contact_static->firstname = $objp->firstname; + $contact_static->lastname = $objp->lastname; + $contact_static->email = $objp->cemail; + $contact_static->socid = $objp->rowid; + $contact_static->canvas = $objp->ccanvas; + $contact_static->phone_pro = $objp->cphone; + $contact_static->address = $objp->caddress; + + $lastmodifiedcontact .= ''; + // Name + $lastmodifiedcontact .= '\n"; + // Contact + $lastmodifiedcontact .= ''; + // Last modified date + $lastmodifiedcontact .= '"; + $lastmodifiedcontact .= '"; + $lastmodifiedcontact .= "\n"; + $i++; + } + + $db->free($result); + + $lastmodifiedcontact .= "
      '.$transRecordedType.' '.img_picto($langs->trans("FullList"), 'contact').'
      '; + $lastmodifiedcontact .= $thirdparty_static->getNomUrl(1); + $lastmodifiedcontact .= "'; + $lastmodifiedcontact .= $contact_static->getNomUrl(1); + $lastmodifiedcontact .= 'date_modification, 'dayhour', 'tzuserrel')).'">'; + $lastmodifiedcontact .= dol_print_date($thirdparty_static->date_modification, 'day', 'tzuserrel'); + $lastmodifiedcontact .= "'; + $lastmodifiedcontact .= $thirdparty_static->getLibStatut(3); + $lastmodifiedcontact .= "
      \n"; + $lastmodifiedcontact .= '
      '; + $lastmodifiedcontact .= "\n"; + } +} else { + dol_print_error($db); +} + // boxes print '
      '; @@ -403,6 +529,8 @@ $boxlist .= ''."\n"; $boxlist .= '
      '; $boxlist .= $lastmodified; $boxlist .= '
      '; +$boxlist .= $lastmodifiedcontact; +$boxlist .= '
      '; $boxlist .= $resultboxes['boxlistb']; $boxlist .= '
      '."\n"; diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index 73fdb35e5af..25cdc5a0ec4 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -203,7 +203,6 @@ if ($type == 'f') { $search_type = '4'; } } - // Initialize technical objects to manage hooks of page. Note that conf->hooks_modules contains array of hook context $object = new Societe($db); $extrafields = new ExtraFields($db); @@ -1106,7 +1105,9 @@ if ($user->hasRight("societe", "creer")) { } if ($user->hasRight("societe", "creer")) { $arrayofmassactions['presetcommercial'] = img_picto('', 'user', 'class="pictofixedwidth"').$langs->trans("AllocateCommercial"); + $arrayofmassactions['unsetcommercial'] = img_picto('', 'user', 'class="pictofixedwidth"').$langs->trans("UnallocateCommercial"); } + if ($user->hasRight('societe', 'supprimer')) { $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); } @@ -1198,6 +1199,7 @@ $objecttmp = new Societe($db); $trackid = 'thi'.$object->id; include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; +/* if (!empty($search_categ_cus) || !empty($search_categ_sup)) { print "
      "; $c = new Categorie($db); @@ -1205,6 +1207,7 @@ if (!empty($search_categ_cus) || !empty($search_categ_sup)) { print " > ".$ways[0]."
      \n"; print "

      "; } +*/ if ($search_all) { $setupstring = ''; diff --git a/htdocs/stripe/admin/stripe.php b/htdocs/stripe/admin/stripe.php index 919e80088c6..a62cdadb471 100644 --- a/htdocs/stripe/admin/stripe.php +++ b/htdocs/stripe/admin/stripe.php @@ -474,7 +474,6 @@ if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { // TODO Not used by current c $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); print $form->selectarray("STRIPE_KLARNA", $arrval, $conf->global->STRIPE_KLARNA); } - print '   '.$langs->trans("ExampleOnlyForKlarnaCustomers").''; print ''; } diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index 0d5e20a7049..c3846425458 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -358,8 +358,8 @@ if (empty($reshook)) { // Possibility to add external linked objects with hooks $object->linked_objects [$object->origin] = $object->origin_id; - if (is_array($_POST['other_linked_objects']) && !empty($_POST['other_linked_objects'])) { - $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']); + if (GETPOSTISARRAY('other_linked_objects')) { + $object->linked_objects = array_merge($object->linked_objects, GETPOST('other_linked_objects', 'array:int')); } $id = $object->create($user); diff --git a/htdocs/supplier_proposal/class/api_supplier_proposals.class.php b/htdocs/supplier_proposal/class/api_supplier_proposals.class.php index bde171e7d68..89a8ebb965b 100644 --- a/htdocs/supplier_proposal/class/api_supplier_proposals.class.php +++ b/htdocs/supplier_proposal/class/api_supplier_proposals.class.php @@ -51,6 +51,38 @@ class SupplierProposals extends DolibarrApi $this->supplier_proposal = new SupplierProposal($this->db); } + /** + * Delete commercial proposal + * + * @param int $id Supplier proposal ID + * @return array + */ + public function delete($id) + { + if (!DolibarrApiAccess::$user->hasRight('supplier_proposal', 'supprimer')) { + throw new RestException(403); + } + $result = $this->supplier_proposal->fetch($id); + if (!$result) { + throw new RestException(404, 'Supplier Proposal not found'); + } + + if (!DolibarrApi::_checkAccessToResource('supplier_proposal', $this->supplier_proposal->id)) { + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + if (!$this->supplier_proposal->delete(DolibarrApiAccess::$user)) { + throw new RestException(500, 'Error when delete Supplier Proposal : '.$this->supplier_proposal->error); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Supplier Proposal deleted' + ) + ); + } + /** * Get properties of a supplier proposal (price request) object * @@ -73,13 +105,106 @@ class SupplierProposals extends DolibarrApi } if (!DolibarrApi::_checkAccessToResource('supplier_proposal', $this->supplier_proposal->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } $this->supplier_proposal->fetchObjectLinked(); return $this->_cleanObjectDatas($this->supplier_proposal); } + /** + * Create supplier proposal (price request) object + * + * @param array $request_data Request data + * @return int ID of supplier proposal + */ + public function post($request_data = null) + { + if (!DolibarrApiAccess::$user->hasRight('supplier_proposal', 'creer')) { + throw new RestException(403, "Insuffisant rights"); + } + // Check mandatory fields + $result = $this->_validate($request_data); + + foreach ($request_data as $field => $value) { + if ($field === 'caller') { + // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller + $this->supplier_proposal->context['caller'] = $request_data['caller']; + continue; + } + + $this->supplier_proposal->$field = $value; + } + /*if (isset($request_data["lines"])) { + $lines = array(); + foreach ($request_data["lines"] as $line) { + array_push($lines, (object) $line); + } + $this->propal->lines = $lines; + }*/ + if ($this->supplier_proposal->create(DolibarrApiAccess::$user) < 0) { + throw new RestException(500, "Error creating supplier proposal", array_merge(array($this->supplier_proposal->error), $this->supplier_proposal->errors)); + } + + return $this->supplier_proposal->id; + } + + /** + * Update supplier proposal general fields (won't touch lines of supplier proposal) + * + * @param int $id Id of supplier proposal to update + * @param array $request_data Datas + * @return Object Object with cleaned properties + */ + public function put($id, $request_data = null) + { + if (!DolibarrApiAccess::$user->hasRight('supplier_proposal', 'creer')) { + throw new RestException(403); + } + + $result = $this->supplier_proposal->fetch($id); + if (!$result) { + throw new RestException(404, 'Supplier proposal not found'); + } + + if (!DolibarrApi::_checkAccessToResource('supplier_proposal', $this->supplier_proposal->id)) { + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + foreach ($request_data as $field => $value) { + if ($field == 'id') { + continue; + } + if ($field === 'caller') { + // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller + $this->supplier_proposal->context['caller'] = $request_data['caller']; + continue; + } + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->supplier_proposal->array_options[$index] = $val; + } + continue; + } + $this->supplier_proposal->$field = $value; + } + + // update end of validity date + if (empty($this->supplier_proposal->fin_validite) && !empty($this->supplier_proposal->duree_validite) && !empty($this->supplier_proposal->date_creation)) { + $this->supplier_proposal->fin_validite = $this->supplier_proposal->date_creation + ($this->supplier_proposal->duree_validite * 24 * 3600); + } + if (!empty($this->supplier_proposal->fin_validite)) { + if ($this->supplier_proposal->set_echeance(DolibarrApiAccess::$user, $this->supplier_proposal->fin_validite) < 0) { + throw new RestException(500, $this->supplier_proposal->error); + } + } + + if ($this->supplier_proposal->update(DolibarrApiAccess::$user) > 0) { + return $this->get($id); + } else { + throw new RestException(500, $this->supplier_proposal->error); + } + } + /** * List supplier proposals * diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index 9ba40dbacf0..8eecbf1a417 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -2879,6 +2879,9 @@ class SupplierProposalLine extends CommonObjectLine public $marge_tx; public $marque_tx; + /** + * @var int special code + */ public $special_code; // Tag for special lines (exclusive tags) // 1: frais de port // 2: ecotaxe diff --git a/htdocs/takepos/admin/other.php b/htdocs/takepos/admin/other.php index 5e2af98b966..c8540ecb5e0 100644 --- a/htdocs/takepos/admin/other.php +++ b/htdocs/takepos/admin/other.php @@ -29,10 +29,10 @@ require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; require_once DOL_DOCUMENT_ROOT."/core/lib/takepos.lib.php"; // If socid provided by ajax company selector -if (!empty($_REQUEST['CASHDESK_ID_THIRDPARTY_id'])) { - $_GET['CASHDESK_ID_THIRDPARTY'] = GETPOST('CASHDESK_ID_THIRDPARTY_id', 'alpha'); - $_POST['CASHDESK_ID_THIRDPARTY'] = GETPOST('CASHDESK_ID_THIRDPARTY_id', 'alpha'); - $_REQUEST['CASHDESK_ID_THIRDPARTY'] = GETPOST('CASHDESK_ID_THIRDPARTY_id', 'alpha'); +if (GETPOST('CASHDESK_ID_THIRDPARTY_id', 'alpha')) { + $_GET['CASHDESK_ID_THIRDPARTY'] = GETPOST('CASHDESK_ID_THIRDPARTY_id', 'alpha'); // Keep this ? + $_POST['CASHDESK_ID_THIRDPARTY'] = GETPOST('CASHDESK_ID_THIRDPARTY_id', 'alpha'); // Keep this ? + $_REQUEST['CASHDESK_ID_THIRDPARTY'] = GETPOST('CASHDESK_ID_THIRDPARTY_id', 'alpha'); // Keep this ? } // Security check diff --git a/htdocs/takepos/admin/printqr.php b/htdocs/takepos/admin/printqr.php index 8d6a27faff0..4e130ff18cc 100644 --- a/htdocs/takepos/admin/printqr.php +++ b/htdocs/takepos/admin/printqr.php @@ -33,7 +33,7 @@ $langs->load("cashdesk"); $id = GETPOSTINT('id'); -$_GET['optioncss'] = "print"; +//$_GET['optioncss'] = "print"; print '
      '; diff --git a/htdocs/takepos/admin/setup.php b/htdocs/takepos/admin/setup.php index 453d0115797..c94a0cc1db9 100644 --- a/htdocs/takepos/admin/setup.php +++ b/htdocs/takepos/admin/setup.php @@ -34,7 +34,7 @@ require_once DOL_DOCUMENT_ROOT."/core/lib/takepos.lib.php"; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; // If socid provided by ajax company selector -if (!empty($_REQUEST['CASHDESK_ID_THIRDPARTY_id'])) { +if (GETPOST('CASHDESK_ID_THIRDPARTY_id', 'alpha')) { $_GET['CASHDESK_ID_THIRDPARTY'] = GETPOST('CASHDESK_ID_THIRDPARTY_id', 'alpha'); $_POST['CASHDESK_ID_THIRDPARTY'] = GETPOST('CASHDESK_ID_THIRDPARTY_id', 'alpha'); $_REQUEST['CASHDESK_ID_THIRDPARTY'] = GETPOST('CASHDESK_ID_THIRDPARTY_id', 'alpha'); diff --git a/htdocs/takepos/admin/terminal.php b/htdocs/takepos/admin/terminal.php index f417c2a9988..b6b2b2857b7 100644 --- a/htdocs/takepos/admin/terminal.php +++ b/htdocs/takepos/admin/terminal.php @@ -35,7 +35,7 @@ require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php'; $terminal = GETPOSTINT('terminal'); // If socid provided by ajax company selector -if (!empty($_REQUEST['CASHDESK_ID_THIRDPARTY'.$terminal.'_id'])) { +if (GETPOST('CASHDESK_ID_THIRDPARTY'.$terminal.'_id', 'alpha')) { $_GET['CASHDESK_ID_THIRDPARTY'.$terminal] = GETPOST('CASHDESK_ID_THIRDPARTY'.$terminal.'_id', 'alpha'); $_POST['CASHDESK_ID_THIRDPARTY'.$terminal] = GETPOST('CASHDESK_ID_THIRDPARTY'.$terminal.'_id', 'alpha'); $_REQUEST['CASHDESK_ID_THIRDPARTY'.$terminal] = GETPOST('CASHDESK_ID_THIRDPARTY'.$terminal.'_id', 'alpha'); diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 9bfbc510ec2..6358bc69e3a 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -2,6 +2,7 @@ /* /* Copyright (C) 2004-2017 Laurent Destailleur * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,6 +28,59 @@ if (!defined('ISLOADEDBYSTEELSHEET')) { $leftmenuwidth = 210; +' +@phan-var-force string $badgeDanger +@phan-var-force string $badgeWarning +@phan-var-force string $borderwidth +@phan-var-force string $colorbackbody +@phan-var-force string $colorbackhmenu1 +@phan-var-force string $colorbacklinebreak +@phan-var-force string $colorbacklineimpair1 +@phan-var-force string $colorbacklineimpair2 +@phan-var-force string $colorbacklinepair1 +@phan-var-force string $colorbacklinepair2 +@phan-var-force string $colorbacklinepairchecked +@phan-var-force string $colorbacklinepairhover +@phan-var-force string $colorbacktabactive +@phan-var-force string $colorbacktabcard1 +@phan-var-force string $colorbacktitle1 +@phan-var-force string $colorbackvmenu1 +@phan-var-force string $colorblind_deuteranopes_textSuccess +@phan-var-force string $colorblind_deuteranopes_textWarning +@phan-var-force string $colorshadowtitle +@phan-var-force string $colortext +@phan-var-force string $colortextbackhmenu +@phan-var-force string $colortextbacktab +@phan-var-force string $colortextbackvmenu +@phan-var-force string $colortextlink +@phan-var-force string $colortexttitle +@phan-var-force string $colortexttitlelink +@phan-var-force string $colortexttitlenotab +@phan-var-force string $colortexttitlenotab2 +@phan-var-force string $colortopbordertitle1 +@phan-var-force int<0,1> $disableimages +@phan-var-force int<0,1> $dol_optimize_smallscreen +@phan-var-force string $fontlist +@phan-var-force string $fontsize +@phan-var-force int $heightmenu +@phan-var-force string $heightrow +@phan-var-force string $img_button +@phan-var-force string $left +@phan-var-force string $maxwidthloginblock +@phan-var-force int $minwidthtmenu +@phan-var-force int $nbtopmenuentries +@phan-var-force int $nbtopmenuentriesreal +@phan-var-force string $path +@phan-var-force string $right +@phan-var-force string $textDanger +@phan-var-force string $textSuccess +@phan-var-force string $textWarning +@phan-var-force string $toolTipBgColor +@phan-var-force string $toolTipFontColor +@phan-var-force int<0,1> $useboldtitle +@phan-var-force int $userborderontable +'; + ?> /*