diff --git a/.github/workflows/stale-issues.yml b/.github/workflows/stale-issues.yml index 66eb3f0cd40..633cc53437b 100644 --- a/.github/workflows/stale-issues.yml +++ b/.github/workflows/stale-issues.yml @@ -3,21 +3,23 @@ name: "Close stale issues (bugs and feature requests)" on: schedule: - - cron: "0 0 * * *" + - cron: "0 20 * * *" jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v1 + - uses: Dolibarr/stale@master with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-issue-message: 'This issue is stale because it has been open 1 year with no activity. If this is a bug, please comment to confirm it is still present on latest stable version. if this is a feature request, please comment to notify the request is still relevant and not yet covered by latest stable version. Without comment, this issue will be closed automatically by stale bot in 15 days.' stale-issue-label: 'Issue Stale (automatic label)' exempt-issue-label: 'Priority High / Blocking' days-before-stale: 365 - days-before-close: 10 + days-before-close: 15 + operations-per-run: 50 #stale-pr-message: 'This PR is stale because it has been open 1 year with no activity. If this PR is still mergeable (no conflict, nor Continuous Integration errors), please comment to confirm this merge is still expected. Without comment, this issue will be closed automatically by stale bot in 15 days.' - #stale-pr-label: 'PR Stale (automatic label)' - #exempt-pr-label: 'Priority Top Strategic' + stale-pr-label: 'PR Stale (automatic label)' + stale-pr-message: + exempt-pr-label: 'Priority Top Strategic' \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index dd3322e5cf7..613d2fa2420 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,7 @@ # For syntax, see http://about.travis-ci.org/docs/user/languages/php/ # We use dist: xenial to have php 5.6+ available +os: linux dist: xenial sudo: required @@ -43,7 +44,7 @@ env: global: # Set to true for very verbose output - DEBUG=false - matrix: + jobs: # MariaDB overrides MySQL installation so it's not possible to test both yet #- DB=mariadb - DB=mysql @@ -53,7 +54,7 @@ env: # See https://github.com/DracoBlue/travis-ci-nginx-php-fpm-test #- WS=nginx -matrix: +jobs: fast_finish: true allow_failures: - php: nightly diff --git a/ChangeLog b/ChangeLog index cdcef2d4e4f..c6cd7463316 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,8 +18,9 @@ Following changes may create regressions for some external modules, but were nec * Default mode for GETPOST function is now 'alphanohtml' instead of 'none'. So check when you make POST or GET requests with HTML content that you make a GETPOST('myparam', 'restricthtml') or GETPOST('myparam', 'none') if you really need posted content without sanitizing the HTML into content (in such a case, sanitize data later) - - +* Removed hidden constant MAIN_EXTRAFIELDS_IN_ONE_TD that was useless. +* Reference of object including a "/" are no more allowed. It is never used by default but to support setup that introduced it, the "/" will be replaced + by a "_" automatically when a reference is generated. ***** ChangeLog for 11.0.1 compared to 11.0.0 ***** FIX: advanced target emailing sql and ergonomy. diff --git a/build/README b/build/README index 07f0ebe3b55..67ceb05c8d2 100644 --- a/build/README +++ b/build/README @@ -45,9 +45,12 @@ Dolibarr working. It is here only to build Dolibarr packages, and those generated packages will not contains this "build" directory. -We can find in "build", following sub-directories: +You can find in "build", following sub-directories: -* debian: +* composer +To test an upgrade of a lib. + +* debian To build Debian package. * dmg: diff --git a/build/obs/README b/build/obs/README index c8a29e1dac4..44427c01d49 100644 --- a/build/obs/README +++ b/build/obs/README @@ -1,20 +1,24 @@ README (English) ################################################## OBS Package tools +OBE - openSUSE Build Service ################################################## -This directory contains files to explain how to publish -a package onto OBS +This directory contains an instruction to explain +how to publish a package onto OBS. -# Create a project onto OBS -#---------------------------------- -https://build.opensuse.org +# Create a project onto OBS +--------------------------- +https://build.opensuse.org -Packaging rules: http://en.opensuse.org/Portal:Packaging + +# Packaging rules: +------------------ +https://en.opensuse.org/Portal:Packaging Add attributes: -OBS:Screenshots URL of screenshot http://www.dolibarr.org/images/dolibarr_screenshot1.png +OBS:Screenshots URL of screenshot https://www.dolibarr.org/images/dolibarr_screenshot1.png OBS:QualityCategory Development|Testing|Stable|Private OBS:Maintained 1 @@ -28,22 +32,24 @@ To submit a snapshot for building, we should have a service file with content -How to have such a service file created automatically ? -Go into project you want to update. It mught be: +# How to have such a service file created automatically ? +--------------------------------------------------------- +Go into project you want to update. It might be: - openSUSE Build Service > Projects > Application:ERP:Dolibarr > dolibarr - or your private project Once logged, click on "Add file" in section "Source Files", then select mode "Upload From: Remote URL" Keep empty for "Filename", choose "Remote URL" and enter into last field, URL that should looks like this: -http://www.dolibarr.org/files/stable/package_rpm_generic/dolibarr-x.y.v-0.4.src.rpm +https://www.dolibarr.org/files/stable/package_rpm_generic/dolibarr-x.y.v-0.4.src.rpm Then add into Advanded - Attributes -OBS:Screenshots http://www.dolibarr.org/images/dolibarr_screenshot1.png -OBS:QualityCategory Stable|Testing|Development|Private +OBS:Screenshots https://www.dolibarr.org/images/dolibarr_screenshot1.png +OBS:QualityCategory Stable|Testing|Development|Private # Move project into official directory +-------------------------------------- - Enter a bug to ask to be a maintener of a category or to add a new one. For example: https://bugzilla.novell.com/show_bug.cgi?id=848083 to be a maintener of category https://build.opensuse.org/project/show/Application:ERP diff --git a/dev/examples/ldap/ldapadd_sample1.txt b/dev/examples/ldap/ldapadd_sample1.txt index 8a28529acb8..e998d6013a3 100644 --- a/dev/examples/ldap/ldapadd_sample1.txt +++ b/dev/examples/ldap/ldapadd_sample1.txt @@ -11,4 +11,4 @@ objectclass: dcObject objectClass: organization objectClass: top dc: my-domain -o: Mon organisation \ No newline at end of file +o: my organisation diff --git a/dev/examples/ldap/ldapmodify_sample1.txt b/dev/examples/ldap/ldapmodify_sample1.txt index e3a8361ca31..e95d1dc03a7 100644 --- a/dev/examples/ldap/ldapmodify_sample1.txt +++ b/dev/examples/ldap/ldapmodify_sample1.txt @@ -12,4 +12,4 @@ objectclass: dcObject objectClass: organization objectClass: top dc: my-domain -o: Mon organisation \ No newline at end of file +o: my organisation diff --git a/dev/resources/licence/Links on GPL.txt b/dev/resources/licence/Links on GPL.txt index bb9c1597f68..0fb3b63c851 100644 --- a/dev/resources/licence/Links on GPL.txt +++ b/dev/resources/licence/Links on GPL.txt @@ -1,7 +1,7 @@ -* Page with licence compatibility +* Page with license compatibility https://www.gnu.org/licenses/quick-guide-gplv3.fr.html -* FAQ on GPL licence +* FAQ on GPL license https://www.fsf.org/licensing/licenses/gpl-faq.html * Questions/Answers on Fork for using Dolibarr as a SaaS diff --git a/dev/resources/sepa/text.txt b/dev/resources/sepa/text.txt index 0a5336a128e..e6c05276be2 100644 --- a/dev/resources/sepa/text.txt +++ b/dev/resources/sepa/text.txt @@ -1,2 +1,2 @@ -To test a SEPA file: -http://www.mesfluxdepaiement.fr/testez-vos-fichiers-sepa \ No newline at end of file +To test a SEPA file: +https://www.mesfluxdepaiement.fr/testez-vos-fichiers-sepa diff --git a/dev/setup/codesniffer/ruleset.dtd b/dev/setup/codesniffer/ruleset.dtd index 276626a3a16..24aa32970ea 100644 --- a/dev/setup/codesniffer/ruleset.dtd +++ b/dev/setup/codesniffer/ruleset.dtd @@ -1,13 +1,18 @@ - + + + + - + + + diff --git a/dev/setup/codesniffer/ruleset.xml b/dev/setup/codesniffer/ruleset.xml index 460f815755e..8bd3ff8b319 100644 --- a/dev/setup/codesniffer/ruleset.xml +++ b/dev/setup/codesniffer/ruleset.xml @@ -2,6 +2,7 @@ Dolibarr coding standard. + build/html build/aps @@ -188,7 +189,6 @@ - diff --git a/dev/setup/eclipse/PSR-12 [built-in].xml b/dev/setup/eclipse/PSR-12 [built-in].xml new file mode 100644 index 00000000000..47925209682 --- /dev/null +++ b/dev/setup/eclipse/PSR-12 [built-in].xml @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/translation/README b/dev/translation/README index b470e4228d8..9727f91e2e6 100644 --- a/dev/translation/README +++ b/dev/translation/README @@ -3,11 +3,12 @@ README (English) This directory contains tools to generate translation files for a new languages or to update translation files for existing languages. See Dolibarr Wiki page: -http://wiki.dolibarr.org/index.php/Translator_documentation +https://wiki.dolibarr.org/index.php/Translator_documentation For more information on how to use them. +for Linux OS: To install transifex client: sudo pip install --upgrade transifex-client To update transifex client: -sudo pip install --upgrade transifex-client \ No newline at end of file +sudo pip install --upgrade transifex-client diff --git a/dev/translation/erp_comparison_translation.txt b/dev/translation/erp_comparison_translation.txt index c99a5f4cc1c..6cf7c4f7c60 100644 --- a/dev/translation/erp_comparison_translation.txt +++ b/dev/translation/erp_comparison_translation.txt @@ -1,17 +1,25 @@ +comparison of terms -Term Dolibarr SAP Odoo ... ----------------------------------------------------------------------------- -Thirdparty Contact partner Partner/Contact (company) -Contact/address Contact person Partner/Contact (individual) +Dolibarr SAP ERP Odoo +------------------------------------------------------------------------- +Thirdparty Contact partner Partner/Contact (company) +Contact/address Contact person Partner/Contact (individual) -Financial ?? Invoicing - -Income / Expense ?? Profit / Loss -Balance ?? Net profit -Subledger account Subledger account ?? +Financial Finance (FI) Accounting +Accounting -Proposal ?? Quotation Proposal is ok but proposition looks better (proposal is for a detailed proposition). We can say also "business proposition or business proposal". - Indian are using "Quotation". +Income / Expense ?? Profit / Loss +Balance ?? Net profit +Subledger account Subledger account ?? + +CRM Sales & Distribution Sales +Proposal ?? Quotation + + + +Proposal is ok but proposition looks better (proposal is for a detailed proposition). +We can say also "business proposition or business proposal". +In India they are using "Quotation". diff --git a/doc/user/README-DE.md b/doc/user/README-DE.md new file mode 100644 index 00000000000..ea9458f4563 --- /dev/null +++ b/doc/user/README-DE.md @@ -0,0 +1,12 @@ +README (german) +LiesMich (deutsch) + +-------------------------------- +Benutzeranleitung +-------------------------------- + +Alle Dolibarr-Informationen sind online verfuegbar ueber die Webseiten: +https://www.dolibarr.de +oder +https://www.dolibarr.org +https://wiki.dolibarr.org diff --git a/htdocs/accountancy/admin/account.php b/htdocs/accountancy/admin/account.php index 9de858da26b..6d59a9de1f6 100644 --- a/htdocs/accountancy/admin/account.php +++ b/htdocs/accountancy/admin/account.php @@ -45,7 +45,8 @@ $search_label = GETPOST('search_label', 'alpha'); $search_labelshort = GETPOST('search_labelshort', 'alpha'); $search_accountparent = GETPOST('search_accountparent', 'alpha'); $search_pcgtype = GETPOST('search_pcgtype', 'alpha'); -$search_pcgsubtype = GETPOST('search_pcgsubtype', 'alpha'); + +$chartofaccounts = GETPOST('chartofaccounts', 'int'); // Security check if ($user->socid > 0) accessforbidden(); @@ -69,8 +70,7 @@ $arrayfields = array( 'aa.labelshort'=>array('label'=>$langs->trans("LabelToShow"), 'checked'=>1), 'aa.account_parent'=>array('label'=>$langs->trans("Accountparent"), 'checked'=>1), 'aa.pcg_type'=>array('label'=>$langs->trans("Pcgtype"), 'checked'=>1, 'help'=>'PcgtypeDesc'), - 'aa.pcg_subtype'=>array('label'=>$langs->trans("Pcgsubtype"), 'checked'=>0, 'help'=>'PcgtypeDesc'), - 'aa.active'=>array('label'=>$langs->trans("Activated"), 'checked'=>1) + 'aa.active'=>array('label'=>$langs->trans("Activated"), 'checked'=>1) ); $accounting = new AccountingAccount($db); @@ -101,14 +101,11 @@ if (empty($reshook)) $search_labelshort = ""; $search_accountparent = ""; $search_pcgtype = ""; - $search_pcgsubtype = ""; $search_array_options = array(); } - - if (GETPOST('change_chart', 'alpha') && (GETPOST('valid_change_chart', 'int') || empty($conf->use_javascript_ajax))) + if ((GETPOST('valid_change_chart', 'alpha') && GETPOST('chartofaccounts', 'int') > 0) // explicit click on button 'Change and load' with js on + || (GETPOST('chartofaccounts', 'int') > 0 && GETPOST('chartofaccounts', 'int') != $conf->global->CHARTOFACCOUNTS)) // a submit of form is done and chartofaccounts combo has been modified { - $chartofaccounts = GETPOST('chartofaccounts', 'int'); - if ($chartofaccounts > 0) { // Get language code for this $chartofaccounts @@ -195,7 +192,7 @@ if ($action == 'delete') { $pcgver = $conf->global->CHARTOFACCOUNTS; -$sql = "SELECT aa.rowid, aa.fk_pcg_version, aa.pcg_type, aa.pcg_subtype, aa.account_number, aa.account_parent , aa.label, aa.labelshort, aa.active, "; +$sql = "SELECT aa.rowid, aa.fk_pcg_version, aa.pcg_type, aa.account_number, aa.account_parent , aa.label, aa.labelshort, aa.active, "; $sql .= " a2.rowid as rowid2, a2.label as label2, a2.account_number as account_number2"; $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as aa"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version AND aa.entity = ".$conf->entity; @@ -241,7 +238,6 @@ if (strlen(trim($search_label))) $sql .= natural_search("aa.label", $search_la if (strlen(trim($search_labelshort))) $sql .= natural_search("aa.labelshort", $search_labelshort); if (strlen(trim($search_accountparent)) && $search_accountparent != '-1') $sql .= natural_search("aa.account_parent", $search_accountparent, 2); if (strlen(trim($search_pcgtype))) $sql .= natural_search("aa.pcg_type", $search_pcgtype); -if (strlen(trim($search_pcgsubtype))) $sql .= natural_search("aa.pcg_subtype", $search_pcgsubtype); $sql .= $db->order($sortfield, $sortorder); // Count total nb of records @@ -274,23 +270,17 @@ if ($resql) if ($search_labelshort) $param .= '&search_labelshort='.urlencode($search_labelshort); if ($search_accountparent > 0 || $search_accountparent == '0') $param .= '&search_accountparent='.urlencode($search_accountparent); if ($search_pcgtype) $param .= '&search_pcgtype='.urlencode($search_pcgtype); - if ($search_pcgsubtype) $param .= '&search_pcgsubtype='.urlencode($search_pcgsubtype); - if ($optioncss != '') $param .= '&optioncss='.$optioncss; + if ($optioncss != '') $param .= '&optioncss='.$optioncss; if (!empty($conf->use_javascript_ajax)) { - print ' + print ' '; @@ -337,8 +327,7 @@ if ($resql) else dol_print_error($db); print ""; print ajax_combobox("chartofaccounts"); - print ''; - print ''; + print ''; print '
'; print '
'; @@ -363,7 +352,6 @@ if ($resql) print ''; } if (!empty($arrayfields['aa.pcg_type']['checked'])) print ''; - if (!empty($arrayfields['aa.pcg_subtype']['checked'])) print ''; if (!empty($arrayfields['aa.active']['checked'])) print ' '; print ''; $searchpicto = $form->showFilterAndCheckAddButtons($massactionbutton ? 1 : 0, 'checkforselect', 1); @@ -377,7 +365,6 @@ if ($resql) if (!empty($arrayfields['aa.labelshort']['checked'])) print_liste_field_titre($arrayfields['aa.labelshort']['label'], $_SERVER["PHP_SELF"], "aa.labelshort", "", $param, '', $sortfield, $sortorder); if (!empty($arrayfields['aa.account_parent']['checked'])) print_liste_field_titre($arrayfields['aa.account_parent']['label'], $_SERVER["PHP_SELF"], "aa.account_parent", "", $param, '', $sortfield, $sortorder, 'left '); if (!empty($arrayfields['aa.pcg_type']['checked'])) print_liste_field_titre($arrayfields['aa.pcg_type']['label'], $_SERVER["PHP_SELF"], 'aa.pcg_type', '', $param, '', $sortfield, $sortorder, '', $arrayfields['aa.pcg_type']['help']); - if (!empty($arrayfields['aa.pcg_subtype']['checked'])) print_liste_field_titre($arrayfields['aa.pcg_subtype']['label'], $_SERVER["PHP_SELF"], 'aa.pcg_subtype', '', $param, '', $sortfield, $sortorder, '', $arrayfields['aa.pcg_subtype']['help']); if (!empty($arrayfields['aa.active']['checked'])) print_liste_field_titre($arrayfields['aa.active']['label'], $_SERVER["PHP_SELF"], 'aa.active', '', $param, '', $sortfield, $sortorder); print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch '); print "\n"; @@ -454,15 +441,6 @@ if ($resql) if (!$i) $totalarray['nbfield']++; } - // Chart of accounts subtype - if (!empty($arrayfields['aa.pcg_subtype']['checked'])) - { - print ""; - print $obj->pcg_subtype; - print "\n"; - if (!$i) $totalarray['nbfield']++; - } - // Activated or not if (!empty($arrayfields['aa.active']['checked'])) { diff --git a/htdocs/accountancy/admin/card.php b/htdocs/accountancy/admin/card.php index f2bc1907c7c..7449750f958 100644 --- a/htdocs/accountancy/admin/card.php +++ b/htdocs/accountancy/admin/card.php @@ -92,7 +92,6 @@ if ($action == 'add' && $user->rights->accounting->chartofaccount) $object->fk_pcg_version = $obj->pcg_version; $object->pcg_type = GETPOST('pcg_type', 'alpha'); - $object->pcg_subtype = GETPOST('pcg_subtype', 'alpha'); $object->account_number = $account_number; $object->account_parent = $account_parent; $object->account_category = GETPOST('account_category', 'alpha'); @@ -158,7 +157,6 @@ if ($action == 'add' && $user->rights->accounting->chartofaccount) $object->fk_pcg_version = $obj->pcg_version; $object->pcg_type = GETPOST('pcg_type', 'alpha'); - $object->pcg_subtype = GETPOST('pcg_subtype', 'alpha'); $object->account_number = $account_number; $object->account_parent = $account_parent; $object->account_category = GETPOST('account_category', 'alpha'); @@ -260,12 +258,6 @@ if ($action == 'create') { print ''; print ''; - // Chart of accounts subtype - print ''.$langs->trans("Pcgsubtype").''; - print ''; - print ''; - print ''; - print ''; dol_fiche_end(); @@ -329,12 +321,6 @@ elseif ($id > 0 || $ref) { print ''; print ''; - // Chart of accounts subtype - print ''.$langs->trans("Pcgsubtype").''; - print ''; - print ''; - print ''; - print ''; dol_fiche_end(); @@ -383,10 +369,6 @@ elseif ($id > 0 || $ref) { print ''.$langs->trans("Pcgtype").''; print ''.$object->pcg_type.''; - // Chart of accounts subtype - print ''.$langs->trans("Pcgsubtype").''; - print ''.$object->pcg_subtype.''; - print ''; print ''; diff --git a/htdocs/accountancy/admin/categories_list.php b/htdocs/accountancy/admin/categories_list.php index f04f17c6e8c..50cf04a490a 100644 --- a/htdocs/accountancy/admin/categories_list.php +++ b/htdocs/accountancy/admin/categories_list.php @@ -677,9 +677,6 @@ if ($id) } if ($fieldlist[$field] == 'pcg_type') { $valuetoshow = $langs->trans("Pcg_type"); - } - if ($fieldlist[$field] == 'pcg_subtype') { - $valuetoshow = $langs->trans("Pcg_subtype"); } if ($fieldlist[$field] == 'type_template') { $valuetoshow = $langs->trans("TypeOfTemplate"); diff --git a/htdocs/accountancy/admin/defaultaccounts.php b/htdocs/accountancy/admin/defaultaccounts.php index 611aa8fc321..c0c3f835481 100644 --- a/htdocs/accountancy/admin/defaultaccounts.php +++ b/htdocs/accountancy/admin/defaultaccounts.php @@ -161,6 +161,7 @@ print ''; // Define main accounts for thirdparty print ''; +print ''; foreach ($list_account_main as $key) { print ''; @@ -180,15 +181,6 @@ foreach ($list_account_main as $key) { } -print "
'.$langs->trans("ThirdParties").' | '.$langs->trans("Users").'
\n"; - - -print '
'; - -// Define default accounts - -print ''; - foreach ($list_account as $key) { $reg=array(); if (preg_match('/---(.*)---/', $key, $reg)) { diff --git a/htdocs/accountancy/admin/export.php b/htdocs/accountancy/admin/export.php index edc73688389..b2262c603f9 100644 --- a/htdocs/accountancy/admin/export.php +++ b/htdocs/accountancy/admin/export.php @@ -134,13 +134,13 @@ if ($action == 'update') { $form = new Form($db); -$title = $langs->trans('ConfigAccountingExpert'); +$title = $langs->trans('ExportOptions'); llxHeader('', $title); $linkback = ''; // $linkback = '' . $langs->trans("BackToModuleList") . ''; -print load_fiche_titre($langs->trans('ConfigAccountingExpert'), $linkback, 'accountancy'); +print load_fiche_titre($langs->trans('ExportOptions'), $linkback, 'accountancy'); print "\n".''; - // set cookie by js - $boxcontent .= ''; + '; + // set cookie by js + $boxcontent .= ''; + } $this->info_box_contents[0][] = array( 'tr'=>'class="nohover showiffilter'.$this->boxcode.' hideobject"', 'td' => 'class="nohover"', diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index dc4cbeff1ac..5ddd0744ea8 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -49,6 +49,10 @@ abstract class CommonDocGenerator */ protected $db; + /** + * @var Extrafields object + */ + public $extrafieldsCache; /** * Constructor @@ -532,14 +536,16 @@ abstract class CommonDocGenerator * * @param Object $line Object line * @param Translate $outputlangs Lang object to use for output + * @param int $linenumber The number of the line for the substitution of "object_line_pos" * @return array Return a substitution array */ - public function get_substitutionarray_lines($line, $outputlangs) + public function get_substitutionarray_lines($line, $outputlangs, $linenumber = 0) { // phpcs:enable global $conf; $resarray = array( + 'line_pos' => $linenumber, 'line_fulldesc'=>doc_getlinedesc($line, $outputlangs), 'line_product_ref'=>$line->product_ref, 'line_product_ref_fourn'=>$line->ref_fourn, // for supplier doc lines @@ -788,81 +794,84 @@ abstract class CommonDocGenerator { // phpcs:enable global $conf; - foreach($extrafields->attributes[$object->table_element]['label'] as $key=>$label) - { - if($extrafields->attributes[$object->table_element]['type'][$key] == 'price') + + if (is_array($extrafields->attributes[$object->table_element]['label'])) { + foreach($extrafields->attributes[$object->table_element]['label'] as $key=>$label) { - $object->array_options['options_'.$key] = price2num($object->array_options['options_'.$key]); - $object->array_options['options_'.$key.'_currency'] = price($object->array_options['options_'.$key], 0, $outputlangs, 0, 0, -1, $conf->currency); - //Add value to store price with currency - $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_currency' => $object->array_options['options_'.$key.'_currency'])); - } - elseif($extrafields->attributes[$object->table_element]['type'][$key] == 'select') - { - $object->array_options['options_'.$key] = $extrafields->attributes[$object->table_element]['param'][$key]['options'][$object->array_options['options_'.$key]]; - } - elseif($extrafields->attributes[$object->table_element]['type'][$key] == 'checkbox') { - $valArray=explode(',', $object->array_options['options_'.$key]); - $output=array(); - foreach($extrafields->attributes[$object->table_element]['param'][$key]['options'] as $keyopt=>$valopt) { - if (in_array($keyopt, $valArray)) { - $output[]=$valopt; + if($extrafields->attributes[$object->table_element]['type'][$key] == 'price') + { + $object->array_options['options_'.$key] = price2num($object->array_options['options_'.$key]); + $object->array_options['options_'.$key.'_currency'] = price($object->array_options['options_'.$key], 0, $outputlangs, 0, 0, -1, $conf->currency); + //Add value to store price with currency + $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_currency' => $object->array_options['options_'.$key.'_currency'])); + } + elseif($extrafields->attributes[$object->table_element]['type'][$key] == 'select') + { + $object->array_options['options_'.$key] = $extrafields->attributes[$object->table_element]['param'][$key]['options'][$object->array_options['options_'.$key]]; + } + elseif($extrafields->attributes[$object->table_element]['type'][$key] == 'checkbox') { + $valArray=explode(',', $object->array_options['options_'.$key]); + $output=array(); + foreach($extrafields->attributes[$object->table_element]['param'][$key]['options'] as $keyopt=>$valopt) { + if (in_array($keyopt, $valArray)) { + $output[]=$valopt; + } } + $object->array_options['options_'.$key] = implode(', ', $output); } - $object->array_options['options_'.$key] = implode(', ', $output); - } - elseif($extrafields->attributes[$object->table_element]['type'][$key] == 'date') - { - if (strlen($object->array_options['options_'.$key])>0) + elseif($extrafields->attributes[$object->table_element]['type'][$key] == 'date') { - $date = $object->array_options['options_'.$key]; - $object->array_options['options_'.$key] = dol_print_date($date, 'day'); // using company output language - $object->array_options['options_'.$key.'_locale'] = dol_print_date($date, 'day', 'tzserver', $outputlangs); // using output language format - $object->array_options['options_'.$key.'_rfc'] = dol_print_date($date, 'dayrfc'); // international format - } - else - { - $object->array_options['options_'.$key] = ''; - $object->array_options['options_'.$key.'_locale'] = ''; - $object->array_options['options_'.$key.'_rfc'] = ''; - } - $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_locale' => $object->array_options['options_'.$key.'_locale'])); - $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_rfc' => $object->array_options['options_'.$key.'_rfc'])); - } - elseif($extrafields->attributes[$object->table_element]['label'][$key] == 'datetime') - { - $datetime = $object->array_options['options_'.$key]; - $object->array_options['options_'.$key] = ($datetime!="0000-00-00 00:00:00"?dol_print_date($object->array_options['options_'.$key], 'dayhour'):''); // using company output language - $object->array_options['options_'.$key.'_locale'] = ($datetime!="0000-00-00 00:00:00"?dol_print_date($object->array_options['options_'.$key], 'dayhour', 'tzserver', $outputlangs):''); // using output language format - $object->array_options['options_'.$key.'_rfc'] = ($datetime!="0000-00-00 00:00:00"?dol_print_date($object->array_options['options_'.$key], 'dayhourrfc'):''); // international format - $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_locale' => $object->array_options['options_'.$key.'_locale'])); - $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_rfc' => $object->array_options['options_'.$key.'_rfc'])); - } - elseif($extrafields->attributes[$object->table_element]['type'][$key] == 'link') - { - $id = $object->array_options['options_'.$key]; - if ($id != "") - { - $param = $extrafields->attributes[$object->table_element]['param'][$key]; - $param_list=array_keys($param['options']); // $param_list='ObjectName:classPath' - $InfoFieldList = explode(":", $param_list[0]); - $classname=$InfoFieldList[0]; - $classpath=$InfoFieldList[1]; - if (! empty($classpath)) + if (strlen($object->array_options['options_'.$key])>0) { - dol_include_once($InfoFieldList[1]); - if ($classname && class_exists($classname)) + $date = $object->array_options['options_'.$key]; + $object->array_options['options_'.$key] = dol_print_date($date, 'day'); // using company output language + $object->array_options['options_'.$key.'_locale'] = dol_print_date($date, 'day', 'tzserver', $outputlangs); // using output language format + $object->array_options['options_'.$key.'_rfc'] = dol_print_date($date, 'dayrfc'); // international format + } + else + { + $object->array_options['options_'.$key] = ''; + $object->array_options['options_'.$key.'_locale'] = ''; + $object->array_options['options_'.$key.'_rfc'] = ''; + } + $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_locale' => $object->array_options['options_'.$key.'_locale'])); + $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_rfc' => $object->array_options['options_'.$key.'_rfc'])); + } + elseif($extrafields->attributes[$object->table_element]['label'][$key] == 'datetime') + { + $datetime = $object->array_options['options_'.$key]; + $object->array_options['options_'.$key] = ($datetime!="0000-00-00 00:00:00"?dol_print_date($object->array_options['options_'.$key], 'dayhour'):''); // using company output language + $object->array_options['options_'.$key.'_locale'] = ($datetime!="0000-00-00 00:00:00"?dol_print_date($object->array_options['options_'.$key], 'dayhour', 'tzserver', $outputlangs):''); // using output language format + $object->array_options['options_'.$key.'_rfc'] = ($datetime!="0000-00-00 00:00:00"?dol_print_date($object->array_options['options_'.$key], 'dayhourrfc'):''); // international format + $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_locale' => $object->array_options['options_'.$key.'_locale'])); + $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_rfc' => $object->array_options['options_'.$key.'_rfc'])); + } + elseif($extrafields->attributes[$object->table_element]['type'][$key] == 'link') + { + $id = $object->array_options['options_'.$key]; + if ($id != "") + { + $param = $extrafields->attributes[$object->table_element]['param'][$key]; + $param_list=array_keys($param['options']); // $param_list='ObjectName:classPath' + $InfoFieldList = explode(":", $param_list[0]); + $classname=$InfoFieldList[0]; + $classpath=$InfoFieldList[1]; + if (! empty($classpath)) { - $tmpobject = new $classname($this->db); - $tmpobject->fetch($id); - // completely replace the id with the linked object name - $object->array_options['options_'.$key] = $tmpobject->name; + dol_include_once($InfoFieldList[1]); + if ($classname && class_exists($classname)) + { + $tmpobject = new $classname($this->db); + $tmpobject->fetch($id); + // completely replace the id with the linked object name + $object->array_options['options_'.$key] = $tmpobject->name; + } } } } - } - $array_to_fill = array_merge($array_to_fill, array($array_key.'_options_'.$key => $object->array_options['options_'.$key])); + $array_to_fill = array_merge($array_to_fill, array($array_key.'_options_'.$key => $object->array_options['options_'.$key])); + } } return $array_to_fill; @@ -1074,7 +1083,7 @@ abstract class CommonDocGenerator * @param float $curY curent Y position * @param string $colKey the column key * @param string $columnText column text - * @return int new rank on success and -1 on error + * @return null */ public function printStdColumnContent($pdf, &$curY, $colKey, $columnText = '') { @@ -1096,6 +1105,221 @@ abstract class CommonDocGenerator } } + /** + * get extrafield content for pdf writeHtmlCell compatibility + * usage for PDF line columns and object note block + * + * @param object $object common object + * @param string $extrafieldKey the extrafield key + * @return string + */ + public function getExtrafieldContent($object, $extrafieldKey) + { + global $hookmanager; + + if(empty($object->table_element)){ return; } + + $extrafieldsKeyPrefix = "options_"; + + // Cleanup extrafield key to remove prefix if present + $pos = strpos($extrafieldKey, $extrafieldsKeyPrefix); + if($pos===0){ + $extrafieldKey = substr($extrafieldKey, strlen($extrafieldsKeyPrefix)); + } + + $extrafieldOptionsKey = $extrafieldsKeyPrefix.$extrafieldKey; + + + // Load extrafiels if not allready does + if(empty($this->extrafieldsCache)){ $this->extrafieldsCache = new ExtraFields($this->db); } + if(empty($this->extrafieldsCache->attributes[$object->table_element])){ $this->extrafieldsCache->fetch_name_optionals_label($object->table_element); } + $extrafields = $this->extrafieldsCache; + + $extrafieldOutputContent = $extrafields->showOutputField($extrafieldKey, $object->array_options[$extrafieldOptionsKey], '', $object->table_element); + + // TODO : allow showOutputField to be pdf public friendly, ex: in a link to object, clean getNomUrl to remove link and images... like a getName methode ... + if($extrafields->attributes[$object->table_element]['type'][$extrafieldKey] == 'link'){ + // for lack of anything better we cleanup all html tags + $extrafieldOutputContent = dol_string_nohtmltag($extrafieldOutputContent); + } + + $parameters = array( + 'object' => $object, + 'extrafields' => $extrafields, + 'extrafieldKey' => $extrafieldKey, + 'extrafieldOutputContent' =>& $extrafieldOutputContent + ); + $reshook = $hookmanager->executeHooks('getPDFExtrafieldContent', $parameters, $this); // Note that $action and $object may have been modified by hook + if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + if ($reshook) + { + $extrafieldOutputContent = $hookmanager->resPrint; + } + + return $extrafieldOutputContent; + } + + + /** + * display extrafields columns content + * + * @param object $object line of common object + * @param Translate $outputlangs Output language + * @param array $params array of additionals parameters + * @return double max y value + */ + public function getExtrafieldsInHtml($object, $outputlangs, $params = array()) + { + global $hookmanager; + + if(empty($object->table_element)){ + return; + } + + // Load extrafiels if not allready does + if(empty($this->extrafieldsCache)){ $this->extrafieldsCache = new ExtraFields($this->db); } + if(empty($this->extrafieldsCache->attributes[$object->table_element])){ $this->extrafieldsCache->fetch_name_optionals_label($object->table_element); } + $extrafields = $this->extrafieldsCache; + + $defaultParams = array( + 'style' => '', + 'display' => 'auto', // auto, table, list + + 'table' => array( + 'maxItemsInRow' => 2, + 'cellspacing' => 0, + 'cellpadding' => 0, + 'border' => 0, + 'labelcolwidth' => '25%', + 'arrayOfLineBreakType' => array('text', 'html') + ), + + 'list' => array( + 'separator' => '
' + ), + + 'auto' => array( + 'list' => 0, // 0 for default + 'table' => 4 // if there more than x extrafield to display + ), + ); + + $params = $params + $defaultParams; + + + /** + * @var $extrafields ExtraFields + */ + + $html = ''; + $fields = array(); + + if (is_array($extrafields->attributes[$object->table_element]['label'])) { + foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) + { + // Enable extrafield ? + $enabled = !empty($extrafields->attributes[$object->table_element]['printable'][$key]); + + if(empty($enabled)){ + continue; + } + + $field = new stdClass(); + $field->rank = intval($extrafields->attributes[$object->table_element]['pos'][$key]); + $field->content = $this->getExtrafieldContent($object, $key); + $field->label = $outputlangs->transnoentities($label); + $field->type = $extrafields->attributes[$object->table_element]['type'][$key]; + + $fields[] = $field; + } + } + + if(!empty($fields)) + { + // Sort extrafields by rank + uasort($fields, function ($a, $b) { + return ($a->rank > $b->rank) ? -1 : 1; + } + ); + + + + // define some HTML content with style + $html.= ''; + + // auto select display format + if($params['display'] == 'auto') { + $lastNnumbItems = 0; + foreach ($params['auto'] as $display => $numbItems){ + if($lastNnumbItems <= $numbItems && count($fields) > $numbItems){ + $lastNnumbItems = $numbItems; + $params['display'] = $display; + } + } + } + + if($params['display'] == 'list') { + // Display in list format + foreach ($fields as $field) { + $html .= !empty($html)?$params['list']['separator']:''; + $html .= '' . $field->label . ' : '; + $html .= $field->content; + } + } + elseif($params['display'] == 'table') { + // Display in table format + $html .= '
'; + + $html .= ""; + $itemsInRow = 0; + $maxItemsInRow = $params['table']['maxItemsInRow']; + foreach ($fields as $field) { + //$html.= !empty($html)?'
':''; + if ($itemsInRow >= $maxItemsInRow) { + // start a new line + $html .= ""; + $itemsInRow = 0; + } + + // for some type we need line break + if (in_array($field->type, $params['table']['arrayOfLineBreakType'])) { + if ($itemsInRow > 0) { + // close table row and empty cols + for ($i = $itemsInRow; $i <= $maxItemsInRow; $i++) { + $html .= ""; + } + $html .= ""; + + // start a new line + $html .= ""; + } + + $itemsInRow = $maxItemsInRow; + $html .= '"; + } else { + $itemsInRow++; + $html .= '"; + + + $html .= '"; + } + } + $html .= ""; + + $html .= '
'; + $html .= '' . $field->label . ' : '; + $html .= $field->content; + $html .= "'; + $html .= '' . $field->label . ' :'; + $html .= "'; + $html .= $field->content; + $html .= "
'; + } + } + + return $html; + } + /** * get column status from column key @@ -1167,4 +1391,81 @@ abstract class CommonDocGenerator } return $this->tabTitleHeight; } + + + + /** + * Define Array Column Field for extrafields + * + * @param object $object common object det + * @param Translate $outputlangs langs + * @param int $hidedetails Do not show line details + * @return null + */ + public function defineColumnExtrafield($object, $outputlangs, $hidedetails = 0) + { + global $conf; + + if(!empty($hidedetails)){ + return; + } + + if(empty($object->table_element)){ + return; + } + + // Load extrafiels if not allready does + if(empty($this->extrafieldsCache)){ $this->extrafieldsCache = new ExtraFields($this->db); } + if(empty($this->extrafieldsCache->attributes[$object->table_element])){ $this->extrafieldsCache->fetch_name_optionals_label($object->table_element); } + $extrafields = $this->extrafieldsCache; + + + if (!empty($extrafields->attributes[$object->table_element]) && is_array($extrafields->attributes[$object->table_element]['label'])) { + foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) + { + // Dont display separator yet even is set to be displayed (not compatible yet) + if ($extrafields->attributes[$object->table_element]['type'][$key] == 'separate') + { + continue; + } + + // Enable extrafield ? + $enabled = !empty($extrafields->attributes[$object->table_element]['printable'][$key]); + + + // Load language if required + if (!empty($extrafields->attributes[$object->table_element]['langfile'][$key])) $outputlangs->load($extrafields->attributes[$object->table_element]['langfile'][$key]); + + // TODO : add more extrafield customisation capacities for PDF like width, rank... + + // set column definition + $def = array( + 'rank' => intval($extrafields->attributes[$object->table_element]['pos'][$key]), + 'width' => 25, // in mm + 'status' => boolval($enabled), + 'title' => array( + 'label' => $outputlangs->transnoentities($label) + ), + 'content' => array( + 'align' => 'C' + ), + 'border-left' => true, // add left line separator + ); + + $alignTypeRight = array('double', 'int', 'price'); + if(in_array($extrafields->attributes[$object->table_element]['type'][$key], $alignTypeRight)){ + $def['content']['align'] = 'R'; + } + + $alignTypeLeft = array('text', 'html'); + if(in_array($extrafields->attributes[$object->table_element]['type'][$key], $alignTypeLeft)){ + $def['content']['align'] = 'L'; + } + + + // for extrafields we use rank of extrafield to place it on PDF + $this->insertNewColumnDef("options_".$key, $def); + } + } + } } diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 6fdf74f8466..a20a8dd8526 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -571,7 +571,7 @@ abstract class CommonObject $return = '
'; $return .= '
'; $return .= ''; - $return .= ''; // Can be image + $return .= ''; // Can be image $return .= ''; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).''; @@ -1797,14 +1797,14 @@ abstract class CommonObject // this->ismultientitymanaged contains // 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table $aliastablesociete = 's'; - if ($this->element == 'societe') $aliastablesociete = 'te'; // te as table_element + if ($this->element == 'societe') $aliastablesociete = 'te'; // te as table_element $sql = "SELECT MAX(te.".$fieldid.")"; $sql .= " FROM ".(empty($nodbprefix) ?MAIN_DB_PREFIX:'').$this->table_element." as te"; if ($this->element == 'user' && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { $sql .= ",".MAIN_DB_PREFIX."usergroup_user as ug"; } - if (isset($this->ismultientitymanaged) && ! is_numeric($this->ismultientitymanaged)) { + if (isset($this->ismultientitymanaged) && !is_numeric($this->ismultientitymanaged)) { $tmparray = explode('@', $this->ismultientitymanaged); $sql .= ", ".MAIN_DB_PREFIX.$tmparray[1]." as ".($tmparray[1] == 'societe' ? 's' : 'parenttable'); // If we need to link to this table to limit select to entity } @@ -1819,7 +1819,7 @@ abstract class CommonObject if (!preg_match('/^\s*AND/i', $filter)) $sql .= " AND "; // For backward compatibility $sql .= $filter; } - if (isset($this->ismultientitymanaged) && ! is_numeric($this->ismultientitymanaged)) { + if (isset($this->ismultientitymanaged) && !is_numeric($this->ismultientitymanaged)) { $tmparray = explode('@', $this->ismultientitymanaged); $sql .= ' AND te.'.$tmparray[0].' = '.($tmparray[1] == 'societe' ? 's' : 'parenttable').'.rowid'; // If we need to link to this table to limit select to entity } @@ -1836,7 +1836,7 @@ abstract class CommonObject $sql .= ' AND te.entity IN ('.getEntity($this->element).')'; } } - if (isset($this->ismultientitymanaged) && ! is_numeric($this->ismultientitymanaged) && $this->element != 'societe') { + if (isset($this->ismultientitymanaged) && !is_numeric($this->ismultientitymanaged) && $this->element != 'societe') { $tmparray = explode('@', $this->ismultientitymanaged); $sql .= ' AND parenttable.entity IN ('.getEntity($tmparray[1]).')'; } @@ -3369,6 +3369,9 @@ abstract class CommonObject elseif ($objecttype == 'subscription') { $classpath = 'adherents/class'; $module = 'adherent'; } + elseif ($objecttype == 'contact') { + $module = 'societe'; + } // Set classfile $classfile = strtolower($subelement); $classname = ucfirst($subelement); @@ -3391,6 +3394,9 @@ abstract class CommonObject elseif ($objecttype == 'subscription') { $classfile = 'subscription'; $classname = 'Subscription'; } + elseif ($objecttype == 'project' || $objecttype == 'projet') { + $classpath = 'projet/class'; $classfile = 'project'; $classname = 'Project'; + } // Here $module, $classfile and $classname are set if ($conf->$module->enabled && (($element != $this->element) || $alsosametype)) @@ -5625,7 +5631,7 @@ abstract class CommonObject $form = new Form($this->db); } - if (! empty($this->fields)) { + if (!empty($this->fields)) { $val = $this->fields[$key]; } diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index cec04a3ac5e..87204294947 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -293,30 +293,30 @@ class Conf $rootfortemp = empty($this->global->MAIN_TEMP_DIR) ? $rootfordata : $this->global->MAIN_TEMP_DIR; // Define default dir_output and dir_temp for directories of modules - foreach($this->modules as $module) + foreach ($this->modules as $module) { //var_dump($module); // For multicompany sharings - $this->$module->multidir_output = array($this->entity => $rootfordata."/".$module); - $this->$module->multidir_temp = array($this->entity => $rootfortemp."/".$module."/temp"); + $this->$module->multidir_output = array($this->entity => $rootfordata."/".$module); + $this->$module->multidir_temp = array($this->entity => $rootfortemp."/".$module."/temp"); // For backward compatibility - $this->$module->dir_output = $rootfordata."/".$module; - $this->$module->dir_temp = $rootfortemp."/".$module."/temp"; + $this->$module->dir_output = $rootfordata."/".$module; + $this->$module->dir_temp = $rootfortemp."/".$module."/temp"; } // External modules storage - if (! empty($this->modules_parts['dir'])) + if (!empty($this->modules_parts['dir'])) { - foreach($this->modules_parts['dir'] as $module => $dirs) + foreach ($this->modules_parts['dir'] as $module => $dirs) { - if (! empty($this->$module->enabled)) + if (!empty($this->$module->enabled)) { - foreach($dirs as $type => $name) // $type is 'output' or 'temp' + foreach ($dirs as $type => $name) // $type is 'output' or 'temp' { - $multidirname = 'multidir_'.$type; - $dirname = 'dir_'.$type; + $multidirname = 'multidir_'.$type; + $dirname = 'dir_'.$type; - if($type != 'temp') + if ($type != 'temp') { // For multicompany sharings $this->$module->$multidirname = array($this->entity => $rootfordata."/".$name); @@ -338,90 +338,90 @@ class Conf } // For mycompany storage - $this->mycompany->dir_output = $rootfordata."/mycompany"; - $this->mycompany->dir_temp = $rootfortemp."/mycompany/temp"; + $this->mycompany->dir_output = $rootfordata."/mycompany"; + $this->mycompany->dir_temp = $rootfortemp."/mycompany/temp"; // For admin storage - $this->admin->dir_output = $rootfordata.'/admin'; - $this->admin->dir_temp = $rootfortemp.'/admin/temp'; + $this->admin->dir_output = $rootfordata.'/admin'; + $this->admin->dir_temp = $rootfortemp.'/admin/temp'; // For user storage - $this->user->multidir_output = array($this->entity => $rootfordata."/users"); - $this->user->multidir_temp = array($this->entity => $rootfortemp."/users/temp"); + $this->user->multidir_output = array($this->entity => $rootfordata."/users"); + $this->user->multidir_temp = array($this->entity => $rootfortemp."/users/temp"); // For backward compatibility - $this->user->dir_output = $rootforuser."/users"; - $this->user->dir_temp = $rootfortemp."/users/temp"; + $this->user->dir_output = $rootforuser."/users"; + $this->user->dir_temp = $rootfortemp."/users/temp"; // For usergroup storage - $this->usergroup->dir_output = $rootforuser."/usergroups"; - $this->usergroup->dir_temp = $rootfortemp."/usergroups/temp"; + $this->usergroup->dir_output = $rootforuser."/usergroups"; + $this->usergroup->dir_temp = $rootfortemp."/usergroups/temp"; // For proposal storage - $this->propal->multidir_output = array($this->entity => $rootfordata."/propale"); - $this->propal->multidir_temp = array($this->entity => $rootfortemp."/propale/temp"); + $this->propal->multidir_output = array($this->entity => $rootfordata."/propale"); + $this->propal->multidir_temp = array($this->entity => $rootfortemp."/propale/temp"); // For backward compatibility - $this->propal->dir_output = $rootfordata."/propale"; - $this->propal->dir_temp = $rootfortemp."/propale/temp"; + $this->propal->dir_output = $rootfordata."/propale"; + $this->propal->dir_temp = $rootfortemp."/propale/temp"; // For medias storage - $this->medias->multidir_output = array($this->entity => $rootfordata."/medias"); - $this->medias->multidir_temp = array($this->entity => $rootfortemp."/medias/temp"); + $this->medias->multidir_output = array($this->entity => $rootfordata."/medias"); + $this->medias->multidir_temp = array($this->entity => $rootfortemp."/medias/temp"); // Exception: Some dir are not the name of module. So we keep exception here for backward compatibility. // Sous module bons d'expedition - $this->expedition_bon->enabled=(! empty($this->global->MAIN_SUBMODULE_EXPEDITION)?$this->global->MAIN_SUBMODULE_EXPEDITION:0); + $this->expedition_bon->enabled = (!empty($this->global->MAIN_SUBMODULE_EXPEDITION) ? $this->global->MAIN_SUBMODULE_EXPEDITION : 0); // Sous module bons de livraison - $this->livraison_bon->enabled=(! empty($this->global->MAIN_SUBMODULE_LIVRAISON)?$this->global->MAIN_SUBMODULE_LIVRAISON:0); + $this->livraison_bon->enabled = (!empty($this->global->MAIN_SUBMODULE_LIVRAISON) ? $this->global->MAIN_SUBMODULE_LIVRAISON : 0); // Module fournisseur - if (! empty($this->fournisseur)) + if (!empty($this->fournisseur)) { - $this->fournisseur->commande=new stdClass(); - $this->fournisseur->commande->multidir_output = array($this->entity => $rootfordata."/fournisseur/commande"); - $this->fournisseur->commande->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/commande/temp"); - $this->fournisseur->commande->dir_output = $rootfordata."/fournisseur/commande"; // For backward compatibility - $this->fournisseur->commande->dir_temp = $rootfortemp."/fournisseur/commande/temp"; // For backward compatibility + $this->fournisseur->commande = new stdClass(); + $this->fournisseur->commande->multidir_output = array($this->entity => $rootfordata."/fournisseur/commande"); + $this->fournisseur->commande->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/commande/temp"); + $this->fournisseur->commande->dir_output = $rootfordata."/fournisseur/commande"; // For backward compatibility + $this->fournisseur->commande->dir_temp = $rootfortemp."/fournisseur/commande/temp"; // For backward compatibility - $this->fournisseur->facture=new stdClass(); - $this->fournisseur->facture->multidir_output = array($this->entity => $rootfordata."/fournisseur/facture"); - $this->fournisseur->facture->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/facture/temp"); - $this->fournisseur->facture->dir_output = $rootfordata."/fournisseur/facture"; // For backward compatibility - $this->fournisseur->facture->dir_temp = $rootfortemp."/fournisseur/facture/temp"; // For backward compatibility + $this->fournisseur->facture = new stdClass(); + $this->fournisseur->facture->multidir_output = array($this->entity => $rootfordata."/fournisseur/facture"); + $this->fournisseur->facture->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/facture/temp"); + $this->fournisseur->facture->dir_output = $rootfordata."/fournisseur/facture"; // For backward compatibility + $this->fournisseur->facture->dir_temp = $rootfortemp."/fournisseur/facture/temp"; // For backward compatibility - $this->supplierproposal=new stdClass(); - $this->supplierproposal->multidir_output = array($this->entity => $rootfordata."/supplier_proposal"); - $this->supplierproposal->multidir_temp = array($this->entity => $rootfortemp."/supplier_proposal/temp"); - $this->supplierproposal->dir_output = $rootfordata."/supplier_proposal"; // For backward compatibility - $this->supplierproposal->dir_temp = $rootfortemp."/supplier_proposal/temp"; // For backward compatibility + $this->supplierproposal = new stdClass(); + $this->supplierproposal->multidir_output = array($this->entity => $rootfordata."/supplier_proposal"); + $this->supplierproposal->multidir_temp = array($this->entity => $rootfortemp."/supplier_proposal/temp"); + $this->supplierproposal->dir_output = $rootfordata."/supplier_proposal"; // For backward compatibility + $this->supplierproposal->dir_temp = $rootfortemp."/supplier_proposal/temp"; // For backward compatibility - $this->fournisseur->payment=new stdClass(); - $this->fournisseur->payment->multidir_output = array($this->entity => $rootfordata."/fournisseur/payment"); - $this->fournisseur->payment->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/payment/temp"); - $this->fournisseur->payment->dir_output = $rootfordata."/fournisseur/payment"; // For backward compatibility - $this->fournisseur->payment->dir_temp = $rootfortemp."/fournisseur/payment/temp"; // For backward compatibility + $this->fournisseur->payment = new stdClass(); + $this->fournisseur->payment->multidir_output = array($this->entity => $rootfordata."/fournisseur/payment"); + $this->fournisseur->payment->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/payment/temp"); + $this->fournisseur->payment->dir_output = $rootfordata."/fournisseur/payment"; // For backward compatibility + $this->fournisseur->payment->dir_temp = $rootfortemp."/fournisseur/payment/temp"; // For backward compatibility // To prepare split of module fournisseur into fournisseur + supplier_order + supplier_invoice - if (! empty($this->fournisseur->enabled) && empty($this->global->MAIN_USE_NEW_SUPPLIERMOD)) // By default, if module supplier is on, we set new properties + if (!empty($this->fournisseur->enabled) && empty($this->global->MAIN_USE_NEW_SUPPLIERMOD)) // By default, if module supplier is on, we set new properties { if (empty($this->global->MAIN_USE_NEW_SUPPLIERMOD)) // This can be set to 1 once modules purchase order and supplier invoice exists { - $this->supplier_order=new stdClass(); - $this->supplier_order->enabled = 1; - $this->supplier_order->multidir_output = array($this->entity => $rootfordata."/fournisseur/commande"); - $this->supplier_order->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/commande/temp"); - $this->supplier_order->dir_output = $rootfordata."/fournisseur/commande"; // For backward compatibility - $this->supplier_order->dir_temp = $rootfortemp."/fournisseur/commande/temp"; // For backward compatibility + $this->supplier_order = new stdClass(); + $this->supplier_order->enabled = 1; + $this->supplier_order->multidir_output = array($this->entity => $rootfordata."/fournisseur/commande"); + $this->supplier_order->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/commande/temp"); + $this->supplier_order->dir_output = $rootfordata."/fournisseur/commande"; // For backward compatibility + $this->supplier_order->dir_temp = $rootfortemp."/fournisseur/commande/temp"; // For backward compatibility } if (empty($this->global->MAIN_USE_NEW_SUPPLIERMOD)) // This can be set to 1 once modules purchase order and supplier invoice exists { - $this->supplier_invoice=new stdClass(); - $this->supplier_invoice->enabled = 1; - $this->supplier_invoice->multidir_output = array($this->entity => $rootfordata."/fournisseur/facture"); - $this->supplier_invoice->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/facture/temp"); - $this->supplier_invoice->dir_output = $rootfordata."/fournisseur/facture"; // For backward compatibility - $this->supplier_invoice->dir_temp = $rootfortemp."/fournisseur/facture/temp"; // For backward compatibility + $this->supplier_invoice = new stdClass(); + $this->supplier_invoice->enabled = 1; + $this->supplier_invoice->multidir_output = array($this->entity => $rootfordata."/fournisseur/facture"); + $this->supplier_invoice->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/facture/temp"); + $this->supplier_invoice->dir_output = $rootfordata."/fournisseur/facture"; // For backward compatibility + $this->supplier_invoice->dir_temp = $rootfortemp."/fournisseur/facture/temp"; // For backward compatibility } } } @@ -438,22 +438,22 @@ class Conf $this->service->dir_temp = $rootfortemp."/produit/temp"; // Module productbatch - $this->productbatch->multidir_output = array($this->entity => $rootfordata."/produitlot"); - $this->productbatch->multidir_temp = array($this->entity => $rootfortemp."/produitlot/temp"); + $this->productbatch->multidir_output = array($this->entity => $rootfordata."/produitlot"); + $this->productbatch->multidir_temp = array($this->entity => $rootfortemp."/produitlot/temp"); // Module contrat - $this->contrat->multidir_output = array($this->entity => $rootfordata."/contract"); - $this->contrat->multidir_temp = array($this->entity => $rootfortemp."/contract/temp"); + $this->contrat->multidir_output = array($this->entity => $rootfordata."/contract"); + $this->contrat->multidir_temp = array($this->entity => $rootfortemp."/contract/temp"); // For backward compatibility - $this->contrat->dir_output = $rootfordata."/contract"; - $this->contrat->dir_temp = $rootfortemp."/contract/temp"; + $this->contrat->dir_output = $rootfordata."/contract"; + $this->contrat->dir_temp = $rootfortemp."/contract/temp"; // Module bank $this->bank->multidir_output = array($this->entity => $rootfordata."/bank"); $this->bank->multidir_temp = array($this->entity => $rootfortemp."/bank/temp"); // For backward compatibility - $this->bank->dir_output = $rootfordata."/bank"; - $this->bank->dir_temp = $rootfortemp."/bank/temp"; + $this->bank->dir_output = $rootfordata."/bank"; + $this->bank->dir_temp = $rootfortemp."/bank/temp"; // Set some default values //$this->global->MAIN_LIST_FILTER_ON_DAY=1; // On filter that show date, we must show input field for day before or after month @@ -527,7 +527,7 @@ class Conf if (empty($this->global->MAIN_THEME)) $this->global->MAIN_THEME = "eldy"; if (!empty($this->global->MAIN_FORCETHEME)) $this->global->MAIN_THEME = $this->global->MAIN_FORCETHEME; $this->theme = $this->global->MAIN_THEME; - $this->css = "/theme/".$this->theme."/style.css.php"; + $this->css = "/theme/".$this->theme."/style.css.php"; // conf->email_from = email pour envoi par dolibarr des mails automatiques $this->email_from = "robot@example.com"; @@ -681,15 +681,11 @@ class Conf $this->global->AGENDA_DEFAULT_FILTER_TYPE = '0'; // 'AC_NON_AUTO' does not exists when AGENDA_DEFAULT_FILTER_TYPE is not on. } - if (!isset($this->global->MAIN_EXTRAFIELDS_IN_ONE_TD)) $this->global->MAIN_EXTRAFIELDS_IN_ONE_TD = 1; - if (!isset($this->global->MAIN_USE_OLD_TITLE_BUTTON)) $this->global->MAIN_USE_OLD_TITLE_BUTTON = 0; if (empty($this->global->MAIN_MODULE_DOLISTORE_API_SRV)) $this->global->MAIN_MODULE_DOLISTORE_API_SRV = 'https://www.dolistore.com'; if (empty($this->global->MAIN_MODULE_DOLISTORE_API_KEY)) $this->global->MAIN_MODULE_DOLISTORE_API_KEY = 'dolistorecatalogpublickey1234567'; - if (! isset($this->global->MAIN_USE_TOP_MENU_BOOKMARK_DROPDOWN)) $this->global->MAIN_USE_TOP_MENU_BOOKMARK_DROPDOWN = 1; - // If we are in develop mode, we activate the option MAIN_SECURITY_CSRF_WITH_TOKEN to 1 if not already defined. if (!isset($this->global->MAIN_SECURITY_CSRF_WITH_TOKEN) && $this->global->MAIN_FEATURES_LEVEL >= 2) $this->global->MAIN_SECURITY_CSRF_WITH_TOKEN = 1; diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php index ca40910aacd..c3707b18972 100644 --- a/htdocs/core/class/discount.class.php +++ b/htdocs/core/class/discount.class.php @@ -504,15 +504,16 @@ class DiscountAbsolute * @param string $filter Filtre autre * @param int $maxvalue Filter on max value for discount * @param int $discount_type 0 => customer discount, 1 => supplier discount + * @param int $multicurrency Return multicurrency_amount instead of amount * @return int <0 if KO, amount otherwise */ - public function getAvailableDiscounts($company = '', $user = '', $filter = '', $maxvalue = 0, $discount_type = 0) + public function getAvailableDiscounts($company = '', $user = '', $filter = '', $maxvalue = 0, $discount_type = 0, $multicurrency = 0) { global $conf; dol_syslog(get_class($this)."::getAvailableDiscounts discount_type=".$discount_type, LOG_DEBUG); - $sql = "SELECT SUM(rc.amount_ttc) as amount"; + $sql = "SELECT SUM(rc.amount_ttc) as amount, SUM(rc.multicurrency_amount_ttc) as multicurrency_amount"; $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as rc"; $sql .= " WHERE rc.entity = ".$conf->entity; $sql .= " AND rc.discount_type=".intval($discount_type); @@ -535,6 +536,11 @@ class DiscountAbsolute //print 'zz'.$obj->amount; //$obj = $this->db->fetch_object($resql); //} + if ($multicurrency) + { + return $obj->amount_multicurrency; + } + return $obj->amount; } return -1; @@ -604,14 +610,14 @@ class DiscountAbsolute $sql = 'SELECT sum(rc.amount_ttc) as amount, sum(rc.multicurrency_amount_ttc) as multicurrency_amount'; $sql .= ' FROM '.MAIN_DB_PREFIX.'societe_remise_except as rc, '.MAIN_DB_PREFIX.'facture as f'; $sql .= ' WHERE rc.fk_facture_source=f.rowid AND rc.fk_facture = '.$invoice->id; - $sql .= ' AND (f.type = 2 OR f.type = 0)'; // Find discount coming from credit note or excess received + $sql .= ' AND f.type IN (' . $invoice::TYPE_STANDARD . ', ' . $invoice::TYPE_CREDIT_NOTE . ', ' . $invoice::TYPE_SITUATION . ')'; // Find discount coming from credit note or excess received } elseif ($invoice->element == 'invoice_supplier') { $sql = 'SELECT sum(rc.amount_ttc) as amount, sum(rc.multicurrency_amount_ttc) as multicurrency_amount'; $sql .= ' FROM '.MAIN_DB_PREFIX.'societe_remise_except as rc, '.MAIN_DB_PREFIX.'facture_fourn as f'; $sql .= ' WHERE rc.fk_invoice_supplier_source=f.rowid AND rc.fk_invoice_supplier = '.$invoice->id; - $sql .= ' AND (f.type = 2 OR f.type = 0)'; // Find discount coming from credit note or excess paid + $sql .= ' AND f.type IN (' . $invoice::TYPE_STANDARD . ', ' . $invoice::TYPE_CREDIT_NOTE . ')'; // Find discount coming from credit note or excess paid } else { diff --git a/htdocs/core/class/doleditor.class.php b/htdocs/core/class/doleditor.class.php index 06b6ec2d949..a38c25f7614 100644 --- a/htdocs/core/class/doleditor.class.php +++ b/htdocs/core/class/doleditor.class.php @@ -90,7 +90,7 @@ class DolEditor { $content = dol_htmlentitiesbr($content); // If content is not HTML, we convert to HTML. } - if ($this->tool == 'fckeditor') + /*if ($this->tool == 'fckeditor') { require_once DOL_DOCUMENT_ROOT.'/includes/fckeditor/fckeditor.php'; @@ -121,7 +121,7 @@ class DolEditor $this->editor->Config['CustomConfigurationsPath'] = DOL_URL_ROOT.'/theme/'.$conf->theme.'/fckeditor/fckconfig.js'; $this->editor->Config['SkinPath'] = DOL_URL_ROOT.'/theme/'.$conf->theme.'/fckeditor/'; } - } + }*/ // Define some properties if (in_array($this->tool, array('textarea', 'ckeditor', 'ace'))) diff --git a/htdocs/core/class/dolgraph.class.php b/htdocs/core/class/dolgraph.class.php index 9aa54498edc..bdeebb10062 100644 --- a/htdocs/core/class/dolgraph.class.php +++ b/htdocs/core/class/dolgraph.class.php @@ -951,7 +951,11 @@ class DolGraph $this->stringtoshow .= '
'.$langs->trans("NotEnoughDataYet").'
'; return; } - $this->stringtoshow .= '
'."\n"; + + // Start the div that will contains all the graph + $dolxaxisvertical=''; + if (count($this->data) > 20) $dolxaxisvertical='dol-xaxis-vertical'; + $this->stringtoshow .= '
'."\n"; $this->stringtoshow .= ' @@ -7070,7 +7075,6 @@ class Form jQuery(".linkto").click(function() { console.log("We choose to show/hide link for rel="+jQuery(this).attr(\'rel\')); jQuery("#"+jQuery(this).attr(\'rel\')+"list").toggle(); - jQuery(this).toggle(); }); }); diff --git a/htdocs/core/class/html.formadmin.class.php b/htdocs/core/class/html.formadmin.class.php index ff99431b221..21c15b3b7c6 100644 --- a/htdocs/core/class/html.formadmin.class.php +++ b/htdocs/core/class/html.formadmin.class.php @@ -59,16 +59,17 @@ class FormAdmin * @param int $forcecombo Force to use combo box (so no ajax beautify effect) * @param int $multiselect Make the combo a multiselect * @param array $onlykeys Show only the following keys (opposite of $filter) + * @param int $mainlangonly 1=Show only main languages ('fr_FR' no' fr_BE', 'es_ES' not 'es_MX', ...) * @return string Return HTML select string with list of languages */ - public function select_language($selected = '', $htmlname = 'lang_id', $showauto = 0, $filter = null, $showempty = '', $showwarning = 0, $disabled = 0, $morecss = '', $showcode = 0, $forcecombo = 0, $multiselect = 0, $onlykeys = array()) + public function select_language($selected = '', $htmlname = 'lang_id', $showauto = 0, $filter = null, $showempty = '', $showwarning = 0, $disabled = 0, $morecss = '', $showcode = 0, $forcecombo = 0, $multiselect = 0, $onlykeys = array(), $mainlangonly = 0) { // phpcs:enable global $conf, $langs; if (!empty($conf->global->MAIN_DEFAULT_LANGUAGE_FILTER)) $filter[$conf->global->MAIN_DEFAULT_LANGUAGE_FILTER] = 1; - $langs_available=$langs->get_available_languages(DOL_DOCUMENT_ROOT, 12); + $langs_available=$langs->get_available_languages(DOL_DOCUMENT_ROOT, 12, 0, $mainlangonly); $out=''; @@ -95,21 +96,28 @@ class FormAdmin { $valuetoshow=$value; if ($showcode == 1) $valuetoshow=$key.' - '.$value; - if ($showcode == 2) $valuetoshow=$value.' ('.$key.')'; + if ($showcode == 2) { + if ($mainlangonly) $valuetoshow=$value.' ('.preg_replace('/[_-].*$/', '', $key).')'; + else $valuetoshow=$value.' ('.$key.')'; + } - if ($filter && is_array($filter) && array_key_exists($key, $filter)) { + $keytouse = $key; + if ($mainlangonly) $keytouse = preg_replace('/[_-].*$/', '', $key); + + if ($filter && is_array($filter) && array_key_exists($keytouse, $filter)) { continue; } - if ($onlykeys && is_array($onlykeys) && ! array_key_exists($key, $onlykeys)) { + if ($onlykeys && is_array($onlykeys) && ! array_key_exists($keytouse, $onlykeys)) { continue; } - if ($selected == $key) + + if ($selected == $keytouse) { - $out.= ''; + $out.= ''; } else { - $out.= ''; + $out.= ''; } } $out.= ''; @@ -137,49 +145,49 @@ class FormAdmin public function select_menu($selected, $htmlname, $dirmenuarray, $moreattrib = '') { // phpcs:enable - global $langs,$conf; + global $langs, $conf; // Clean parameters // Check parameters - if (! is_array($dirmenuarray)) return -1; + if (!is_array($dirmenuarray)) return -1; - $menuarray=array(); + $menuarray = array(); foreach ($conf->file->dol_document_root as $dirroot) { - foreach($dirmenuarray as $dirtoscan) + foreach ($dirmenuarray as $dirtoscan) { - $dir=$dirroot.$dirtoscan; + $dir = $dirroot.$dirtoscan; //print $dir.'
'; if (is_dir($dir)) { - $handle=opendir($dir); + $handle = opendir($dir); if (is_resource($handle)) { - while (($file = readdir($handle))!==false) + while (($file = readdir($handle)) !== false) { if (is_file($dir."/".$file) && substr($file, 0, 1) <> '.' && substr($file, 0, 3) <> 'CVS' && substr($file, 0, 5) != 'index') { - if (preg_match('/lib\.php$/i', $file)) continue; // We exclude library files - if (preg_match('/eldy_(backoffice|frontoffice)\.php$/i', $file)) continue; // We exclude all menu manager files - if (preg_match('/auguria_(backoffice|frontoffice)\.php$/i', $file)) continue; // We exclude all menu manager files - if (preg_match('/smartphone_(backoffice|frontoffice)\.php$/i', $file)) continue; // We exclude all menu manager files + if (preg_match('/lib\.php$/i', $file)) continue; // We exclude library files + if (preg_match('/eldy_(backoffice|frontoffice)\.php$/i', $file)) continue; // We exclude all menu manager files + if (preg_match('/auguria_(backoffice|frontoffice)\.php$/i', $file)) continue; // We exclude all menu manager files + if (preg_match('/smartphone_(backoffice|frontoffice)\.php$/i', $file)) continue; // We exclude all menu manager files - $filelib=preg_replace('/\.php$/i', '', $file); - $prefix=''; + $filelib = preg_replace('/\.php$/i', '', $file); + $prefix = ''; // 0=Recommanded, 1=Experimental, 2=Developpement, 3=Other - if (preg_match('/^eldy/i', $file)) $prefix='0'; - elseif (preg_match('/^smartphone/i', $file)) $prefix='2'; - else $prefix='3'; + if (preg_match('/^eldy/i', $file)) $prefix = '0'; + elseif (preg_match('/^smartphone/i', $file)) $prefix = '2'; + else $prefix = '3'; if ($file == $selected) { - $menuarray[$prefix.'_'.$file]=''; + $menuarray[$prefix.'_'.$file] = ''; } else { - $menuarray[$prefix.'_'.$file]=''; + $menuarray[$prefix.'_'.$file] = ''; } } } @@ -191,26 +199,26 @@ class FormAdmin ksort($menuarray); // Output combo list of menus - print ''; + $oldprefix = ''; foreach ($menuarray as $key => $val) { - $tab=explode('_', $key); - $newprefix=$tab[0]; - if ($newprefix=='1' && ($conf->global->MAIN_FEATURES_LEVEL < 1)) continue; - if ($newprefix=='2' && ($conf->global->MAIN_FEATURES_LEVEL < 2)) continue; + $tab = explode('_', $key); + $newprefix = $tab[0]; + if ($newprefix == '1' && ($conf->global->MAIN_FEATURES_LEVEL < 1)) continue; + if ($newprefix == '2' && ($conf->global->MAIN_FEATURES_LEVEL < 2)) continue; if ($newprefix != $oldprefix) // Add separators { // Affiche titre print ''; - $oldprefix=$newprefix; + $oldprefix = $newprefix; } - print $val."\n"; // Show menu entry + print $val."\n"; // Show menu entry } print ''; } @@ -227,37 +235,37 @@ class FormAdmin public function select_menu_families($selected, $htmlname, $dirmenuarray) { // phpcs:enable - global $langs,$conf; + global $langs, $conf; //$expdevmenu=array('smartphone_backoffice.php','smartphone_frontoffice.php'); // Menu to disable if $conf->global->MAIN_FEATURES_LEVEL is not set - $expdevmenu=array(); + $expdevmenu = array(); - $menuarray=array(); + $menuarray = array(); - foreach($dirmenuarray as $dirmenu) + foreach ($dirmenuarray as $dirmenu) { foreach ($conf->file->dol_document_root as $dirroot) { - $dir=$dirroot.$dirmenu; + $dir = $dirroot.$dirmenu; if (is_dir($dir)) { - $handle=opendir($dir); + $handle = opendir($dir); if (is_resource($handle)) { - while (($file = readdir($handle))!==false) + while (($file = readdir($handle)) !== false) { if (is_file($dir."/".$file) && substr($file, 0, 1) <> '.' && substr($file, 0, 3) <> 'CVS') { - $filelib=preg_replace('/(_backoffice|_frontoffice)?\.php$/i', '', $file); + $filelib = preg_replace('/(_backoffice|_frontoffice)?\.php$/i', '', $file); if (preg_match('/^index/i', $filelib)) continue; if (preg_match('/^default/i', $filelib)) continue; if (preg_match('/^empty/i', $filelib)) continue; if (preg_match('/\.lib/i', $filelib)) continue; if (empty($conf->global->MAIN_FEATURES_LEVEL) && in_array($file, $expdevmenu)) continue; - $menuarray[$filelib]=1; + $menuarray[$filelib] = 1; } - $menuarray['all']=1; + $menuarray['all'] = 1; } closedir($handle); } @@ -269,11 +277,11 @@ class FormAdmin // Affichage liste deroulante des menus print ''; + $out .= ''; + $out .= ''; return $out; } diff --git a/htdocs/core/class/html.formcategory.class.php b/htdocs/core/class/html.formcategory.class.php new file mode 100644 index 00000000000..4dd8bed247b --- /dev/null +++ b/htdocs/core/class/html.formcategory.class.php @@ -0,0 +1,58 @@ + + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/html.formcategory.class.php + * \ingroup core + * \brief File of class to build HTML component for category filtering + */ + +require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; + +class FormCategory extends Form +{ + /** + * Return a HTML filter box for a list filter view + * + * @param string $type The categorie type (e.g Categorie::TYPE_WAREHOUSE) + * @param Array $preSelected A list with the elements that should pre-selected + * @return string A HTML filter box (Note: selected results can get with GETPOST("search_category_".$type."_list")) + */ + public function getFilterBox($type, $preSelected) + { + // phpcs:enable + global $langs; + + if (empty($preSelected) || !is_array($preSelected)) + { + $preSelected = array(); + } + + $htmlName = "search_category_".$type."_list"; + + $categoryArray = $this->select_all_categories($type, "", "", 64, 0, 1); + $categoryArray[-2] = "- ".$langs->trans('NotCategorized')." -"; + + $filter = ''; + $filter .= '
'; + $filter .= $langs->trans('Categories').": "; + $filter .= Form::multiselectarray($htmlName, $categoryArray, $preSelected, 0, 0, "minwidth300"); + $filter .= "
"; + + return $filter; + } +} diff --git a/htdocs/core/class/html.formcompany.class.php b/htdocs/core/class/html.formcompany.class.php index 2a538aa3b47..79c87f1ba92 100644 --- a/htdocs/core/class/html.formcompany.class.php +++ b/htdocs/core/class/html.formcompany.class.php @@ -249,8 +249,7 @@ class FormCompany extends Form } } - if ((!empty($selected) && $selected == $obj->rowid) - || (empty($selected) && !empty($conf->global->MAIN_FORCE_DEFAULT_STATE_ID) && $conf->global->MAIN_FORCE_DEFAULT_STATE_ID == $obj->rowid)) + if (!empty($selected) && $selected == $obj->rowid) { $out .= '